Merge remote-tracking branch 'refs/remotes/Roll20/master'
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
.charsheet {
|
||||
background-color: #c0c0c0;
|
||||
}
|
||||
|
||||
.charsheet table{
|
||||
border-collapse:separate;
|
||||
border-spacing:10px;
|
||||
}
|
||||
|
||||
.charsheet textarea{
|
||||
resize:vertical;
|
||||
}
|
||||
|
||||
.charsheet .sheet-section{
|
||||
border-top: 5px solid #505050;
|
||||
padding-top:10px;
|
||||
padding-bottom:10px;
|
||||
}
|
||||
|
||||
.charsheet input[type=number].sheet-smallnumber{
|
||||
width:40px;
|
||||
}
|
||||
|
||||
.charsheet input[type=text].sheet-smalltext{
|
||||
width:60px;
|
||||
height: 18px;
|
||||
margin:0px;
|
||||
}
|
||||
.charsheet input[type=text].sheet-shorttext{
|
||||
padding-top:2px;
|
||||
padding-bottom:2px;
|
||||
}
|
||||
|
||||
.charsheet input[type=text].sheet-skilltext{
|
||||
width:100px;
|
||||
padding:2px;
|
||||
margin-left:3px;
|
||||
}
|
||||
|
||||
.charsheet .sheet-right{
|
||||
float:right;
|
||||
}
|
||||
|
||||
.charsheet .sheet-bold{
|
||||
font-size: 12pt;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.charsheet .sheet-border{
|
||||
border: 2px solid white;
|
||||
vertical-align:top;
|
||||
width:100%;
|
||||
padding: 2px;
|
||||
margin: 2px;
|
||||
}
|
||||
|
||||
.charsheet input[type=number].sheet-smallshortnumber{
|
||||
width:40px;
|
||||
padding-top:2px;
|
||||
padding-bottom:2px;
|
||||
display: inline-block;
|
||||
float:right;
|
||||
}
|
||||
|
||||
.charsheet input[type=number].sheet-shortnumber{
|
||||
padding-top:2px;
|
||||
padding-bottom:2px;
|
||||
}
|
||||
|
||||
.charsheet label.sheet-areaLabel{
|
||||
margin:5px;
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
<div class="sheet-section-main" style=" position:relative;">
|
||||
<div name="header" style="text-align: Center;">
|
||||
<img src="http://www.ilhadotabuleiro.com.br/upload/jogo/imagem/mini/23420.jpg"/>
|
||||
</div>
|
||||
<div name="characterinfo" class="sheet-section">
|
||||
<div class='sheet-2colrow'>
|
||||
<div class='sheet-col' style="display:inline-block;">
|
||||
<label>Nome:<input class="sheet-right sheet-shorttext" type="text" name="attr_charactername" style="width:65%;"/></label>
|
||||
<label>Pontos:<input class="sheet-right sheet-shorttext" type="number" name="attr_playername" style="width:70%;"/></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div name="attributes" class="sheet-section">
|
||||
<div class="sheet-3colrow">
|
||||
<div name="Atributos" class="sheet-col">
|
||||
<div name="Força" class="sheet-bold sheet-border">
|
||||
<button type='roll' value='/roll d6 - @{forca}' >Força</button>
|
||||
<div style="float:right;">
|
||||
<input type="number" name="attr_forca" class="sheet-smallnumber sheet-shortnumber" min="0" value="0"/>
|
||||
</div>
|
||||
</div>
|
||||
<div name="Habilidade" class="sheet-bold sheet-border">
|
||||
<button type='roll' class="astext" value='/roll d6 - @{habilidade}' >Habilidade</button>
|
||||
<div style="float:right">
|
||||
<input type="number" name="attr_habilidade" class="sheet-smallnumber sheet-shortnumber" min="0" value="0"/>
|
||||
</div>
|
||||
</div>
|
||||
<div name="Resistencia" class="sheet-bold sheet-border">
|
||||
<button type='roll' class="astext" value='/roll d6 - @{resistencia}' >Resistência</button>
|
||||
<div style="float:right;">
|
||||
<input type="number" name="attr_resistencia" class="sheet-smallnumber sheet-shortnumber" min="0" value="0"/>
|
||||
</div>
|
||||
</div>
|
||||
<div name="Armadura" class="sheet-bold sheet-border">
|
||||
<button type='roll' class="astext" value='/roll d6 - @{armadura}'>Armadura</button>
|
||||
<div style="float:right;">
|
||||
<input type="number" name="attr_armadura" class="sheet-smallnumber sheet-shortnumber" min="0" value="0"/>
|
||||
</div>
|
||||
</div>
|
||||
<div name="Poder-de-Fogo" class="sheet-bold sheet-border">
|
||||
<button type='roll' value='/roll d6 - @{poderdefogo}' >Poder de Fogo</button>
|
||||
<div style="float:right;">
|
||||
<input type="number" name="attr_poderdefogo" class="sheet-smallnumber sheet-shortnumber" min="0" value="0"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div name="characterpoints" class="sheet-section">
|
||||
<div class="sheet-3colrow">
|
||||
<div name="VidaMagia" class="sheet-col">
|
||||
<div name="vida" class="sheet-bold">
|
||||
<div style="float:right;">
|
||||
<label>Pontos de Vida
|
||||
<input type="number" name="attr_vida" class="sheet-smallnumber sheet-shortnumber" value="@{resistencia} * 5"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div name="magia" class="sheet-bold">
|
||||
<div style="float:right;">
|
||||
<label>Pontos de Magia
|
||||
<input type="number" name="attr_magia" class="sheet-smallnumber sheet-shortnumber" value="@{resistencia} * 5"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div name="experiencia" class="sheet-bold">
|
||||
<div style="float:right;">
|
||||
<label>Pontos de Experiência
|
||||
<input type="number" name="attr_experiencia" class="sheet-smallnumber sheet-shortnumber" value="0"/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div name="characterbasics" class="sheet-section">
|
||||
<div class='sheet-2colrow'>
|
||||
<div name="Basic-Info" class='sheet-col'>
|
||||
<label style="padding-top: 4px; padding-bottom: 2px;">Dinheiro<input type="number" name="attr_dinheiro" min="0" class="sheet-smallshortnumber" style="width: 35%; float: right; padding-bottom: 2px;"/></label>
|
||||
</div>
|
||||
</div>
|
||||
<div name="characterfeatures" class="sheet-section">
|
||||
<div class="sheet-3colrow">
|
||||
<div name="Vantagens" class="sheet-col">
|
||||
<label class="sheet-areaLabel">Vantagens:</label>
|
||||
<textarea name="attr_vantagens" style="height:100px; width:250px;"></textarea>
|
||||
</div>
|
||||
<div name="Desvantagens" class="sheet-col">
|
||||
<label class="sheet-areaLabel">Desvantagens:</label>
|
||||
<textarea name="attr_desvantagens" style="height:100px; width:250px;"></textarea>
|
||||
</div>
|
||||
<div name="Dano" class="sheet-col">
|
||||
<label class="sheet-areaLabel">Tipos de Dano:</label>
|
||||
<textarea name="attr_dano" style="height:100px; width:250px;"></textarea>
|
||||
</div>
|
||||
<div name="Magias" class="sheet-col">
|
||||
<label class="sheet-areaLabel">Magias Conhecidas:</label>
|
||||
<textarea name="attr_magias" style="height:100px; width:250px;"></textarea>
|
||||
</div>
|
||||
<div name="Itens" class="sheet-col">
|
||||
<label class="sheet-areaLabel">Itens:</label>
|
||||
<textarea name="attr_itens" style="height:100px; width:250px;"></textarea>
|
||||
</div>
|
||||
<div name="Hitoria" class="sheet-col">
|
||||
<label class="sheet-areaLabel">História:</label>
|
||||
<textarea name="attr_historia" style="height:100px; width:250px;"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 161 KiB |
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"html": "3DeT_ALPHA.html",
|
||||
"css": "3DeT_ALPHA.css",
|
||||
"authors": "Julio Melanda",
|
||||
"roll20userid": "1413302",
|
||||
"preview": "3DeT_ALPHA.png",
|
||||
"instructions": "This is a character sheet for 3D&T Defensores de Tóquio 3ª Edição Alpha"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
+78
-13
File diff suppressed because one or more lines are too long
+5
-3
@@ -29,8 +29,8 @@ Please report any bugs in the [issues tab](https://github.com/mlenser/roll20-cha
|
||||
* Roll settings to choose to always roll with advantage, disadvantage, or query for both
|
||||
* Optional bonuses to all skills, abilities, saving throws, etc.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## How to Update the sheet yourself (as Pro):
|
||||
|
||||
@@ -40,7 +40,9 @@ Please report any bugs in the [issues tab](https://github.com/mlenser/roll20-cha
|
||||
4. In the HTML tab paste the HTML code
|
||||
5. Copy the [css](https://raw.githubusercontent.com/mlenser/roll20-character-sheets/master/5eShaped/5eShaped.css) from github
|
||||
6. On Roll20 in the CSS tab paste the CSS code.
|
||||
7. Hit save.
|
||||
7. Copy the [translation](https://github.com/mlenser/roll20-character-sheets/tree/master/5eShaped/translations) from the appropriate file on github (en is English, fr is French, de is German, it is Italian, etc)
|
||||
8. On Roll20 in the Translation tab paste the JSON from the appropriate file.
|
||||
9. Hit save.
|
||||
|
||||
## Contribute
|
||||
Since many have asked for it: If you appreciate what I do and want to compensate me for the countless hours that I have spent building this character sheet feel free to support me on [Patreon](https://www.patreon.com/mlenser) or Paypal (mlenser@gmail.com).
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"parser": "babel-eslint",
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": "airbnb/base",
|
||||
"rules": {
|
||||
"arrow-body-style": 0,
|
||||
"max-len": 0,
|
||||
"no-cond-assign": 0,
|
||||
"no-console": 0,
|
||||
"no-param-reassign": 0,
|
||||
"no-restricted-syntax": 0
|
||||
}
|
||||
}
|
||||
@@ -458,6 +458,13 @@ $pad-mar: (
|
||||
}
|
||||
|
||||
.sheet-slide-input-pc {
|
||||
&:checked ~ div {
|
||||
.sheet-trait {
|
||||
span {
|
||||
line-height: 1.15;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:checked ~ div .sheet-pc,
|
||||
&:checked ~ .sheet-pc,
|
||||
&:not(:checked) ~ div .sheet-npc,
|
||||
@@ -465,6 +472,8 @@ $pad-mar: (
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.sheet-slide-input-pc {
|
||||
}
|
||||
|
||||
.sheet-small-note {
|
||||
font-size: 10px;
|
||||
@@ -608,15 +617,18 @@ $pad-mar: (
|
||||
}
|
||||
|
||||
.sheet-ability-wrapper {
|
||||
height: 69px;
|
||||
margin-bottom: 12px;
|
||||
height: 62px;
|
||||
margin-bottom: 15px;
|
||||
padding-left: 1px;
|
||||
padding-right: 1px;
|
||||
padding-top: 1px;
|
||||
position: relative;
|
||||
|
||||
& .sheet-ability-score-wrapper {
|
||||
background-color: $white;
|
||||
border: 1px solid $black;
|
||||
border-radius: 50%;
|
||||
bottom: -10px;
|
||||
bottom: -11px;
|
||||
height: 24px;
|
||||
left: 0;
|
||||
margin-left: auto;
|
||||
@@ -640,12 +652,9 @@ $pad-mar: (
|
||||
|
||||
.sheet-ability-modifier {
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
padding-bottom: 8px !important;
|
||||
padding-top: 8px !important;
|
||||
padding-top: 6px !important;
|
||||
|
||||
input.sheet-toggle-edit-mode:checked ~ div & {
|
||||
padding-bottom: 0 !important;
|
||||
padding-top: 0 !important;
|
||||
}
|
||||
}
|
||||
@@ -735,6 +744,7 @@ $pad-mar: (
|
||||
select {
|
||||
padding: 0;
|
||||
}
|
||||
padding-right: 1px;
|
||||
}
|
||||
|
||||
.sheet-skills-ability-selector {
|
||||
@@ -762,6 +772,10 @@ $pad-mar: (
|
||||
}
|
||||
}
|
||||
|
||||
input.sheet-toggle-use-custom-saving-throws:not([value='1']) ~ div .sheet-resistances-immunities {
|
||||
margin-left: -75px;
|
||||
}
|
||||
|
||||
.sheet-shield {
|
||||
height: 55px;
|
||||
margin-left: auto;
|
||||
@@ -791,7 +805,7 @@ $pad-mar: (
|
||||
}
|
||||
|
||||
.sheet-wrap-box-title {
|
||||
margin-top: 1px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -819,13 +833,15 @@ $pad-mar: (
|
||||
}
|
||||
|
||||
.sheet-big-text {
|
||||
font-size: 16px;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.sheet-initiative,
|
||||
.sheet-speed {
|
||||
.sheet-big-text {
|
||||
padding: .4em;
|
||||
display: block;
|
||||
min-height: 1.6em;
|
||||
padding: .2em;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -841,9 +857,8 @@ $pad-mar: (
|
||||
|
||||
.sheet-wrap-box-title,
|
||||
.sheet-ability-name {
|
||||
font-size: 10px;
|
||||
font-size: 9px;
|
||||
font-weight: bold;
|
||||
letter-spacing: -.2px;
|
||||
}
|
||||
|
||||
.sheet-wrap-box-title {
|
||||
@@ -976,7 +991,7 @@ $pad-mar: (
|
||||
.sheet-exhaustion-wrapper {
|
||||
border: 1px solid $black;
|
||||
border-radius: 50%;
|
||||
height: 30px;
|
||||
height: 29px;
|
||||
left: -6px;
|
||||
position: absolute;
|
||||
top: -3px;
|
||||
@@ -1042,6 +1057,10 @@ $pad-mar: (
|
||||
}
|
||||
}
|
||||
|
||||
.sheet-hit-dice-container {
|
||||
min-height: 2.7em;
|
||||
}
|
||||
|
||||
.sheet-death-success,
|
||||
.sheet-death-fail {
|
||||
.sheet-checkbox-label {
|
||||
@@ -1545,7 +1564,6 @@ input.sheet-attack-toggle:not(:checked) ~ div.sheet-attack-toggle,
|
||||
input.sheet-show-uses:not(:checked) ~ .sheet-show-uses,
|
||||
input.sheet-toggle-use-custom-saving-throws[value='1'] ~ div .sheet-default-saving-throw,
|
||||
input.sheet-toggle-use-custom-saving-throws:not([value='1']) ~ div .sheet-custom-saving-throw,
|
||||
input.sheet-toggle-hide-ac[value='1'] ~ div .sheet-ac,
|
||||
input.sheet-has-sorcerer-levels:not([value='1']) ~ div .sheet-has-sorcerer-levels {
|
||||
display: none;
|
||||
}
|
||||
@@ -1816,12 +1834,21 @@ textarea {
|
||||
resize: both;
|
||||
}
|
||||
|
||||
.sheet-background-text {
|
||||
.sheet-background-text,
|
||||
.sheet-trait {
|
||||
display: block;
|
||||
.sheet-toggle-edit-mode:not(:checked) ~ div & {
|
||||
max-height: 4em;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.sheet-background-text {
|
||||
line-height: 1.1;
|
||||
max-height: 4.2em;
|
||||
min-height: 1.1em;
|
||||
}
|
||||
.sheet-trait {
|
||||
max-height: 5.5em;
|
||||
span {
|
||||
line-height: 1.1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1918,7 +1945,7 @@ textarea {
|
||||
}
|
||||
@include faded-border-bottom;
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid black;
|
||||
border-top: 1px solid $black;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 5px;
|
||||
width: 50%;
|
||||
@@ -1926,7 +1953,7 @@ textarea {
|
||||
&:first-child,
|
||||
&:nth-child(2) {
|
||||
border-image: none;
|
||||
border-top: none;
|
||||
border-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,23 +1,21 @@
|
||||
<input type="hidden" name="attr_attack_formula">
|
||||
|
||||
<div class="shaped-row vert-top mar-t-sm">
|
||||
<input type="checkbox" name="attr_roll_toggle" value="{{vs_ac=1}} {{vs_saving_throw=@{attacks_vs_a_saving_throw}}} @{roll_info} {{roll1=[[@{shaped_d20}cs>@{crit_range} + @{attack_formula}]]}} @{roll_setting}cs>@{crit_range} + @{attack_formula}]]}} {{targetAC=@{attacks_vs_target_ac}}} {{targetName=@{attacks_vs_target_name}}}" class="attack-toggle" checked>
|
||||
|
||||
<input type="checkbox" name="attr_roll_toggle" value="{{vs_ac=1}} @{roll_info} {{roll1=[[@{shaped_d20}cs>@{crit_range} + @{attack_formula}]]}} @{roll_setting}cs>@{crit_range} + @{attack_formula}]]}} {{targetAC=@{attacks_vs_target_ac}}} {{targetName=@{attacks_vs_target_name}}}" class="attack-toggle" checked>
|
||||
<div class="bold italic mar-r-sm"><span data-i18n="ATTACK"></span>.</div>
|
||||
<div class="attack-toggle col-08 center pad-r-sm">
|
||||
<input type="checkbox" name="attr_proficiency" checked>
|
||||
<div class="small-label" data-i18n="PROF"></div>
|
||||
</div>
|
||||
<div class="attack-toggle col-16 center pad-r-sm">
|
||||
<div class="attack-toggle col-10 center pad-r-sm">
|
||||
<select name="attr_attack_ability">
|
||||
<option value="">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE">Finesse</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE"></option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
<input type="hidden" name="attr_attack_formula">
|
||||
|
||||
<div class="shaped-row vert-top mar-t-sm">
|
||||
<input type="checkbox" name="attr_roll_toggle" value="{{vs_ac=1}} {{vs_saving_throw=@{attacks_vs_a_saving_throw}}} @{roll_info} {{roll1=[[@{shaped_d20}cs>@{crit_range} + @{attack_formula}]]}} @{roll_setting}cs>@{crit_range} + @{attack_formula}]]}} {{targetAC=@{attacks_vs_target_ac}}} {{targetName=@{attacks_vs_target_name}}}" class="attack-toggle">
|
||||
<input type="checkbox" name="attr_roll_toggle" value="{{vs_ac=1}} @{roll_info} {{roll1=[[@{shaped_d20}cs>@{crit_range} + @{attack_formula}]]}} @{roll_setting}cs>@{crit_range} + @{attack_formula}]]}} {{targetAC=@{attacks_vs_target_ac}}} {{targetName=@{attacks_vs_target_name}}}" class="attack-toggle">
|
||||
<div class="bold italic mar-r-sm"><span data-i18n="ATTACK"></span>.</div>
|
||||
<div class="attack-toggle col-08 center pad-r-sm">
|
||||
<input type="checkbox" name="attr_proficiency" checked>
|
||||
<div class="small-label" data-i18n="PROF"></div>
|
||||
</div>
|
||||
<div class="attack-toggle col-16 center pad-r-sm">
|
||||
<div class="attack-toggle col-10 center pad-r-sm">
|
||||
<select name="attr_attack_ability">
|
||||
<option value="">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE">Finesse</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE"></option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
<input type="text" name="attr_damage" class="center" accept="Damage" placeholder="1d6">
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
<div class="attack-toggle col-14 center">
|
||||
<div class="attack-toggle col-10 center">
|
||||
<select name="attr_damage_ability">
|
||||
<option value="">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE">Finesse</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE"></option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="attack-toggle col-18 center pad-r-sm">
|
||||
<input type="text" name="attr_damage_type" class="center" data-i18n-placeholder="SLASHING" accept="Damage Type">
|
||||
</div>
|
||||
<div class="attack-toggle col-18 center pad-l-sm">
|
||||
<div class="attack-toggle col-16 center pad-l-sm">
|
||||
<input type="text" name="attr_damage_crit" class="center">
|
||||
<div class="small-label relative">
|
||||
<span data-i18n="CRIT"></span>
|
||||
@@ -40,4 +40,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
<input type="text" name="attr_second_damage" class="center" accept="Secondary Damage" placeholder="1d6">
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
<div class="attack-toggle col-14 center">
|
||||
<div class="attack-toggle col-10 center">
|
||||
<select name="attr_second_damage_ability">
|
||||
<option value="" selected>—</option>
|
||||
<option value="finesse" data-i18n="FINESSE">Finesse</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE"></option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="attack-toggle col-18 center pad-r-sm">
|
||||
<input type="text" name="attr_second_damage_type" class="center" data-i18n-placeholder="FIRE" accept="Secondary Damage Type">
|
||||
</div>
|
||||
<div class="attack-toggle col-18 center pad-l-sm">
|
||||
<div class="attack-toggle col-16 center pad-l-sm">
|
||||
<input type="text" name="attr_second_damage_crit" class="center">
|
||||
<div class="small-label relative">
|
||||
<span data-i18n="CRIT"></span>
|
||||
|
||||
@@ -9,16 +9,16 @@
|
||||
<input type="text" name="attr_damage" class="center" accept="Damage" placeholder="1d6">
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
<div class="attack-toggle col-14 center">
|
||||
<div class="attack-toggle col-10 center">
|
||||
<select name="attr_damage_ability">
|
||||
<option value="">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE">Finesse</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE"></option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="attack-toggle center pad-l-sm pad-r-sm">+</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="attack-toggle col-18 center pad-r-sm">
|
||||
<input type="text" name="attr_damage_type" class="center" data-i18n-placeholder="FIRE" accept="Damage Type">
|
||||
</div>
|
||||
<div class="attack-toggle col-18 center pad-l-sm">
|
||||
<div class="attack-toggle col-16 center pad-l-sm">
|
||||
<input type="text" name="attr_damage_crit" class="center">
|
||||
<div class="small-label relative">
|
||||
<span data-i18n="CRIT"></span>
|
||||
|
||||
@@ -6,15 +6,15 @@
|
||||
<input type="text" name="attr_heal" class="center" accept="Healing" placeholder="1d6">
|
||||
</div>
|
||||
<div class="attack-toggle pad-l-sm pad-r-sm">+</div>
|
||||
<div class="attack-toggle col-16">
|
||||
<div class="attack-toggle col-10">
|
||||
<select name="attr_heal_ability">
|
||||
<option value="" selected>—</option>
|
||||
<option value="strength" data-i18n="STR" selected>Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="attack-toggle pad-l-sm pad-r-sm">+</div>
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
<textarea class="one-line-textarea" name="attr_saving_throw_condition" data-i18n-placeholder="IF_THE_TARGET_IS"></textarea>
|
||||
</div>
|
||||
<div class="attack-toggle col-100"></div>
|
||||
<div class="attack-toggle col-16 center">
|
||||
<div class="attack-toggle col-10 center">
|
||||
<select name="attr_saving_throw_ability">
|
||||
<option value="">—</option>
|
||||
<option value="0">—</option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<div class="shaped-row vert-top mar-t-sm relative">
|
||||
<input type="checkbox" name="attr_special_effects_toggle" value="{{fx=@{type}-@{color} @{points_of_origin}}}" class="attack-toggle">
|
||||
<input type="checkbox" name="attr_special_effects_toggle" value="{{fx=@{special_effects_type}-@{special_effects_color} @{special_effects_points_of_origin}}}" class="attack-toggle">
|
||||
|
||||
<div class="bold italic mar-r-sm"><span data-i18n="SPECIAL_EFFECTS"></span>.</div>
|
||||
<div class="attack-toggle col-15 center mar-b-sm">
|
||||
<input type="text" name="attr_type" class="center" placeholder="explode">
|
||||
<input type="text" name="attr_special_effects_type" class="center" placeholder="explode">
|
||||
<div class="small-label" data-i18n="TYPE"></div>
|
||||
</div>
|
||||
<div class="attack-toggle col-15 center pad-l-sm mar-b-sm">
|
||||
<input type="text" name="attr_color" class="center" data-i18n-placeholder="FIRE">
|
||||
<input type="text" name="attr_special_effects_color" class="center" data-i18n-placeholder="FIRE">
|
||||
<div class="small-label" data-i18n="COLOR"></div>
|
||||
</div>
|
||||
<div class="attack-toggle col-30 center pad-l-sm mar-b-sm">
|
||||
<select name="attr_points_of_origin">
|
||||
<option value="sourceToTarget @{target|token_id}"><span data-i18n="SOURCE">Source</span> → <span data-i18n="TARGET">Target</span></option>
|
||||
<option value="target @{target|token_id}" data-i18n="TARGET">target</option>
|
||||
<option value="source" data-i18n="SOURCE">source</option>
|
||||
<option value="targetToSource @{target|token_id}"><span data-i18n="TARGET">Target</span> → <span data-i18n="SOURCE">Source</span></option>
|
||||
<select name="attr_special_effects_points_of_origin">
|
||||
<option value="sourceToTarget @{target|token_id}" data-i18n="SOURCE_TO_TARGET"></option>
|
||||
<option value="target @{target|token_id}" data-i18n="TARGET"></option>
|
||||
<option value="source" data-i18n="SOURCE"></option>
|
||||
<option value="targetToSource @{target|token_id}" data-i18n="TARGET_TO_SOURCE"></option>
|
||||
</select>
|
||||
<div class="small-label" data-i18n="POINTS_OF_ORIGIN"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="col-17 center pad-l-sm pad-r-sm">
|
||||
<select name="attr_type">
|
||||
<option value="Other" data-i18n="OTHER">Other</option>
|
||||
<option value="Melee Weapon" data-i18n="MELEE">Melee</option>
|
||||
<option value="Ranged Weapon" data-i18n="RANGED">Ranged</option>
|
||||
<option value="Other" data-i18n="OTHER_TYPE"></option>
|
||||
<option value="Melee Weapon" data-i18n="MELEE_WEAPON"></option>
|
||||
<option value="Ranged Weapon" data-i18n="RANGED_WEAPON"></option>
|
||||
</select>
|
||||
<div class="small-label" data-i18n="TYPE"></div>
|
||||
</div>
|
||||
@@ -6,14 +6,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<select name="attr_default_ability">
|
||||
<option value="">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE">Finesse</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="finesse" data-i18n="FINESSE"></option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
<div class="wrap-box-title center" data-i18n="DEFAULT_ABILITY"></div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="ac col-33 center">
|
||||
<button type="roll" name="roll_shaped_ac" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=^{AC}}} {{text_big=[[@{ac}]]}}">
|
||||
<div class="shield">
|
||||
<span name="attr_AC" class="big-text bold block center"></span>
|
||||
<span name="attr_AC" class="big-text block center"></span>
|
||||
<div class="wrap-box-title center" data-i18n="ARMOR_CLASS"></div>
|
||||
</div>
|
||||
</button>
|
||||
@@ -14,10 +14,10 @@
|
||||
<div>+</div>
|
||||
<input type="text" name="attr_initiative_bonus" class="center no-border" value="0">
|
||||
<div>=</div>
|
||||
<span name="attr_initiative" class="big-text bold block center"></span>
|
||||
<span name="attr_initiative" class="big-text block center"></span>
|
||||
</div>
|
||||
<button type="roll" name="roll_shaped_initiative" value="@{initiative_output_option} &{template:5e-shaped} {{ability=1}} {{character_name=@{character_name}}} @{show_character_name} {{title=^{INITIATIVE}}} {{roll1=[[@{initiative_roll} + @{initiative_to_tracker} + @{initiative_tie_breaker}]]}} @{attacher_initiative}">
|
||||
<span name="attr_initiative" class="presentation big-text bold block center initiative-total"></span>
|
||||
<span name="attr_initiative" class="presentation big-text block center initiative-total"></span>
|
||||
<div class="wrap-box-title center" data-i18n="INITIATIVE"></div>
|
||||
</button>
|
||||
</div>
|
||||
@@ -25,10 +25,10 @@
|
||||
<div class="col-29 center pad-l-md">
|
||||
<div class="wrap-box center speed">
|
||||
<div class="edit">
|
||||
<input type="number" name="attr_speed" class="big-text bold center no-spin no-border" step="1">
|
||||
<input type="number" name="attr_speed" class="big-text center no-spin no-border" step="1">
|
||||
</div>
|
||||
<button type="roll" name="roll_shaped_speed" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=^{SPEED}}} {{text_big=[[@{speed}]]}}">
|
||||
<span name="attr_speed" class="presentation big-text bold block center"></span>
|
||||
<span name="attr_speed" class="presentation big-text block center"></span>
|
||||
<div class="wrap-box-title" data-i18n="SPEED"></div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
</div>
|
||||
<div class="col-17 center pad-l-sm pad-r-sm">
|
||||
<select name="attr_type" accept="Item Type">
|
||||
<option value="Other" data-i18n="OTHER">Other</option>
|
||||
<option value="Melee Weapon" data-i18n="MELEE">Melee</option>
|
||||
<option value="Ranged Weapon" data-i18n="RANGED">Ranged</option>
|
||||
<option value="Other" data-i18n="OTHER"></option>
|
||||
<option value="Melee Weapon" data-i18n="MELEE"></option>
|
||||
<option value="Ranged Weapon" data-i18n="RANGED"></option>
|
||||
</select>
|
||||
<div class="small-label" data-i18n="TYPE"></div>
|
||||
</div>
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
<div class="section-core pc">
|
||||
<div class="shaped-row">
|
||||
<div class="col-32 pad-r-sm">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="shaped-row mar-b-smd">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
//= include abilities.html
|
||||
</div>
|
||||
<div class="col-70 pad-l-sm">
|
||||
<div class="col-71 pad-l-sm">
|
||||
//= include inspiration.html
|
||||
//= include proficiency.html
|
||||
//= include savingThrows.html
|
||||
//= include skills.html
|
||||
<div class="resistances-immunities wrap-box">
|
||||
//= include resistancesVulnerabilities.html
|
||||
<div class="wrap-box-title center" data-i18n="RESISTANCES_AND_IMMUNITIES"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
//= include languagesProficiencies.html
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-39 pad-l-sm pad-r-sm">
|
||||
<div class="col-38 pad-l-sm pad-r-sm">
|
||||
<div class="shaped-row">
|
||||
<div class="col-58 pad-r-sm">
|
||||
//= include armorInit.html
|
||||
@@ -32,10 +36,6 @@
|
||||
</div>
|
||||
<div class="col-42 pad-l-sm">
|
||||
//= include ../spells/spellSlots.html
|
||||
<div class="resistances-immunities wrap-box mar-b-smd">
|
||||
//= include resistancesVulnerabilities.html
|
||||
<div class="wrap-box-title center" data-i18n="RESISTANCES_AND_IMMUNITIES"></div>
|
||||
</div>
|
||||
//= include exhaustion.html
|
||||
//= include rests.html
|
||||
</div>
|
||||
@@ -47,7 +47,7 @@
|
||||
//= include equipment.html
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-29 pad-l-sm">
|
||||
<div class="col-32 pad-l-sm">
|
||||
//= include background.html
|
||||
//= include traits.html
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="exhaustion wrap-box relative mar-b-smd">
|
||||
<div class="shaped-row vert-center">
|
||||
<div class="exhaustion-wrapper">
|
||||
<input type="number" name="attr_exhaustion_level" class="no-spin bold big-font no-border" min="0" value="0" max="6">
|
||||
<input type="number" name="attr_exhaustion_level" class="no-spin big-font no-border" min="0" value="0" max="6">
|
||||
</div>
|
||||
<button type="roll" name="roll_shaped_exhaustion" class="wrapper-button" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=^{EXHAUSTION_LEVEL}}} {{text_big=[[@{exhaustion_level}]]}}">
|
||||
<div class="wrap-box-title white-space-no-wrap" data-i18n="EXHAUSTION_LEVEL"></div>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
<div class="hit-dice wrap-box center mar-b-smd">
|
||||
//= include ../hitDice/hitDice.html
|
||||
<div class="hit-dice-container">
|
||||
//= include ../hitDice/hitDice.html
|
||||
</div>
|
||||
<div class="wrap-box-title" data-i18n="HIT_DICE"></div>
|
||||
</div>
|
||||
@@ -3,11 +3,11 @@
|
||||
<div class="heart mar-b-smd">
|
||||
<div class="shaped-row center flex-end no-wrap pad-t-seven">
|
||||
<div class="col-40">
|
||||
<input type="number" name="attr_HP" class="big-text bold no-spin no-border" step="1">
|
||||
<input type="number" name="attr_HP" class="big-text no-spin no-border" step="1">
|
||||
</div>
|
||||
<div class="heart-divider pad-l-sm pad-r-sm">/</div>
|
||||
<div class="col-40">
|
||||
<input type="number" name="attr_HP_max" class="big-text bold no-spin no-border" min="1" step="1">
|
||||
<input type="number" name="attr_HP_max" class="big-text no-spin no-border" min="1" step="1">
|
||||
</div>
|
||||
</div>
|
||||
<button type="roll" name="roll_shaped_hp" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=^{HIT_POINTS}}} {{text_big=[[@{HP}]]/[[@{HP|max}]]}}">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<button type="roll" name="roll_shaped_pb" class="wrapper-button" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=^{PROFICIENCY_BONUS}}} {{text_big=[[@{pb}]]}}" tabindex="-1">
|
||||
<div class="shaped-row vert-center">
|
||||
<div class="proficiency-bonus-wrapper center">
|
||||
<input type="number" name="attr_PB" class="bold big-font no-border" readonly tabindex="-1">
|
||||
<input type="number" name="attr_PB" class="big-font no-border" readonly tabindex="-1">
|
||||
<input type="hidden" name="attr_exp">
|
||||
<input type="hidden" name="attr_h_PB" value="[[floor(@{PB}/2)]]">
|
||||
</div>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<div class="skills wrap-box">
|
||||
<div class="skills wrap-box mar-b-smd">
|
||||
<input type="checkbox" name="attr_show_passive_skills" class="item-shown hidden">
|
||||
<fieldset class="repeating_skill">
|
||||
<div class="shaped-row no-wrap flex-end">
|
||||
<div class="col-10 no-shrink edit">
|
||||
<div class="col-10 no-shrink edit pad-r-sm">
|
||||
<select name="attr_skill_d20">
|
||||
<option value="@{shaped_d20}" data-i18n="NORMAL">Normal</option>
|
||||
<option value="2d20@{d20_mod}kh1" data-i18n="ADVANTAGE">Advantage</option>
|
||||
<option value="2d20@{d20_mod}kl1" data-i18n="DISADVANTAGE">Disadvantage</option>
|
||||
<option value="@{shaped_d20}" data-i18n="NORMAL"></option>
|
||||
<option value="2d20@{d20_mod}kh1" data-i18n="ADVANTAGE"></option>
|
||||
<option value="2d20@{d20_mod}kl1" data-i18n="DISADVANTAGE"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-10 skill-select-wrapper no-shrink">
|
||||
<div class="col-08 skill-select-wrapper no-shrink">
|
||||
<select name="attr_proficiency" class="no-border">
|
||||
<option value="unproficient">—   <span data-i18n="UNPROFICIENT">Unproficient</span></option>
|
||||
<option value="proficient">✓    <span data-i18n="PROFICIENT">Proficient</span></option>
|
||||
<option value="expertise">✗    <span data-i18n="EXPERTISE">Expertise</span></option>
|
||||
<option value="unproficient" data-i18n="SKILL_SELECT_UNPROFICIENT"></option>
|
||||
<option value="proficient" data-i18n="SKILL_SELECT_PROFICIENT"></option>
|
||||
<option value="expertise" data-i18n="SKILL_SELECT_EXPERTISE"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-09 edit no-shrink">
|
||||
@@ -35,13 +35,13 @@
|
||||
<div class="shaped-row no-wrap vert-center">
|
||||
<span>(</span>
|
||||
<select name="attr_ability" class="skills-ability-selector">
|
||||
<option value="">—</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
<span>)</span>
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@
|
||||
<input type="hidden" name="attr_passive">
|
||||
<button type="roll" name="roll_passive" class="item-to-show" value="@{output_option} &{template:5e-shaped} {{ability=1}} {{character_name=@{character_name}}} @{show_character_name} {{title=^{PASSIVE} @{name} (<span data-i18n=@{ability_key}>@{ability_key}<span>)}} @{roll_info} {{roll1=[[@{passive}]]}} @{hide_gm_info} @{attacher_skill}" tabindex="-1">
|
||||
<div class="shaped-row no-wrap flex-end">
|
||||
<span name="attr_passive" class="col-1-3-em input-like center border-bottom"></span>
|
||||
<span name="attr_passive" class="col-1-3-em input-like small-label center border-bottom"></span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -25,13 +25,13 @@
|
||||
</div>
|
||||
<div class="col-17 center pad-r-sm">
|
||||
<select name="attr_type" accept="Item Type">
|
||||
<option value="Light Armor" data-i18n="LIGHT_ARMOR">Light Armor</option>
|
||||
<option value="Medium Armor" data-i18n="MEDIUM_ARMOR">Medium Armor</option>
|
||||
<option value="Heavy Armor" data-i18n="HEAVY_ARMOR">Heavy Armor</option>
|
||||
<option value="Armored" data-i18n="OTHER_ARMOR">Other Armor</option>
|
||||
<option value="Shield" data-i18n="SHIELD">Shield</option>
|
||||
<option value="AC" data-i18n="ARMORED_AND_UNARMORED">Armored and Unarmored</option>
|
||||
<option value="Unarmored" data-i18n="UNARMORED">Unarmored</option>
|
||||
<option value="Light Armor" data-i18n="LIGHT_ARMOR"></option>
|
||||
<option value="Medium Armor" data-i18n="MEDIUM_ARMOR"></option>
|
||||
<option value="Heavy Armor" data-i18n="HEAVY_ARMOR"></option>
|
||||
<option value="Armored" data-i18n="OTHER_ARMOR"></option>
|
||||
<option value="Shield" data-i18n="SHIELD"></option>
|
||||
<option value="AC" data-i18n="ARMORED_AND_UNARMORED"></option>
|
||||
<option value="Unarmored" data-i18n="UNARMORED"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="edit col-05 center">
|
||||
@@ -48,8 +48,8 @@
|
||||
<div class="col-11 pad-l-md">
|
||||
<select name="attr_strength_requirements">
|
||||
<option value="no">—</option>
|
||||
<option value="Str 13"><span data-i18n="STR">Str</span> 13</option>
|
||||
<option value="Str 15"><span data-i18n="STR">Str</span> 15</option>
|
||||
<option value="Str 13" data-i18n="STR_13"></option>
|
||||
<option value="Str 15" data-i18n="STR_15"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-09 center pad-l-md">
|
||||
@@ -79,12 +79,12 @@
|
||||
<div class="col-12 center pad-r-md">
|
||||
<select name="attr_ac_unarmored_ability">
|
||||
<option value="" selected>—</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
<div class="small-label" data-i18n="AC_UNARMORED_ABILITY"></div>
|
||||
</div>
|
||||
@@ -92,10 +92,10 @@
|
||||
<span name="attr_ac_unarmored_calc" class="pseudo-input center border-bottom"></span>
|
||||
<div class="small-label" data-i18n="AC_UNARMORED"></div>
|
||||
</div>
|
||||
<div class="col-15 center bold">
|
||||
<div class="col-15 center">
|
||||
<button type="roll" name="roll_shaped_ac" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=^{AC}}} {{text_big=[[@{ac}]]}}">
|
||||
<div class="shield">
|
||||
<span name="attr_AC" class="pseudo-input center big-text bold"></span>
|
||||
<span name="attr_AC" class="pseudo-input center big-text"></span>
|
||||
<div class="wrap-box-title center" data-i18n="ARMOR_CLASS"></div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
@@ -16,5 +16,4 @@
|
||||
<input type="hidden" name="attr_shaped_d20" value="d20">
|
||||
<input type="hidden" name="attr_d20_mod">
|
||||
|
||||
<input type="hidden" name="attr_use_custom_saving_throws" class="toggle-use-custom-saving-throws hidden">
|
||||
<input type="hidden" name="attr_hide_ac" class="toggle-hide-ac hidden">
|
||||
<input type="hidden" name="attr_use_custom_saving_throws" class="toggle-use-custom-saving-throws hidden">
|
||||
@@ -7,105 +7,105 @@
|
||||
<input type="checkbox" name="attr_hd_d20_toggle" value="1" class="toggle-hd-d20 hidden">
|
||||
|
||||
<div class="shaped-row center flex-end toggle-hd-d2">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
<input type="number" name="attr_hd_d2" class="no-spin no-border" min="0" step="1">
|
||||
</div>
|
||||
<div class="col-05">/</div>
|
||||
<div class="col-30">
|
||||
<div class="col-29">
|
||||
<span name="attr_hd_d2_max" class="center"></span>
|
||||
</div>
|
||||
<input type="hidden" name="attr_hd_d2_query">
|
||||
<div class="col-33 center">
|
||||
<div class="col-37 center">
|
||||
<button type="roll" name="roll_shaped_hd_d2" class="bold" value="@{hit_dice_output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{hd_d2_query}d2 ^{HIT_DICE}}} {{uses=@{hd_d2}}} {{uses_max=@{hd_d2|max}}} @{roll_info} {{roll1=[[{((@{hd_d2_query})d2[d2 * hd] + ((@{hd_d2_query}) * @{constitution_mod})[con mod * hd]), 0d0+1}kh1[minimum of 1]]]}} @{attacher_hit_dice}">
|
||||
d2
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row center flex-end toggle-hd-d4">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
<input type="number" name="attr_hd_d4" class="no-spin no-border" min="0" step="1">
|
||||
</div>
|
||||
<div class="col-05">/</div>
|
||||
<div class="col-30">
|
||||
<div class="col-29">
|
||||
<span name="attr_hd_d4_max" class="center"></span>
|
||||
</div>
|
||||
<input type="hidden" name="attr_hd_d4_query">
|
||||
<div class="col-33 center">
|
||||
<div class="col-37 center">
|
||||
<button type="roll" name="roll_shaped_hd_d4" class="bold" value="@{hit_dice_output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{hd_d4_query}d4 ^{HIT_DICE}}} {{uses=@{hd_d4}}} {{uses_max=@{hd_d4|max}}} @{roll_info} {{roll1=[[{((@{hd_d4_query})d4[d4 * hd] + ((@{hd_d4_query}) * @{constitution_mod})[con mod * hd]), 0d0+1}kh1[minimum of 1]]]}} @{attacher_hit_dice}">
|
||||
d4
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row center flex-end toggle-hd-d6">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
<input type="number" name="attr_hd_d6" class="no-spin no-border" min="0" step="1">
|
||||
</div>
|
||||
<div class="col-05">/</div>
|
||||
<div class="col-30">
|
||||
<div class="col-29">
|
||||
<span name="attr_hd_d6_max" class="center"></span>
|
||||
</div>
|
||||
<input type="hidden" name="attr_hd_d6_query">
|
||||
<div class="col-33 center">
|
||||
<div class="col-37 center">
|
||||
<button type="roll" name="roll_shaped_hd_d6" class="bold" value="@{hit_dice_output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{hd_d6_query}d6 ^{HIT_DICE}}} {{uses=@{hd_d6}}} {{uses_max=@{hd_d6|max}}} @{roll_info} {{roll1=[[{((@{hd_d6_query})d6[d6 * hd] + ((@{hd_d6_query}) * @{constitution_mod})[con mod * hd]), 0d0+1}kh1[minimum of 1]]]}} @{attacher_hit_dice}">
|
||||
d6
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row center flex-end toggle-hd-d8">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
<input type="number" name="attr_hd_d8" class="no-spin no-border" min="0" step="1">
|
||||
</div>
|
||||
<div class="col-05">/</div>
|
||||
<div class="col-30">
|
||||
<div class="col-29">
|
||||
<span name="attr_hd_d8_max" class="center"></span>
|
||||
</div>
|
||||
<input type="hidden" name="attr_hd_d8_query">
|
||||
<div class="col-33 center">
|
||||
<div class="col-37 center">
|
||||
<button type="roll" name="roll_shaped_hd_d8" class="bold" value="@{hit_dice_output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{hd_d8_query}d8 ^{HIT_DICE}}} {{uses=@{hd_d8}}} {{uses_max=@{hd_d8|max}}} @{roll_info} {{roll1=[[{((@{hd_d8_query})d8[d8 * hd] + ((@{hd_d8_query}) * @{constitution_mod})[con mod * hd]), 0d0+1}kh1[minimum of 1]]]}} @{attacher_hit_dice}">
|
||||
d8
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row center flex-end toggle-hd-d10">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
<input type="number" name="attr_hd_d10" class="no-spin no-border" min="0" step="1">
|
||||
</div>
|
||||
<div class="col-05">/</div>
|
||||
<div class="col-30">
|
||||
<div class="col-29">
|
||||
<span name="attr_hd_d10_max" class="center"></span>
|
||||
</div>
|
||||
<input type="hidden" name="attr_hd_d10_query">
|
||||
<div class="col-33 center">
|
||||
<div class="col-37 center">
|
||||
<button type="roll" name="roll_shaped_hd_d10" class="bold" value="@{hit_dice_output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{hd_d10_query}d10 ^{HIT_DICE}}} {{uses=@{hd_d10}}} {{uses_max=@{hd_d10|max}}} @{roll_info} {{roll1=[[{((@{hd_d10_query})d10[d10 * hd] + ((@{hd_d10_query}) * @{constitution_mod})[con mod * hd]), 0d0+1}kh1[minimum of 1]]]}} @{attacher_hit_dice}">
|
||||
d10
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row center flex-end toggle-hd-d12">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
<input type="number" name="attr_hd_d12" class="no-spin no-border" min="0" step="1">
|
||||
</div>
|
||||
<div class="col-05">/</div>
|
||||
<div class="col-30">
|
||||
<div class="col-29">
|
||||
<span name="attr_hd_d12_max" class="center"></span>
|
||||
</div>
|
||||
<input type="hidden" name="attr_hd_d12_query">
|
||||
<div class="col-33 center">
|
||||
<div class="col-37 center">
|
||||
<button type="roll" name="roll_shaped_hd_d12" class="bold" value="@{hit_dice_output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{hd_d12_query}d12 ^{HIT_DICE}}} {{uses=@{hd_d12}}} {{uses_max=@{hd_d12|max}}} @{roll_info} {{roll1=[[{((@{hd_d12_query})d12[d12 * hd] + ((@{hd_d12_query}) * @{constitution_mod})[con mod * hd]), 0d0+1}kh1[minimum of 1]]]}} @{attacher_hit_dice}">
|
||||
d12
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row center flex-end toggle-hd-d20">
|
||||
<div class="col-30 pad-r-sm">
|
||||
<div class="col-29 pad-r-sm">
|
||||
<input type="number" name="attr_hd_d20" class="no-spin no-border" min="0" step="1">
|
||||
</div>
|
||||
<div class="col-05">/</div>
|
||||
<div class="col-30">
|
||||
<div class="col-29">
|
||||
<span name="attr_hd_d20_max" class="center"></span>
|
||||
</div>
|
||||
<input type="hidden" name="attr_hd_d20_query">
|
||||
<div class="col-33 center">
|
||||
<div class="col-37 center">
|
||||
<button type="roll" name="roll_shaped_hd_d20" class="bold" value="@{hit_dice_output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{hd_d20_query}d20 ^{HIT_DICE}}} {{uses=@{hd_d20}}} {{uses_max=@{hd_d20|max}}} @{roll_info} {{roll1=[[{((@{hd_d20_query})d20[d20 * hd] + ((@{hd_d20_query}) * @{constitution_mod})[con mod * hd]), 0d0+1}kh1[minimum of 1]]]}} @{attacher_hit_dice}">
|
||||
d20
|
||||
</button>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<div class="shaped-row center">
|
||||
<div class="col-40">
|
||||
<select name="attr_ability_checks_text_size">
|
||||
<option value="text" data-i18n="NORMAL">Normal</option>
|
||||
<option value="text_big" selected data-i18n="BIG">Big</option>
|
||||
<option value="text" data-i18n="NORMAL"></option>
|
||||
<option value="text_big" data-i18n="BIG" selected></option>
|
||||
</select>
|
||||
<div class="small-label" data-i18n="TEXT_SIZE"></div>
|
||||
</div>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<div class="shaped-row center">
|
||||
<div class="col-40">
|
||||
<select name="attr_saving_throws_text_size">
|
||||
<option value="text" data-i18n="NORMAL">Normal</option>
|
||||
<option value="text_big" selected data-i18n="BIG">Big</option>
|
||||
<option value="text" data-i18n="NORMAL"></option>
|
||||
<option value="text_big" data-i18n="BIG" selected></option>
|
||||
</select>
|
||||
<div class="small-label" data-i18n="TEXT_SIZE"></div>
|
||||
</div>
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
<div class="shaped-row center">
|
||||
<div class="col-40">
|
||||
<select name="attr_spells_text_size">
|
||||
<option value="" data-i18n="NORMAL">Normal</option>
|
||||
<option value="big" data-i18n="BIG">Big</option>
|
||||
<option value="" data-i18n="NORMAL"></option>
|
||||
<option value="big" data-i18n="BIG"></option>
|
||||
</select>
|
||||
<div class="small-label" data-i18n="TEXT_SIZE"></div>
|
||||
</div>
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
//= include ../actionComponents/range.html
|
||||
//= include ../actionComponents/recharge.html
|
||||
</div>
|
||||
<input type="checkbox" name="attr_toggle_details" class="toggle-icon-settings edit" checked><span class="toggle-icon-settings pictos edit">y</span>
|
||||
<input type="checkbox" name="attr_toggle_details" class="toggle-icon-settings edit"><span class="toggle-icon-settings pictos edit">y</span>
|
||||
<div class="details edit">
|
||||
//= include ../actionComponents/attack.html
|
||||
//= include ../actionComponents/attackSpell.html
|
||||
//= include ../actionComponents/savingThrow.html
|
||||
//= include ../actionComponents/damage.html
|
||||
//= include ../actionComponents/damageSecondary.html
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
<input type="number" name="attr_fortitude_save_bonus" class="no-spin small-label" value="0" step="1">
|
||||
</div>
|
||||
<button type="roll" name="roll_shaped_fortitude_saving_throw" class="inline" value="@{output_option} &{template:5e-shaped} {{saving_throw=1}} {{character_name=@{character_name}}} @{show_character_name} {{title=^{FORTITUDE} ^{SAVE}}} @{roll_info} {{roll1=[[@{shaped_d20} + @{fortitude_saving_throw_mod}]]}} @{roll_setting} + @{fortitude_saving_throw_mod}]]}} @{hide_gm_info} @{attacher_fortitude_saving_throw}" tabindex="-1">
|
||||
<span data-i18n="FORT"></span>
|
||||
<span data-i18n="FORTITUDE"></span>
|
||||
<span name="attr_fortitude_saving_throw_mod_with_sign" class="inline-block center"></span>
|
||||
</button>
|
||||
</div>
|
||||
@@ -99,7 +99,7 @@
|
||||
<input type="number" name="attr_reflex_save_bonus" class="no-spin small-label" value="0" step="1">
|
||||
</div>
|
||||
<button type="roll" name="roll_shaped_reflex_saving_throw" class="inline" value="@{output_option} &{template:5e-shaped} {{saving_throw=1}} {{character_name=@{character_name}}} @{show_character_name} {{title=^{REFLEX} ^{SAVE}}} @{roll_info} {{roll1=[[@{shaped_d20} + @{reflex_saving_throw_mod}]]}} @{roll_setting} + @{reflex_saving_throw_mod}]]}} @{hide_gm_info} @{attacher_reflex_saving_throw}" tabindex="-1">
|
||||
<span data-i18n="REF"></span>
|
||||
<span data-i18n="REFLEX"></span>
|
||||
<span name="attr_reflex_saving_throw_mod_with_sign" class="inline-block center"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<div class="shaped-row edit">
|
||||
<div class="col-20 pad-r-sm">
|
||||
<select name="attr_size" class="italic no-border" accept="Size">
|
||||
<option value="Tiny" data-i18n="TINY">Tiny</option>
|
||||
<option value="Small" data-i18n="SMALL">Small</option>
|
||||
<option value="Medium" data-i18n="MEDIUM">Medium</option>
|
||||
<option value="Large" data-i18n="LARGE" selected>Large</option>
|
||||
<option value="Huge" data-i18n="HUGE">Huge</option>
|
||||
<option value="Gargantuan" data-i18n="GARGANTUAN">Gargantuan</option>
|
||||
<option value="Tiny" data-i18n="TINY"></option>
|
||||
<option value="Small" data-i18n="SMALL"></option>
|
||||
<option value="Medium" data-i18n="MEDIUM"></option>
|
||||
<option value="Large" data-i18n="LARGE" selected></option>
|
||||
<option value="Huge" data-i18n="HUGE"></option>
|
||||
<option value="Gargantuan" data-i18n="GARGANTUAN"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-30 pad-l-sm pad-r-sm">
|
||||
|
||||
@@ -8,16 +8,16 @@
|
||||
<div class="shaped-row no-wrap vert-center">
|
||||
<div class="col-1-3-em no-shrink edit">
|
||||
<select name="attr_skill_d20">
|
||||
<option value="@{shaped_d20}" data-i18n="NORMAL">Normal</option>
|
||||
<option value="2d20@{d20_mod}kh1" data-i18n="ADVANTAGE">Advantage</option>
|
||||
<option value="2d20@{d20_mod}kl1" data-i18n="DISADVANTAGE">Disadvantage</option>
|
||||
<option value="@{shaped_d20}" data-i18n="NORMAL"></option>
|
||||
<option value="2d20@{d20_mod}kh1" data-i18n="ADVANTAGE"></option>
|
||||
<option value="2d20@{d20_mod}kl1" data-i18n="DISADVANTAGE"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-1-3-em skill-select-wrapper edit">
|
||||
<select name="attr_proficiency" class="no-border">
|
||||
<option value="unproficient">—   <span data-i18n="UNPROFICIENT">Unproficient</span></option>
|
||||
<option value="proficient">✓    <span data-i18n="PROFICIENT">Proficient</span></option>
|
||||
<option value="expertise">✗    <span data-i18n="EXPERTISE">Expertise</span></option>
|
||||
<option value="unproficient" data-i18n="SKILL_SELECT_UNPROFICIENT"></option>
|
||||
<option value="proficient" data-i18n="SKILL_SELECT_PROFICIENT"></option>
|
||||
<option value="expertise" data-i18n="SKILL_SELECT_EXPERTISE"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-1-3-em edit">
|
||||
@@ -40,12 +40,12 @@
|
||||
<span>(</span>
|
||||
<select name="attr_ability" class="skills-ability-selector">
|
||||
<option value="0">—</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX">Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX"></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
<span>)</span>
|
||||
</div>
|
||||
|
||||
@@ -100,15 +100,10 @@
|
||||
{{#targetName}}
|
||||
<span>{{targetName}}</span>
|
||||
{{/targetName}}
|
||||
{{^vs_saving_throw}}
|
||||
<span data-i18n="AC">AC</span>
|
||||
{{#targetAC}}
|
||||
<span>{{targetAC}}</span>
|
||||
{{/targetAC}}
|
||||
{{/vs_saving_throw}}
|
||||
{{#vs_saving_throw}}
|
||||
<span>[<span data-i18n="{{vs_saving_throw}}">{{vs_saving_throw}}</span>](~target|shaped_{{vs_saving_throw}}_saving_throw)</span>
|
||||
{{/vs_saving_throw}}
|
||||
<span data-i18n="AC">AC</span>
|
||||
{{#targetAC}}
|
||||
<span>{{targetAC}}</span>
|
||||
{{/targetAC}}
|
||||
</div>
|
||||
{{/vs_ac}}
|
||||
</div>
|
||||
@@ -298,12 +293,12 @@
|
||||
{{#text_big}}
|
||||
<div class="output-small">{{text_big}}</div>
|
||||
{{/text_big}}
|
||||
{{#allprops() freetext text text_center text_big text_top character_name saving_throw title ignore show_character_name subheader uses uses_max roll1 roll2 advantage disadvantage vs_ac vs_saving_throw ability emote death_saving_throw death_saving_throw_successes death_saving_throw_failures targetAC targetName action type crit_name crit_text damage damage_type crit_damage second_damage second_damage_type second_crit_damage ranged damage target reach range ammo ammo_name spell spell_list saving_throw_condition saving_throw_dc saving_throw_vs_ability saving_throw_success saving_throw_failure spell_level school ritual content cast_as_level heal casting_time duration components materials hide_ability_checks hide_saving_throws hide_saving_throw_dc hide_spell_content hide_freetext hide_attack hide_damage hide_saving_throw_failure hide_saving_throw_success recharge hide_recharge fx trait armor equipment cantrips spells_level_1 spells_level_1_uses spells_level_1_show spells_level_2 spells_level_2_uses spells_level_2_show spells_level_3 spells_level_3_uses spells_level_3_show spells_level_4 spells_level_4_uses spells_level_4_show spells_level_5 spells_level_5_uses spells_level_5_show spells_level_6 spells_level_6_uses spells_level_6_show spells_level_7 spells_level_7_uses spells_level_7_show spells_level_8 spells_level_8_uses spells_level_8_show spells_level_9 spells_level_9_uses spells_level_9_show spells_text_size}}
|
||||
{{#allprops() freetext text text_center text_big text_top character_name saving_throw title ignore show_character_name subheader uses uses_max roll1 roll2 advantage disadvantage vs_ac ability emote death_saving_throw death_saving_throw_successes death_saving_throw_failures targetAC targetName action type crit_name crit_text damage damage_type crit_damage second_damage second_damage_type second_crit_damage ranged damage target reach range ammo ammo_name spell spell_list saving_throw_condition saving_throw_dc saving_throw_vs_ability saving_throw_success saving_throw_failure spell_level school ritual content cast_as_level heal casting_time duration components materials hide_ability_checks hide_saving_throws hide_saving_throw_dc hide_spell_content hide_freetext hide_attack hide_damage hide_saving_throw_failure hide_saving_throw_success recharge hide_recharge fx trait armor equipment cantrips spells_level_1 spells_level_1_uses spells_level_1_show spells_level_2 spells_level_2_uses spells_level_2_show spells_level_3 spells_level_3_uses spells_level_3_show spells_level_4 spells_level_4_uses spells_level_4_show spells_level_5 spells_level_5_uses spells_level_5_show spells_level_6 spells_level_6_uses spells_level_6_show spells_level_7 spells_level_7_uses spells_level_7_show spells_level_8 spells_level_8_uses spells_level_8_show spells_level_9 spells_level_9_uses spells_level_9_show spells_text_size}}
|
||||
<div>
|
||||
<span class="bold italic">{{key}}.</span>
|
||||
{{value}}
|
||||
</div>
|
||||
{{/allprops() freetext text text_center text_big text_top character_name saving_throw title ignore show_character_name subheader uses uses_max roll1 roll2 advantage disadvantage vs_ac vs_saving_throw ability emote death_saving_throw death_saving_throw_successes death_saving_throw_failures targetAC targetName action type crit_name crit_text damage damage_type crit_damage second_damage second_damage_type second_crit_damage ranged damage target reach range ammo ammo_name spell spell_list saving_throw_condition saving_throw_dc saving_throw_vs_ability saving_throw_success saving_throw_failure spell_level school ritual content cast_as_level heal casting_time duration components materials hide_ability_checks hide_saving_throws hide_saving_throw_dc hide_spell_content hide_freetext hide_attack hide_damage hide_saving_throw_failure hide_saving_throw_success recharge hide_recharge fx trait armor equipment cantrips spells_level_1 spells_level_1_uses spells_level_1_show spells_level_2 spells_level_2_uses spells_level_2_show spells_level_3 spells_level_3_uses spells_level_3_show spells_level_4 spells_level_4_uses spells_level_4_show spells_level_5 spells_level_5_uses spells_level_5_show spells_level_6 spells_level_6_uses spells_level_6_show spells_level_7 spells_level_7_uses spells_level_7_show spells_level_8 spells_level_8_uses spells_level_8_show spells_level_9 spells_level_9_uses spells_level_9_show spells_text_size}}
|
||||
{{/allprops() freetext text text_center text_big text_top character_name saving_throw title ignore show_character_name subheader uses uses_max roll1 roll2 advantage disadvantage vs_ac ability emote death_saving_throw death_saving_throw_successes death_saving_throw_failures targetAC targetName action type crit_name crit_text damage damage_type crit_damage second_damage second_damage_type second_crit_damage ranged damage target reach range ammo ammo_name spell spell_list saving_throw_condition saving_throw_dc saving_throw_vs_ability saving_throw_success saving_throw_failure spell_level school ritual content cast_as_level heal casting_time duration components materials hide_ability_checks hide_saving_throws hide_saving_throw_dc hide_spell_content hide_freetext hide_attack hide_damage hide_saving_throw_failure hide_saving_throw_success recharge hide_recharge fx trait armor equipment cantrips spells_level_1 spells_level_1_uses spells_level_1_show spells_level_2 spells_level_2_uses spells_level_2_show spells_level_3 spells_level_3_uses spells_level_3_show spells_level_4 spells_level_4_uses spells_level_4_show spells_level_5 spells_level_5_uses spells_level_5_show spells_level_6 spells_level_6_uses spells_level_6_show spells_level_7 spells_level_7_uses spells_level_7_show spells_level_8 spells_level_8_uses spells_level_8_show spells_level_9 spells_level_9_uses spells_level_9_show spells_text_size}}
|
||||
|
||||
{{#freetext}}
|
||||
<div class="{{#hide_freetext}} gm-info-block{{/hide_freetext}}">{{freetext}}</div>
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
<div class="wrap-box relative">
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="AMMO_AUTO_USE"></span>
|
||||
<input type="checkbox" name="attr_ammo_auto_use" class="mar-l-md" value="1">
|
||||
<input type="checkbox" name="attr_ammo_auto_use" class="mar-l-md no-shrink" value="1">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="AUTO_REVERT_ADV"></span>
|
||||
<input type="checkbox" name="attr_auto_revert_advantage" class="mar-l-md">
|
||||
<input type="checkbox" name="attr_auto_revert_advantage" class="mar-l-md no-shrink">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="SHOW_RESTS"></span>
|
||||
<input type="checkbox" name="attr_show_rests" class="mar-l-md">
|
||||
<input type="checkbox" name="attr_show_rests" class="mar-l-md no-shrink">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center no-wrap">
|
||||
<span class="small-label" data-i18n="EXPERTISE_AS_ADVANTAGE"></span>
|
||||
<input type="checkbox" name="attr_expertise_as_advantage" class="mar-l-md no-shrink" value="1">
|
||||
</div>
|
||||
<div class="tooltip-position-wrapper">
|
||||
<div class="tooltip">
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
<div class="wrap-box">
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="COIN_CONVERSION_GP_PER_CP"></span>
|
||||
<div class="col-25">
|
||||
<input type="number" name="attr_copper_per_gold" value="100">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="COIN_CONVERSION_GP_PER_SP"></span>
|
||||
<div class="col-25">
|
||||
<input type="number" name="attr_silver_per_gold" value="10">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="COIN_CONVERSION_GP_PER_EP"></span>
|
||||
<div class="col-25">
|
||||
<input type="number" name="attr_electrum_per_gold" value="2">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center">
|
||||
<div class="shaped-row space-between vert-center no-wrap">
|
||||
<span class="small-label" data-i18n="COIN_CONVERSION_GP_PER_PP"></span>
|
||||
<div class="col-25">
|
||||
<input type="number" name="attr_platinum_per_gold" value="10">
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="USE_CUSTOM_SAVING_THROWS"></span><input type="checkbox" name="attr_use_custom_saving_throws" value="1">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="USE_CUSTOM_SAVING_THROWS"></span>
|
||||
<input type="checkbox" name="attr_use_custom_saving_throws" class="mar-l-md no-shrink" value="1">
|
||||
</div>
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="AVERAGE_OF_ABILITIES"></span><input type="checkbox" name="attr_average_of_abilities" value="1">
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="AVERAGE_OF_ABILITIES"></span>
|
||||
<input type="checkbox" name="attr_average_of_abilities" class="mar-l-md no-shrink" value="1">
|
||||
</div>
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="FORTITUDE">Fortitude</span>
|
||||
<div>
|
||||
<div class="shaped-row vert-center">
|
||||
<div class="shaped-row vert-center justify-flex-end no-wrap">
|
||||
<div>
|
||||
<span class="small-label" data-i18n="STR">Str</span><input type="checkbox" name="attr_fortitude_strength" value="1">
|
||||
</div>
|
||||
@@ -18,7 +20,7 @@
|
||||
<span class="small-label" data-i18n="CON">Con</span><input type="checkbox" name="attr_fortitude_constitution" value="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row vert-center justify-flex-end">
|
||||
<div class="shaped-row vert-center justify-flex-end no-wrap">
|
||||
<div>
|
||||
<span class="small-label" data-i18n="INT">Int</span><input type="checkbox" name="attr_fortitude_intelligence" value="1">
|
||||
</div>
|
||||
@@ -32,10 +34,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<hr class="custom-saving-throw">
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="REFLEX">Reflex</span>
|
||||
<div>
|
||||
<div class="shaped-row vert-center">
|
||||
<div class="shaped-row vert-center justify-flex-end no-wrap">
|
||||
<div>
|
||||
<span class="small-label" data-i18n="STR">Str</span><input type="checkbox" name="attr_reflex_strength" value="1">
|
||||
</div>
|
||||
@@ -46,7 +48,7 @@
|
||||
<span class="small-label" data-i18n="CON">Con</span><input type="checkbox" name="attr_reflex_constitution" value="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row vert-center justify-flex-end">
|
||||
<div class="shaped-row vert-center justify-flex-end no-wrap">
|
||||
<div>
|
||||
<span class="small-label" data-i18n="INT">Int</span><input type="checkbox" name="attr_reflex_intelligence" value="1">
|
||||
</div>
|
||||
@@ -60,10 +62,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<hr class="custom-saving-throw">
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="custom-saving-throw shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="WILL">Will</span>
|
||||
<div>
|
||||
<div class="shaped-row vert-center">
|
||||
<div class="shaped-row vert-center justify-flex-end no-wrap">
|
||||
<div>
|
||||
<span class="small-label" data-i18n="STR">Str</span><input type="checkbox" name="attr_will_strength" value="1">
|
||||
</div>
|
||||
@@ -74,7 +76,7 @@
|
||||
<span class="small-label" data-i18n="CON">Con</span><input type="checkbox" name="attr_will_constitution" value="1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row vert-center justify-flex-end">
|
||||
<div class="shaped-row vert-center justify-flex-end no-wrap">
|
||||
<div>
|
||||
<span class="small-label" data-i18n="INT">Int</span><input type="checkbox" name="attr_will_intelligence" value="1">
|
||||
</div>
|
||||
|
||||
@@ -1,44 +1,46 @@
|
||||
<div class="wrap-box relative">
|
||||
<input type="hidden" name="attr_hide_gm_info" value="@{hide_attack} @{hide_damage} @{hide_ability_checks} @{hide_saving_throws} @{hide_saving_throw_dc} @{hide_spell_content} @{hide_action_freetext} @{hide_saving_throw_failure} @{hide_saving_throw_success} @{hide_recharge}">
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_ATTACK"></span>
|
||||
<input type="checkbox" name="attr_hide_attack" class="mar-l-md" value="{{hide_attack=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_DAMAGE"></span>
|
||||
<input type="checkbox" name="attr_hide_damage" class="mar-l-md" value="{{hide_damage=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<input type="hidden" name="attr_hide_gm_info" value="@{hide_attack} @{hide_damage} @{hide_ability_checks} @{hide_saving_throws} @{hide_saving_throw_dc} @{hide_spell_content} @{hide_freetext} @{hide_saving_throw_failure} @{hide_saving_throw_success} @{hide_recharge}">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_ABILITY_CHECKS"></span>
|
||||
<input type="checkbox" name="attr_hide_ability_checks" class="mar-l-md" value="{{hide_ability_checks=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_SAVING_THROWS"></span>
|
||||
<input type="checkbox" name="attr_hide_saving_throws" class="mar-l-md" value="{{hide_saving_throws=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<hr>
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_ATTACK"></span>
|
||||
<input type="checkbox" name="attr_hide_attack" class="mar-l-md" value="{{hide_attack=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_DAMAGE"></span>
|
||||
<input type="checkbox" name="attr_hide_damage" class="mar-l-md" value="{{hide_damage=1}}">
|
||||
</div>
|
||||
<hr>
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_FREETEXT"></span>
|
||||
<input type="checkbox" name="attr_hide_freetext" class="mar-l-md" value="{{hide_freetext=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_RECHARGE"></span>
|
||||
<input type="checkbox" name="attr_hide_recharge" class="mar-l-md" value="{{hide_recharge=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_SAVING_THROW_DC"></span>
|
||||
<input type="checkbox" name="attr_hide_saving_throw_dc" class="mar-l-md" value="{{hide_saving_throw_dc=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_SPELL_CONTENT"></span>
|
||||
<input type="checkbox" name="attr_hide_spell_content" class="mar-l-md" value="{{hide_spell_content=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_ACTION_FREETEXT"></span>
|
||||
<input type="checkbox" name="attr_hide_action_freetext" class="mar-l-md" value="{{hide_freetext=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_SAVING_THROW_FAILURE"></span>
|
||||
<input type="checkbox" name="attr_hide_saving_throw_failure" class="mar-l-md" value="{{hide_saving_throw_failure=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_SAVING_THROW_SUCCESS"></span>
|
||||
<input type="checkbox" name="attr_hide_saving_throw_success" class="mar-l-md" value="{{hide_saving_throw_success=1}}">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_RECHARGE"></span>
|
||||
<input type="checkbox" name="attr_hide_recharge" class="mar-l-md" value="{{hide_recharge=1}}">
|
||||
<div class="shaped-row space-between vert-center no-wrap">
|
||||
<span class="small-label" data-i18n="HIDE_INFO_SPELL_CONTENT"></span>
|
||||
<input type="checkbox" name="attr_hide_spell_content" class="mar-l-md" value="{{hide_spell_content=1}}">
|
||||
</div>
|
||||
<div class="tooltip-position-wrapper">
|
||||
<div class="tooltip">
|
||||
|
||||
@@ -1,36 +1,16 @@
|
||||
<div class="wrap-box">
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="wrap-box mar-b-smd">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label center" data-i18n="BASE_DC"></span>
|
||||
<div class="col-15">
|
||||
<input type="number" name="attr_base_dc" value="8">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label center" data-i18n="MEDIUM_ARMOR_MAX_DEX"></span>
|
||||
<div class="col-15">
|
||||
<input type="number" name="attr_medium_armor_max_dex" value="2">
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="HIDE_AC"></span><input type="checkbox" name="attr_hide_ac" value="1">
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<span class="small-label" data-i18n="ATTACKS_VS_A_SAVING_THROW"></span>
|
||||
<div class="col-15">
|
||||
<select name="attr_attacks_vs_a_saving_throw">
|
||||
<option value="">—</option>
|
||||
<option value="STRENGTH" data-i18n="STR" class="default-saving-throw">Str</option>
|
||||
<option value="DEXTERITY" data-i18n="DEX" class="default-saving-throw">Dex</option>
|
||||
<option value="CONSTITUTION" data-i18n="CON" class="default-saving-throw">Con</option>
|
||||
<option value="INTELLIGENCE" data-i18n="INT" class="default-saving-throw">Int</option>
|
||||
<option value="WISDOM" data-i18n="WIS" class="default-saving-throw">Wis</option>
|
||||
<option value="CHARISMA" data-i18n="CHA" class="default-saving-throw">Cha</option>
|
||||
<option value="FORTITUDE" data-i18n="FORT" class="custom-saving-throw">Fort</option>
|
||||
<option value="REFLEX" data-i18n="REF" class="custom-saving-throw">Ref</option>
|
||||
<option value="WILL" data-i18n="WILL" class="custom-saving-throw">Will</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wrap-box-title center" data-i18n="HOUSERULES"></div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
<span class="small-label" data-i18n="OUTPUT"></span>
|
||||
<div class="col-60">
|
||||
<select name="attr_initiative_output_option">
|
||||
<option value="@{output_option}" data-i18n="SHEET_OUTPUT" selected>Sheet output</option>
|
||||
<option value="" data-i18n="PUBLIC_FOR_ALL">Public for all to see</option>
|
||||
<option value="/w GM" data-i18n="WHISPERED_TO_GM">Whispered to the GM</option>
|
||||
<option value="@{output_option}" data-i18n="SHEET_OUTPUT" selected></option>
|
||||
<option value="" data-i18n="PUBLIC_FOR_ALL"></option>
|
||||
<option value="/w GM" data-i18n="WHISPERED_TO_GM"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -13,9 +13,9 @@
|
||||
<span class="small-label" data-i18n="ROLL_OPTIONS"></span>
|
||||
<div class="col-60">
|
||||
<select name="attr_initiative_roll">
|
||||
<option value="@{shaped_d20}" data-i18n="NORMAL">Normal</option>
|
||||
<option value="2d20@{d20_mod}kh1" data-i18n="ADVANTAGE">Advantage</option>
|
||||
<option value="2d20@{d20_mod}kl1" data-i18n="DISADVANTAGE">Disadvantage</option>
|
||||
<option value="@{shaped_d20}" data-i18n="NORMAL"></option>
|
||||
<option value="2d20@{d20_mod}kh1" data-i18n="ADVANTAGE"></option>
|
||||
<option value="2d20@{d20_mod}kl1" data-i18n="DISADVANTAGE"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,8 +23,8 @@
|
||||
<span class="small-label" data-i18n="TRACKER"></span>
|
||||
<div class="col-60">
|
||||
<select name="attr_initiative_to_tracker">
|
||||
<option value="@{selected|initiative_formula} &{tracker}" data-i18n="TO_TRACKER" selected>Send to Tracker</option>
|
||||
<option value="@{initiative_formula}" data-i18n="DONT">Don't</option>
|
||||
<option value="@{selected|initiative_formula} &{tracker}" data-i18n="TO_TRACKER" selected></option>
|
||||
<option value="@{initiative_formula}" data-i18n="DONT"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -36,13 +36,13 @@
|
||||
<span class="small-label" data-i18n="INITIATIVE_ABILITY"></span>
|
||||
<div class="col-20">
|
||||
<select name="attr_initiative_ability">
|
||||
<option value="">—</option>
|
||||
<option value="strength" data-i18n="STR">Str</option>
|
||||
<option value="dexterity" data-i18n="DEX" selected>Dex</option>
|
||||
<option value="constitution" data-i18n="CON">Con</option>
|
||||
<option value="intelligence" data-i18n="INT">Int</option>
|
||||
<option value="wisdom" data-i18n="WIS">Wis</option>
|
||||
<option value="charisma" data-i18n="CHA">Cha</option>
|
||||
<option value="0">—</option>
|
||||
<option value="strength" data-i18n="STR"></option>
|
||||
<option value="dexterity" data-i18n="DEX" selected></option>
|
||||
<option value="constitution" data-i18n="CON"></option>
|
||||
<option value="intelligence" data-i18n="INT"></option>
|
||||
<option value="wisdom" data-i18n="WIS"></option>
|
||||
<option value="charisma" data-i18n="CHA"></option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<div class="wrap-box">
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="CHARACTER_NAME_ON_ROLL_TEMPLATES"></span>
|
||||
<div class="col-15">
|
||||
<select name="attr_show_character_name">
|
||||
@@ -8,7 +8,7 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="SHOW_TARGET_AC_ON_ATTACKS"></span>
|
||||
<div class="col-15">
|
||||
<select name="attr_attacks_vs_target_ac">
|
||||
@@ -17,7 +17,7 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="shaped-row space-between vert-center">
|
||||
<div class="shaped-row space-between vert-center no-wrap">
|
||||
<span class="small-label" data-i18n="SHOW_TARGET_NAME_ON_ATTACKS"></span>
|
||||
<div class="col-15">
|
||||
<select name="attr_attacks_vs_target_name">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<div class="wrap-box">
|
||||
<div class="shaped-row space-between vert-center mar-b-sm">
|
||||
<div class="shaped-row space-between vert-center no-wrap mar-b-sm">
|
||||
<span class="small-label" data-i18n="ADD_HALF_PROFICIENCY_TO_UNPROFICIENT_SAVING_THROWS"></span>
|
||||
<input type="checkbox" name="attr_saving_throws_half_proficiency" class="mar-l-md">
|
||||
<input type="checkbox" name="attr_saving_throws_half_proficiency" class="mar-l-md no-shrink">
|
||||
</div>
|
||||
//= include customSavingThrows.html
|
||||
<div class="wrap-box-title center" data-i18n="SAVING_THROWS">Saving throws</div>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="col-28 pad-l-sm pad-r-sm">
|
||||
//= include rollTemplate.html
|
||||
</div>
|
||||
<div class="pad-l-sm">
|
||||
<div class="col-22 pad-l-sm">
|
||||
//= include api.html
|
||||
</div>
|
||||
<div class="pad-l-sm pad-r-sm">
|
||||
@@ -23,11 +23,9 @@
|
||||
</div>
|
||||
<div class="col-22 pad-l-sm pad-r-sm">
|
||||
//= include houserules.html
|
||||
</div>
|
||||
<div class="col-22 pad-l-sm pad-r-sm">
|
||||
//= include savingThrows.html
|
||||
</div>
|
||||
<div class="pad-l-sm pad-r-sm">
|
||||
<div class="col-20 pad-l-sm pad-r-sm">
|
||||
//= include hideInfo.html
|
||||
</div>
|
||||
<div class="col-22 pad-r-sm">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -70,28 +70,28 @@
|
||||
<div class="shaped-row vert-center">
|
||||
<div class="col-18">
|
||||
<select name="attr_spell_level" class="italic no-border" accept="Level">
|
||||
<option value="CANTRIP" data-i18n="CANTRIP">Cantrip</option>
|
||||
<option value="1ST_LEVEL" data-i18n="1ST_LEVEL">1st-level</option>
|
||||
<option value="2ND_LEVEL" data-i18n="2ND_LEVEL">2nd-level</option>
|
||||
<option value="3RD_LEVEL" data-i18n="3RD_LEVEL">3rd-level</option>
|
||||
<option value="4TH_LEVEL" data-i18n="4TH_LEVEL">4th-level</option>
|
||||
<option value="5TH_LEVEL" data-i18n="5TH_LEVEL">5th-level</option>
|
||||
<option value="6TH_LEVEL" data-i18n="6TH_LEVEL">6th-level</option>
|
||||
<option value="7TH_LEVEL" data-i18n="7TH_LEVEL">7th-level</option>
|
||||
<option value="8TH_LEVEL" data-i18n="8TH_LEVEL">8th-level</option>
|
||||
<option value="9TH_LEVEL" data-i18n="9TH_LEVEL">9th-level</option>
|
||||
<option value="CANTRIP" data-i18n="CANTRIP"></option>
|
||||
<option value="1ST_LEVEL" data-i18n="1ST_LEVEL"></option>
|
||||
<option value="2ND_LEVEL" data-i18n="2ND_LEVEL"></option>
|
||||
<option value="3RD_LEVEL" data-i18n="3RD_LEVEL"></option>
|
||||
<option value="4TH_LEVEL" data-i18n="4TH_LEVEL"></option>
|
||||
<option value="5TH_LEVEL" data-i18n="5TH_LEVEL"></option>
|
||||
<option value="6TH_LEVEL" data-i18n="6TH_LEVEL"></option>
|
||||
<option value="7TH_LEVEL" data-i18n="7TH_LEVEL"></option>
|
||||
<option value="8TH_LEVEL" data-i18n="8TH_LEVEL"></option>
|
||||
<option value="9TH_LEVEL" data-i18n="9TH_LEVEL"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-26 center">
|
||||
<select name="attr_school" class="italic no-border">
|
||||
<option value="ABJURATION" data-i18n="ABJURATION">Abjuration</option>
|
||||
<option value="CONJURATION" data-i18n="CONJURATION">Conjuration</option>
|
||||
<option value="DIVINATION" data-i18n="DIVINATION">Divination</option>
|
||||
<option value="ENCHANTMENT" data-i18n="ENCHANTMENT">Enchantment</option>
|
||||
<option value="EVOCATION" data-i18n="EVOCATION">Evocation</option>
|
||||
<option value="ILLUSION" data-i18n="ILLUSION">Illusion</option>
|
||||
<option value="NECROMANCY" data-i18n="NECROMANCY">Necromancy</option>
|
||||
<option value="TRANSMUTATION" data-i18n="TRANSMUTATION">Transmutation</option>
|
||||
<option value="ABJURATION" data-i18n="ABJURATION"></option>
|
||||
<option value="CONJURATION" data-i18n="CONJURATION"></option>
|
||||
<option value="DIVINATION" data-i18n="DIVINATION"></option>
|
||||
<option value="ENCHANTMENT" data-i18n="ENCHANTMENT"></option>
|
||||
<option value="EVOCATION" data-i18n="EVOCATION"></option>
|
||||
<option value="ILLUSION" data-i18n="ILLUSION"></option>
|
||||
<option value="NECROMANCY" data-i18n="NECROMANCY"></option>
|
||||
<option value="TRANSMUTATION" data-i18n="TRANSMUTATION"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mar-l-lg">
|
||||
@@ -125,13 +125,13 @@
|
||||
<span class="bold mar-r-sm"><span data-i18n="COMPONENTS"></span>:</span>
|
||||
<div class="col-14 center pad-l-sm">
|
||||
<select name="attr_components" class="no-border">
|
||||
<option value="COMPONENTS_V_S_M" data-i18n="COMPONENTS_V_S_M">V, S, M</option>
|
||||
<option value="COMPONENTS_V_S" data-i18n="COMPONENTS_V_S">V, S</option>
|
||||
<option value="COMPONENTS_V_M" data-i18n="COMPONENTS_V_M">V, M</option>
|
||||
<option value="COMPONENTS_V" data-i18n="COMPONENTS_V">V</option>
|
||||
<option value="COMPONENTS_S_M" data-i18n="COMPONENTS_S_M">S, M</option>
|
||||
<option value="COMPONENTS_S" data-i18n="COMPONENTS_S">S</option>
|
||||
<option value="COMPONENTS_M" data-i18n="COMPONENTS_M">M</option>
|
||||
<option value="COMPONENTS_V_S_M" data-i18n="COMPONENTS_V_S_M"></option>
|
||||
<option value="COMPONENTS_V_S" data-i18n="COMPONENTS_V_S"></option>
|
||||
<option value="COMPONENTS_V_M" data-i18n="COMPONENTS_V_M"></option>
|
||||
<option value="COMPONENTS_V" data-i18n="COMPONENTS_V"></option>
|
||||
<option value="COMPONENTS_S_M" data-i18n="COMPONENTS_S_M"></option>
|
||||
<option value="COMPONENTS_S" data-i18n="COMPONENTS_S"></option>
|
||||
<option value="COMPONENTS_M" data-i18n="COMPONENTS_M"></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="flex-grow pad-l-sm">
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<div class="edit small-label center" data-i18n="USES"></div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="roll" name="roll_trait" class="presentation trait wrapper-button traits-presentation-wrapper" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{name}}} {{trait=1}} {{recharge=@{recharge}}} @{saving_throw_toggle} @{damage_toggle} @{second_damage_toggle} {{uses=@{uses}}} {{uses_max=@{uses|max}}} @{heal_toggle} @{hide_gm_info} @{extras_toggle}">
|
||||
<button type="roll" name="roll_trait" class="presentation trait wrapper-button" value="@{output_option} &{template:5e-shaped} {{character_name=@{character_name}}} @{show_character_name} {{title=@{name}}} {{trait=1}} {{recharge=@{recharge}}} @{saving_throw_toggle} @{damage_toggle} @{second_damage_toggle} {{uses=@{uses}}} {{uses_max=@{uses|max}}} @{heal_toggle} @{hide_gm_info} @{extras_toggle}">
|
||||
<span class="heading"></span>
|
||||
<span name="attr_name" class="bold italic"></span><span name="attr_recharge_display" class="bold italic"></span><span class="bold italic">.</span>
|
||||
<span name="attr_display_text" class="pre-line"></span>
|
||||
|
||||
@@ -21,12 +21,17 @@ const request = require('request');
|
||||
const gutil = require('gulp-util');
|
||||
const sortJSON = require('gulp-json-sort').default;
|
||||
|
||||
String.prototype.capitalize = function () {
|
||||
return this.replace(/\w\S*/g, function (txt) {
|
||||
const browserify = require('browserify');
|
||||
const babelify = require('babelify');
|
||||
const source = require('vinyl-source-stream');
|
||||
const buffer = require('vinyl-buffer');
|
||||
|
||||
String.prototype.capitalize = () => {
|
||||
return this.replace(/\w\S*/g, (txt) => {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1)
|
||||
});
|
||||
};
|
||||
String.prototype.lowercase = function () {
|
||||
String.prototype.lowercase = () => {
|
||||
return this.toLowerCase();
|
||||
};
|
||||
|
||||
@@ -69,22 +74,24 @@ const compileSheetHTML = () => {
|
||||
}));
|
||||
};
|
||||
const compileSheetWorkers = () => {
|
||||
return gulp.src(['components/sheetWorkers.js'])
|
||||
.pipe(babel({
|
||||
return browserify('./scripts/sheetWorkers.js')
|
||||
.transform(babelify, {
|
||||
presets: ['es2015'],
|
||||
comments: false,
|
||||
compact: true
|
||||
}))
|
||||
}).bundle()
|
||||
.pipe(source('sheetWorkers.js'))
|
||||
.pipe(buffer())
|
||||
.pipe(wrapper({
|
||||
header: '<script type="text/worker">',
|
||||
footer: '</script>'
|
||||
}));
|
||||
}))
|
||||
};
|
||||
const compileRollTemplate = () => {
|
||||
return gulp.src(['./components/rollTemplate.html']);
|
||||
};
|
||||
|
||||
gulp.task('compile', ['sass', 'translationDist'], function () {
|
||||
gulp.task('compile', ['sass', 'translationDist'], () => {
|
||||
return streamqueue({objectMode: true},
|
||||
compileSheetHTML(),
|
||||
compileSheetWorkers(),
|
||||
@@ -94,22 +101,9 @@ gulp.task('compile', ['sass', 'translationDist'], function () {
|
||||
.pipe(gulp.dest('../'))
|
||||
});
|
||||
|
||||
const esLintConfig = {
|
||||
parser: 'babel-eslint',
|
||||
extends: 'airbnb/base',
|
||||
rules: {
|
||||
'arrow-body-style': 0,
|
||||
'indent': 0,
|
||||
'max-len': 0,
|
||||
'no-cond-assign': 0,
|
||||
'no-console': 0,
|
||||
'no-param-reassign': 0,
|
||||
'no-undef': 0
|
||||
}
|
||||
};
|
||||
gulp.task('lint', function () {
|
||||
return gulp.src(['components/sheetWorkers.js'])
|
||||
.pipe(eslint(esLintConfig))
|
||||
gulp.task('lint', () => {
|
||||
return gulp.src(['./scripts/*.js'])
|
||||
.pipe(eslint())
|
||||
.pipe(eslint.format())
|
||||
.pipe(eslint.failAfterError());
|
||||
});
|
||||
@@ -126,23 +120,23 @@ const sassConfig = {
|
||||
include: 0
|
||||
}
|
||||
};
|
||||
gulp.task('sass', function () {
|
||||
gulp.task('sass', () => {
|
||||
return gulp.src('./5eShaped.scss')
|
||||
.pipe(sass().on('error', sass.logError))
|
||||
.pipe(autoprefixer())
|
||||
.pipe(minifyCss())
|
||||
.pipe(gulp.dest('../'));
|
||||
});
|
||||
gulp.task('sass-lint', function() {
|
||||
gulp.task('sass-lint', () => {
|
||||
return gulp.src('./5eShaped.scss')
|
||||
.pipe(sassLint(sassConfig))
|
||||
.pipe(sassLint.format())
|
||||
.pipe(sassLint.failOnError())
|
||||
});
|
||||
|
||||
gulp.task('sort-translations', function() {
|
||||
gulp.task('sort-translations', () => {
|
||||
return gulp.src('../translations/*.json')
|
||||
.pipe(sortJSON({ space: 1 }))
|
||||
.pipe(sortJSON({ space: 2 }))
|
||||
.pipe(replaceTask({
|
||||
patterns: [
|
||||
{
|
||||
@@ -192,7 +186,7 @@ gulp.task('submit', ['compile'], (done) => {
|
||||
);
|
||||
});
|
||||
|
||||
gulp.task('translationDist', function () {
|
||||
gulp.task('translationDist', () => {
|
||||
return gulp.src('../translations/en.json')
|
||||
.pipe(rename('translation.json'))
|
||||
.pipe(gulp.dest('../'));
|
||||
|
||||
@@ -1,33 +1,41 @@
|
||||
{
|
||||
"name": "5eShaped",
|
||||
"version": "5.0.6",
|
||||
"version": "6.0.4",
|
||||
"bin": "./",
|
||||
"description": "5e Shaped character sheet for Roll20.net",
|
||||
"main": "gulpfile.js",
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^6.0.0",
|
||||
"babel-preset-es2015": "6.6.0",
|
||||
"eslint-config-airbnb": "3.1.0",
|
||||
"babel-eslint": "^6.1.2",
|
||||
"babel-preset-es2015": "^6.9.0",
|
||||
"babelify": "^7.3.0",
|
||||
"browserify": "^13.0.1",
|
||||
"eslint": "^3.1.1",
|
||||
"eslint-config-airbnb": "^9.0.1",
|
||||
"eslint-plugin-import": "^1.11.1",
|
||||
"eslint-plugin-jsx-a11y": "^2.0.1",
|
||||
"eslint-plugin-react": "^5.2.2",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-autoprefixer": "^3.1.0",
|
||||
"gulp-babel": "6.1.2",
|
||||
"gulp-change": "^1.0.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-eslint": "1.1.1",
|
||||
"gulp-include": "^2.1.0",
|
||||
"gulp-inject": "^3.0.0",
|
||||
"gulp-eslint": "^3.0.1",
|
||||
"gulp-htmlmin": "latest",
|
||||
"gulp-include": "^2.3.0",
|
||||
"gulp-inject": "^4.1.0",
|
||||
"gulp-json-sort": "^1.0.0",
|
||||
"gulp-minify-css": "^1.2.2",
|
||||
"gulp-minify-html": "^1.0.4",
|
||||
"gulp-rename": "^1.2.2",
|
||||
"gulp-replace-task": "^0.11.0",
|
||||
"gulp-sass": "^2.2.0",
|
||||
"gulp-sass-lint": "^1.1.1",
|
||||
"gulp-sass": "^2.3.2",
|
||||
"gulp-sass-lint": "^1.2.0",
|
||||
"gulp-util": "latest",
|
||||
"gulp-wrapper": "1.0.0",
|
||||
"request": "latest",
|
||||
"streamqueue": "^1.1.1",
|
||||
"gulp-htmlmin": "latest"
|
||||
"vinyl-buffer": "^1.0.0",
|
||||
"vinyl-source-stream": "^1.1.0"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/* global on:false */
|
||||
|
||||
import { AbilityChecks } from './AbilityChecks';
|
||||
const abilityChecks = new AbilityChecks();
|
||||
import { Actions } from './Actions';
|
||||
const actions = new Actions();
|
||||
import { Attacks } from './Attacks';
|
||||
const attacks = new Attacks();
|
||||
import { Spells } from './Spells';
|
||||
const spells = new Spells();
|
||||
import { getSetItems, getIntValue, getFloatValue, getAbilityMod, addArithmeticOperator, showSign, firstThree } from './utilities';
|
||||
|
||||
export class Abilities {
|
||||
updateModifier(ability) {
|
||||
const collectionArray = [ability, `${ability}_bonus`, `${ability}_mod`, `${ability}_mod_with_sign`, `${ability}_check_mod`, `${ability}_check_mod_formula`, `${ability}_check_bonus`, 'global_ability_bonus', 'strength_mod', 'dexterity_mod', 'jack_of_all_trades_toggle', 'jack_of_all_trades', 'remarkable_athlete_toggle', 'remarkable_athlete', 'global_check_bonus'];
|
||||
if (ability === 'strength' || ability === 'dexterity') {
|
||||
collectionArray.push('finesse_mod');
|
||||
}
|
||||
if (ability === 'strength') {
|
||||
collectionArray.push('weight_multiplier');
|
||||
collectionArray.push('carrying_capacity');
|
||||
collectionArray.push('max_push_drag_lift');
|
||||
collectionArray.push('encumbered');
|
||||
collectionArray.push('heavily_encumbered');
|
||||
}
|
||||
|
||||
getSetItems('abilities.updateModifier', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const abilityScore = getIntValue(v[ability]);
|
||||
const abilityBonus = getIntValue(v[`${ability}_bonus`]);
|
||||
const globalAbilityBonus = v.global_ability_bonus;
|
||||
let abilityScoreCalc = abilityScore + abilityBonus;
|
||||
|
||||
if (!isNaN(globalAbilityBonus)) {
|
||||
abilityScoreCalc += getIntValue(globalAbilityBonus);
|
||||
}
|
||||
|
||||
const abilityCheckBonus = getIntValue(v[`${ability}_check_bonus`]);
|
||||
const abilityMod = getAbilityMod(abilityScoreCalc);
|
||||
|
||||
let abilityCheck = abilityMod;
|
||||
let abilityCheckFormula = '';
|
||||
|
||||
if (abilityMod !== 0) {
|
||||
abilityCheckFormula = `${abilityMod}[${firstThree(ability)} mod with bonus]`;
|
||||
}
|
||||
if ((ability === 'strength' || ability === 'dexterity' || ability === 'constitution') && v.remarkable_athlete_toggle === '@{remarkable_athlete}') {
|
||||
const remarkableAthlete = getIntValue(v.remarkable_athlete);
|
||||
abilityCheck += remarkableAthlete;
|
||||
abilityCheckFormula += `${addArithmeticOperator(abilityCheckFormula, remarkableAthlete)}[remarkable athlete]`;
|
||||
} else if (v.jack_of_all_trades_toggle === '@{jack_of_all_trades}') {
|
||||
const jackOfAllTrades = getIntValue(v.jack_of_all_trades);
|
||||
abilityCheck += jackOfAllTrades;
|
||||
abilityCheckFormula += `${addArithmeticOperator(abilityCheckFormula, jackOfAllTrades)}[jack of all trades]`;
|
||||
}
|
||||
if (abilityCheckBonus) {
|
||||
abilityCheck += abilityCheckBonus;
|
||||
abilityCheckFormula += `${addArithmeticOperator(abilityCheckFormula, abilityCheckBonus)}[${ability} check bonus]`;
|
||||
}
|
||||
if (v.global_check_bonus) {
|
||||
if (!isNaN(v.global_check_bonus)) {
|
||||
abilityCheck += getIntValue(v.global_check_bonus);
|
||||
}
|
||||
if (abilityCheckFormula) {
|
||||
abilityCheckFormula += ' + ';
|
||||
}
|
||||
abilityCheckFormula += '(@{global_check_bonus})[global check bonus]';
|
||||
}
|
||||
|
||||
finalSetAttrs[`${ability}_calculated`] = abilityScoreCalc;
|
||||
finalSetAttrs[`${ability}_mod`] = abilityMod;
|
||||
finalSetAttrs[`${ability}_mod_with_sign`] = showSign(abilityMod);
|
||||
finalSetAttrs[`${ability}_check_mod`] = abilityCheck;
|
||||
finalSetAttrs[`${ability}_check_mod_with_sign`] = showSign(abilityCheck);
|
||||
finalSetAttrs[`${ability}_check_mod_formula`] = abilityCheckFormula;
|
||||
|
||||
if (ability === 'strength') {
|
||||
finalSetAttrs.finesse_mod = Math.max(abilityMod, getIntValue(v.dexterity_mod));
|
||||
const weightMultiplier = getFloatValue(v.weight_multiplier, 1);
|
||||
finalSetAttrs.carrying_capacity = abilityScore * 15 * weightMultiplier;
|
||||
finalSetAttrs.max_push_drag_lift = abilityScore * 30 * weightMultiplier;
|
||||
finalSetAttrs.encumbered = abilityScore * 5 * weightMultiplier;
|
||||
finalSetAttrs.heavily_encumbered = abilityScore * 10 * weightMultiplier;
|
||||
} else if (ability === 'dexterity') {
|
||||
finalSetAttrs.finesse_mod = Math.max(abilityMod, getIntValue(v.strength_mod));
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateModifiers() {
|
||||
this.updateModifier('strength');
|
||||
this.updateModifier('dexterity');
|
||||
this.updateModifier('constitution');
|
||||
this.updateModifier('intelligence');
|
||||
this.updateModifier('wisdom');
|
||||
this.updateModifier('charisma');
|
||||
}
|
||||
setup() {
|
||||
on('change:jack_of_all_trades_toggle change:jack_of_all_trades change:global_ability_bonus change:global_check_bonus', () => {
|
||||
this.updateModifiers();
|
||||
});
|
||||
on('change:strength change:strength_bonus change:strength_check_mod change:strength_check_bonus change:remarkable_athlete_toggle change:remarkable_athlete change:weight_multiplier', () => {
|
||||
this.updateModifier('strength');
|
||||
});
|
||||
on('change:dexterity change:dexterity_bonus change:dexterity_check_mod change:dexterity_check_bonus change:remarkable_athlete_toggle change:remarkable_athlete', () => {
|
||||
this.updateModifier('dexterity');
|
||||
});
|
||||
on('change:constitution change:constitution_bonus change:constitution_check_mod change:constitution_check_bonus change:remarkable_athlete_toggle change:remarkable_athlete', () => {
|
||||
this.updateModifier('constitution');
|
||||
});
|
||||
on('change:intelligence change:intelligence_bonus change:intelligence_check_mod change:intelligence_check_bonus', () => {
|
||||
this.updateModifier('intelligence');
|
||||
});
|
||||
on('change:wisdom change:wisdom_bonus change:wisdom_check_mod change:wisdom_check_bonus', () => {
|
||||
this.updateModifier('wisdom');
|
||||
});
|
||||
on('change:charisma change:charisma_bonus change:charisma_check_mod change:charisma_check_bonus', () => {
|
||||
this.updateModifier('charisma');
|
||||
});
|
||||
on('change:strength_mod change:dexterity_mod change:constitution_mod change:intelligence_mod change:wisdom_mod change:charisma_mod', () => {
|
||||
abilityChecks.updateSkill();
|
||||
attacks.update();
|
||||
spells.update();
|
||||
actions.updateAll();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,305 @@
|
||||
/* global on:false, generateRowID:false, getTranslationByKey:false */
|
||||
|
||||
import { getSetItems, getSetRepeatingItems, isUndefinedOrEmpty, getAbilityValue, getAbilityShortName, getIntValue, addArithmeticOperator, showSign, capitalize, exists, getRepeatingInfo, isUndefined } from './utilities';
|
||||
import { ABILITIES } from './constants';
|
||||
import { ProficiencyBonus } from './ProficiencyBonus';
|
||||
const proficiencyBonus = new ProficiencyBonus();
|
||||
|
||||
export class AbilityChecks {
|
||||
updateMacro() {
|
||||
const collectionArray = ['ability_checks_query_var', 'ability_checks_macro_var', 'ability_checks_show_totals'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_check_mod`);
|
||||
collectionArray.push(`${ability}_check_mod_with_sign`);
|
||||
}
|
||||
|
||||
getSetRepeatingItems('abilityChecks.updateMacro', {
|
||||
repeatingItems: ['repeating_skill'],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['name', 'ability', 'total_with_sign'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
finalSetAttrs.ability_checks_query_var = '?{Ability Check';
|
||||
finalSetAttrs.ability_checks_macro_var = '';
|
||||
finalSetAttrs.skills_macro_var = '';
|
||||
|
||||
|
||||
for (const ability of ABILITIES) {
|
||||
finalSetAttrs.ability_checks_query_var += `|${capitalize(ability)},{{title=${capitalize(ability)}}} {{roll1=[[@{shaped_d20} + ${v[`${ability}_check_mod`]}]]}} @{roll_setting} + ${v[`${ability}_check_mod`]}]]}}`;
|
||||
if (v.ability_checks_show_totals === 'on') {
|
||||
finalSetAttrs.ability_checks_macro_var += `[${capitalize(ability)} ${v[`${ability}_check_mod_with_sign`]}](~shaped_${ability}_check)`;
|
||||
} else {
|
||||
finalSetAttrs.ability_checks_macro_var += `[${capitalize(ability)}](~shaped_${ability}_check)`;
|
||||
}
|
||||
finalSetAttrs.ability_checks_macro_var += ', ';
|
||||
}
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
finalSetAttrs.ability_checks_query_var += `|${v[`${repeatingString}name`]}, {{title=${v[`${repeatingString}name`]} (${capitalize(getAbilityShortName(v[`${repeatingString}ability`]))})}} {{roll1=[[@{shaped_d20} + @{${repeatingString}formula}]]}} @{roll_setting} + @{${repeatingString}formula}]]}}`;
|
||||
if (id !== ids[0]) {
|
||||
finalSetAttrs.ability_checks_macro_var += ', ';
|
||||
finalSetAttrs.skills_macro_var += ', ';
|
||||
}
|
||||
let skillButton;
|
||||
if (v.ability_checks_show_totals === 'on') {
|
||||
skillButton = `[${v[`${repeatingString}name`]} ${v[`${repeatingString}total_with_sign`]}](~repeating_skill_${id}_skill)`;
|
||||
} else {
|
||||
skillButton = `[${v[`${repeatingString}name`]}](~repeating_skill_${id}_skill)`;
|
||||
}
|
||||
finalSetAttrs.ability_checks_macro_var += skillButton;
|
||||
finalSetAttrs.skills_macro_var += skillButton;
|
||||
}
|
||||
finalSetAttrs.ability_checks_query_var += '}';
|
||||
},
|
||||
});
|
||||
}
|
||||
updateSkill(rowId) {
|
||||
const collectionArray = ['jack_of_all_trades_toggle', 'jack_of_all_trades', 'remarkable_athlete_toggle', 'remarkable_athlete', 'pb', 'exp', 'global_check_bonus'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
collectionArray.push(`${ability}_check_bonus`);
|
||||
}
|
||||
|
||||
getSetRepeatingItems('abilityChecks.updateSkill', {
|
||||
repeatingItems: ['repeating_skill'],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['skill_d20', 'skill_info', 'proficiency', 'name', 'storage_name', 'ability', 'bonus', 'ability_key', 'formula', 'total', 'total_with_sign', 'passive_bonus', 'passive_total'],
|
||||
rowId,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
const skillName = v[`${repeatingString}name`];
|
||||
if (isUndefinedOrEmpty(skillName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
finalSetAttrs[`${repeatingString}ability_key`] = getAbilityShortName(v[`${repeatingString}ability`]).toUpperCase();
|
||||
|
||||
let total = 0;
|
||||
let totalFormula = '';
|
||||
const proficiency = v[`${repeatingString}proficiency`];
|
||||
if (!proficiency || proficiency === 'unproficient') {
|
||||
if ((v[`${repeatingString}ability`] === 'strength' || v[`${repeatingString}ability`] === 'dexterity' || v[`${repeatingString}ability`] === 'constitution') && v.remarkable_athlete_toggle === '@{remarkable_athlete}') {
|
||||
const remarkableAthlete = getIntValue(v.remarkable_athlete);
|
||||
total += remarkableAthlete;
|
||||
totalFormula += `${remarkableAthlete}[remarkable athlete]`;
|
||||
} else if (v.jack_of_all_trades_toggle === '@{jack_of_all_trades}') {
|
||||
const jackOfAllTrades = getIntValue(v.jack_of_all_trades);
|
||||
total += jackOfAllTrades;
|
||||
totalFormula += `${jackOfAllTrades}[jack of all trades]`;
|
||||
}
|
||||
} else if (proficiency === 'proficient') {
|
||||
const pb = getIntValue(v.pb);
|
||||
total += pb;
|
||||
totalFormula += `${pb}[proficient]`;
|
||||
} else if (proficiency === 'expertise') {
|
||||
const exp = getIntValue(v.exp);
|
||||
total += exp;
|
||||
totalFormula += `${exp}[expertise]`;
|
||||
}
|
||||
|
||||
const abilityValue = getAbilityValue(v, v[`${repeatingString}ability`], 'strength');
|
||||
if (exists(abilityValue)) {
|
||||
total += abilityValue;
|
||||
totalFormula += `${addArithmeticOperator(totalFormula, abilityValue)}[${getAbilityShortName(v[`${repeatingString}ability`])}]`;
|
||||
}
|
||||
|
||||
const skillBonus = getIntValue(v[`${repeatingString}bonus`]);
|
||||
if (exists(skillBonus)) {
|
||||
total += skillBonus;
|
||||
totalFormula += `${addArithmeticOperator(totalFormula, skillBonus)}[bonus]`;
|
||||
}
|
||||
|
||||
if (exists(v[`${repeatingString}ability`])) {
|
||||
let checkBonus = v[`${v[`${repeatingString}ability`]}_check_bonus`];
|
||||
if (exists(checkBonus)) {
|
||||
checkBonus = getIntValue(checkBonus);
|
||||
total += checkBonus;
|
||||
totalFormula += `${addArithmeticOperator(totalFormula, checkBonus)}[${getAbilityShortName(v[`${repeatingString}ability`])} check bonus]`;
|
||||
}
|
||||
}
|
||||
|
||||
const globalCheckBonus = v.global_check_bonus;
|
||||
if (exists(globalCheckBonus)) {
|
||||
if (!isNaN(globalCheckBonus)) {
|
||||
total += getIntValue(globalCheckBonus);
|
||||
}
|
||||
if (totalFormula) {
|
||||
totalFormula += ' + ';
|
||||
}
|
||||
totalFormula += '(@{global_check_bonus})[global check bonus]';
|
||||
}
|
||||
const passiveBonus = getIntValue(v[`${repeatingString}passive_bonus`]);
|
||||
let advantageOrDisadvantage = 0;
|
||||
|
||||
finalSetAttrs[`${repeatingString}skill_info`] = '';
|
||||
|
||||
if (v[`${repeatingString}skill_d20`] && v[`${repeatingString}skill_d20`].indexOf('kh1') !== -1) {
|
||||
finalSetAttrs[`${repeatingString}skill_info`] = '{{advantage=1}}';
|
||||
advantageOrDisadvantage = 5;
|
||||
} else if (v[`${repeatingString}skill_d20`] && v[`${repeatingString}skill_d20`].indexOf('kl1') !== -1) {
|
||||
finalSetAttrs[`${repeatingString}skill_info`] = '{{disadvantage=1}}';
|
||||
advantageOrDisadvantage = -5;
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}skill_info`] = '';
|
||||
}
|
||||
|
||||
const passiveTotal = 10 + total + passiveBonus + advantageOrDisadvantage;
|
||||
|
||||
finalSetAttrs[`${repeatingString}total`] = total;
|
||||
finalSetAttrs[`${repeatingString}passive`] = passiveTotal;
|
||||
finalSetAttrs[`${repeatingString}total_with_sign`] = showSign(total);
|
||||
finalSetAttrs[`${repeatingString}formula`] = totalFormula;
|
||||
}
|
||||
},
|
||||
setFinalAttrsCallback: () => {
|
||||
this.updateMacro();
|
||||
},
|
||||
});
|
||||
}
|
||||
updateSkillsFromSRD() {
|
||||
getSetRepeatingItems('abilityChecks.updateSkillsFromSRD', {
|
||||
repeatingItems: ['repeating_skill'],
|
||||
collectionArray: ['skills_srd', 'level', 'challenge', 'strength_mod', 'dexterity_mod', 'constitution_mod', 'intelligence_mod', 'wisdom_mod', 'charisma_mod', 'expertise_as_advantage'],
|
||||
collectionArrayAddItems: ['name', 'ability'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
const skillsFromSRD = v.skills_srd;
|
||||
const skillsObj = {};
|
||||
const pb = proficiencyBonus.get(v.level, v.challenge);
|
||||
const expertise = pb * 2;
|
||||
let skillName;
|
||||
let repeatingString;
|
||||
|
||||
if (!isUndefinedOrEmpty(skillsFromSRD)) {
|
||||
for (const id of ids) {
|
||||
repeatingString = `${repeatingItem}_${id}_`;
|
||||
skillName = v[`${repeatingString}name`];
|
||||
skillsObj[skillName] = id;
|
||||
}
|
||||
|
||||
const re = /(\w+)\s?((?:\+|\-)\d+)/gi;
|
||||
let match;
|
||||
while ((match = re.exec(skillsFromSRD)) !== null) {
|
||||
if (match && match[1] && match[2]) {
|
||||
skillName = match[1];
|
||||
if (skillsObj[skillName]) {
|
||||
const skillId = skillsObj[skillName];
|
||||
repeatingString = `${repeatingItem}_${skillId}_`;
|
||||
|
||||
const skillAbility = v[`${repeatingString}ability`];
|
||||
const abilityValue = getAbilityValue(v, skillAbility);
|
||||
const skillBonus = getIntValue(match[2]) - abilityValue;
|
||||
|
||||
if (skillBonus >= expertise) {
|
||||
if (v.expertise_as_advantage === '1') {
|
||||
finalSetAttrs[`${repeatingString}skill_d20`] = '2d20@{d20_mod}kh1';
|
||||
finalSetAttrs[`${repeatingString}proficiency`] = 'proficient';
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}proficiency`] = 'expertise';
|
||||
}
|
||||
if (skillBonus > expertise) {
|
||||
finalSetAttrs[`${repeatingString}bonus`] = skillBonus - expertise;
|
||||
}
|
||||
} else if (skillBonus >= pb) {
|
||||
finalSetAttrs[`${repeatingString}proficiency`] = 'proficient';
|
||||
if (skillBonus > pb) {
|
||||
finalSetAttrs[`${repeatingString}bonus`] = skillBonus - pb;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.warn(`${skillName} does not exist in the list of skills`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateInitiative() {
|
||||
const collectionArray = ['initiative', 'initiative_ability', 'initiative_formula', 'initiative_bonus', 'jack_of_all_trades_toggle', 'jack_of_all_trades', 'remarkable_athlete_toggle', 'remarkable_athlete', 'global_check_bonus'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
collectionArray.push(`${ability}_check_bonus`);
|
||||
}
|
||||
|
||||
getSetItems('abilityChecks.updateInitiative', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.initiative = 0;
|
||||
|
||||
let initiativeAbility = v.initiative_ability;
|
||||
|
||||
if (isUndefined(initiativeAbility)) {
|
||||
initiativeAbility = 'dexterity';
|
||||
}
|
||||
|
||||
const abilityMod = getAbilityValue(v, initiativeAbility);
|
||||
if (exists(abilityMod)) {
|
||||
finalSetAttrs.initiative += abilityMod;
|
||||
}
|
||||
finalSetAttrs.initiative_formula = `${abilityMod}[${getAbilityShortName(initiativeAbility)}]`;
|
||||
|
||||
const abilityCheckBonus = getIntValue(v[`${initiativeAbility}_check_bonus`]);
|
||||
if (exists(abilityCheckBonus)) {
|
||||
finalSetAttrs.initiative += abilityCheckBonus;
|
||||
finalSetAttrs.initiative_formula += `${addArithmeticOperator(finalSetAttrs.initiative_formula, abilityCheckBonus)}[${getAbilityShortName(initiativeAbility)} check bonus]`;
|
||||
}
|
||||
|
||||
const initiativeBonus = v.initiative_bonus;
|
||||
if (exists(initiativeBonus)) {
|
||||
if (!isNaN(initiativeBonus)) {
|
||||
finalSetAttrs.initiative += getIntValue(initiativeBonus);
|
||||
}
|
||||
finalSetAttrs.initiative_formula += `${addArithmeticOperator(finalSetAttrs.initiative_formula, initiativeBonus)}[initiative bonus]`;
|
||||
}
|
||||
|
||||
if (v.remarkable_athlete_toggle === '@{remarkable_athlete}') {
|
||||
const remarkableAthlete = getIntValue(v.remarkable_athlete);
|
||||
if (exists(remarkableAthlete)) {
|
||||
finalSetAttrs.initiative += remarkableAthlete;
|
||||
finalSetAttrs.initiative_formula += `${addArithmeticOperator(finalSetAttrs.initiative_formula, remarkableAthlete)}[remarkable athlete]`;
|
||||
}
|
||||
} else if (v.jack_of_all_trades_toggle === '@{jack_of_all_trades}') {
|
||||
const jackOfAllTrades = getIntValue(v.jack_of_all_trades);
|
||||
if (exists(jackOfAllTrades)) {
|
||||
finalSetAttrs.initiative += jackOfAllTrades;
|
||||
finalSetAttrs.initiative_formula += `${addArithmeticOperator(finalSetAttrs.initiative_formula, jackOfAllTrades)}[jack of all trades]`;
|
||||
}
|
||||
}
|
||||
|
||||
const globalCheckBonus = v.global_check_bonus;
|
||||
if (exists(globalCheckBonus)) {
|
||||
if (finalSetAttrs.initiative_formula) {
|
||||
finalSetAttrs.initiative_formula += ' + ';
|
||||
}
|
||||
finalSetAttrs.initiative_formula += '(@{global_check_bonus})[global check bonus]';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:repeating_skill', (eventInfo) => {
|
||||
const repeatingInfo = getRepeatingInfo('repeating_skill', eventInfo);
|
||||
if (repeatingInfo && repeatingInfo.field !== 'ability_key' && repeatingInfo.field !== 'total' && repeatingInfo.field !== 'total_with_sign' && repeatingInfo.field !== 'passive_total' && repeatingInfo.field !== 'passive_total_with_sign' && repeatingInfo.field !== 'formula') {
|
||||
this.updateSkill(repeatingInfo.rowId);
|
||||
}
|
||||
});
|
||||
on('change:pb change:jack_of_all_trades_toggle change:jack_of_all_trades change:remarkable_athlete_toggle change:remarkable_athlete change:global_check_bonus change:strength_check_bonus change:dexterity_check_bonus change:constitution_check_bonus change:intelligence_check_bonus change:wisdom_check_bonus change:charisma_check_bonus', () => {
|
||||
this.updateSkill();
|
||||
});
|
||||
on('change:skills_srd', () => {
|
||||
this.updateSkillsFromSRD();
|
||||
});
|
||||
on('remove:repeating_skill change:ability_checks_show_totals', () => {
|
||||
this.updateMacro();
|
||||
});
|
||||
const initiativeWatch = ['change:initiative_ability', 'change:initiative_bonus', 'change:jack_of_all_trades_toggle', 'change:jack_of_all_trades', 'change:remarkable_athlete_toggle', 'change:remarkable_athlete', 'change:global_check_bonus'];
|
||||
for (const ability of ABILITIES) {
|
||||
initiativeWatch.push(`change:${ability}_mod`);
|
||||
initiativeWatch.push(`change:${ability}_check_bonus`);
|
||||
}
|
||||
on(initiativeWatch.join(' '), () => {
|
||||
this.updateInitiative();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,495 @@
|
||||
/* global on:false */
|
||||
|
||||
import { ABILITIES, TOGGLE_VARS } from './constants';
|
||||
import { ProficiencyBonus } from './ProficiencyBonus';
|
||||
const proficiencyBonus = new ProficiencyBonus();
|
||||
import { getSetRepeatingItems, isUndefined, isUndefinedOrEmpty, fromVOrFinalSetAttrs, setCritDamage, getIntValue, getRepeatingInfo, lowercaseDamageTypes, exists } from './utilities';
|
||||
import { updateAttackToggle, updateSavingThrowToggle, updateDamageToggle, updateHealToggle } from './updateToggles';
|
||||
|
||||
export class Actions {
|
||||
updateAll() {
|
||||
this.update('trait');
|
||||
this.update('action');
|
||||
this.update('reaction');
|
||||
this.update('legendaryaction');
|
||||
this.update('lairaction');
|
||||
this.update('regionaleffect');
|
||||
}
|
||||
update(type, rowId) {
|
||||
const rechargeRegex = /\s*?\((?:Recharge\s*?(\d+\-\d+|\d+)|Recharges\safter\sa\s(.*))\)/gi;
|
||||
const rechargeDayRegex = /\s*?\((\d+\/Day)\)/gi;
|
||||
const collectionArray = ['pb', 'strength_mod', 'finesse_mod', 'global_attack_bonus', 'global_melee_attack_bonus', 'global_ranged_attack_bonus', 'global_damage_bonus', 'global_melee_damage_bonus', 'global_ranged_damage_bonus', 'default_ability', 'base_dc'];
|
||||
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
}
|
||||
|
||||
getSetRepeatingItems('actions.update', {
|
||||
repeatingItems: [`repeating_${type}`],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['name', 'type', 'uses', 'uses_max', 'has_uses', 'roll_toggle', 'to_hit', 'attack_formula', 'proficiency', 'attack_ability', 'attack_bonus', 'saving_throw_toggle', 'saving_throw_ability', 'saving_throw_bonus', 'saving_throw_dc', 'damage_toggle', 'damage_formula', 'damage', 'damage_ability', 'damage_bonus', 'damage_type', 'damage_crit', 'second_damage_toggle', 'second_damage_formula', 'second_damage', 'second_damage_ability', 'second_damage_bonus', 'second_damage_type', 'second_damage_crit', 'damage_string', 'heal_toggle', 'heal', 'heal_ability', 'heal_bonus', 'heal_query_toggle', 'parsed', 'recharge', 'recharge_display', 'extras_toggle', 'emote', 'freetext', 'freeform'],
|
||||
rowId,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
const actionName = v[`${repeatingString}name`];
|
||||
if (!isUndefinedOrEmpty(actionName)) {
|
||||
const rechargeResult = rechargeRegex.exec(actionName);
|
||||
if (rechargeResult) {
|
||||
finalSetAttrs[`${repeatingString}recharge`] = rechargeResult[1] || rechargeResult[2];
|
||||
finalSetAttrs[`${repeatingString}name`] = actionName.replace(rechargeRegex, '');
|
||||
}
|
||||
const rechargeDayResult = rechargeDayRegex.exec(actionName);
|
||||
if (rechargeDayResult) {
|
||||
finalSetAttrs[`${repeatingString}recharge`] = rechargeDayResult[1] || rechargeDayResult[2];
|
||||
finalSetAttrs[`${repeatingString}name`] = actionName.replace(rechargeDayRegex, '');
|
||||
}
|
||||
}
|
||||
|
||||
if (v[`${repeatingString}uses`] || v[`${repeatingString}uses_max`]) {
|
||||
finalSetAttrs[`${repeatingString}has_uses`] = 1;
|
||||
} else if (!isUndefinedOrEmpty(v[`${repeatingString}has_uses`])) {
|
||||
finalSetAttrs[`${repeatingString}has_uses`] = 0;
|
||||
}
|
||||
|
||||
const recharge = fromVOrFinalSetAttrs(v, finalSetAttrs, `${repeatingString}recharge`);
|
||||
if (exists(recharge)) {
|
||||
if (isNaN(recharge)) {
|
||||
finalSetAttrs[`${repeatingString}recharge_display`] = ` (${recharge})`;
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}recharge_display`] = ` (Recharge ${recharge})`;
|
||||
}
|
||||
} else if (exists(v[`${repeatingString}recharge_display`])) {
|
||||
finalSetAttrs[`${repeatingString}recharge_display`] = '';
|
||||
}
|
||||
|
||||
let attackOptions = {};
|
||||
if (type !== 'trait') {
|
||||
attackOptions = {
|
||||
globalAttackBonus: v.global_attack_bonus,
|
||||
globalAttackBonusLabel: 'global attack bonus',
|
||||
globalMeleeAttackBonus: v.global_melee_attack_bonus,
|
||||
globalRangedAttackBonus: v.global_ranged_attack_bonus,
|
||||
type: 'attack',
|
||||
};
|
||||
}
|
||||
updateAttackToggle(v, finalSetAttrs, repeatingString, attackOptions);
|
||||
|
||||
updateSavingThrowToggle(v, finalSetAttrs, repeatingString);
|
||||
|
||||
let damageOptions = {};
|
||||
if (type !== 'trait') {
|
||||
damageOptions = {
|
||||
globalDamageBonus: v.global_damage_bonus,
|
||||
globalMeleeDamageBonus: v.global_melee_damage_bonus,
|
||||
globalRangedDamageBonus: v.global_ranged_damage_bonus,
|
||||
type: 'attack',
|
||||
};
|
||||
}
|
||||
updateDamageToggle(v, finalSetAttrs, repeatingString, damageOptions);
|
||||
if (v.damage_type) {
|
||||
finalSetAttrs.damage_type = lowercaseDamageTypes(v.damage_type);
|
||||
}
|
||||
if (v.second_damage_type) {
|
||||
finalSetAttrs.second_damage_type = lowercaseDamageTypes(v.second_damage_type);
|
||||
}
|
||||
setCritDamage(v, finalSetAttrs, repeatingString);
|
||||
|
||||
updateHealToggle(v, finalSetAttrs, repeatingString);
|
||||
|
||||
if (isUndefined(v[`${repeatingString}extras_toggle`]) && (v[`${repeatingString}emote`] || v[`${repeatingString}freetext`] || v[`${repeatingString}freeform`])) {
|
||||
finalSetAttrs[`${repeatingString}extras_toggle`] = TOGGLE_VARS.extras;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateIfTriggered(type, eventInfo) {
|
||||
const repeatingInfo = getRepeatingInfo(`repeating_${type}`, eventInfo);
|
||||
if (repeatingInfo && repeatingInfo.field !== 'name' && repeatingInfo.field !== 'freetext' && repeatingInfo.field !== 'to_hit' && repeatingInfo.field !== 'attack_formula' && repeatingInfo.field !== 'damage_formula' && repeatingInfo.field !== 'damage_crit' && repeatingInfo.field !== 'second_damage_formula' && repeatingInfo.field !== 'second_damage_crit' && repeatingInfo.field !== 'damage_string' && repeatingInfo.field !== 'saving_throw_dc' && repeatingInfo.field !== 'parsed' && repeatingInfo.field !== 'recharge_display') {
|
||||
this.update(type, repeatingInfo.rowId);
|
||||
}
|
||||
}
|
||||
updateChatMacro(type) {
|
||||
getSetRepeatingItems('actions.updateChatMacro', {
|
||||
repeatingItems: [`repeating_${type}`],
|
||||
collectionArray: [`${type}s_macro_var`, `${type}s_chat_var`, `${type}s_exist`],
|
||||
collectionArrayAddItems: ['name', 'freetext'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
finalSetAttrs[`${type}s_macro_var`] = '';
|
||||
finalSetAttrs[`${type}s_chat_var`] = '';
|
||||
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
let actionName = v[`${repeatingString}name`];
|
||||
const freeText = v[`${repeatingString}freetext`];
|
||||
|
||||
if (id !== ids[0]) {
|
||||
finalSetAttrs[`${type}s_macro_var`] += ', ';
|
||||
}
|
||||
let actionType = 'action';
|
||||
let title;
|
||||
if (type === 'trait') {
|
||||
title = 'Traits';
|
||||
actionType = 'trait';
|
||||
} else if (type === 'action') {
|
||||
title = 'Actions';
|
||||
} else if (type === 'reaction') {
|
||||
title = 'Reactions';
|
||||
} else if (type === 'legendaryaction') {
|
||||
title = 'Legendary Actions';
|
||||
} else if (type === 'lairaction') {
|
||||
title = 'Lair Actions';
|
||||
actionName = freeText;
|
||||
} else if (type === 'regionaleffect') {
|
||||
title = 'Regional Effects';
|
||||
actionName = freeText;
|
||||
}
|
||||
|
||||
if (actionName && actionName.length > 50) {
|
||||
actionName = `${actionName.substring(0, 50)}...`;
|
||||
}
|
||||
|
||||
finalSetAttrs[`${type}s_macro_var`] += `[${actionName}](~repeating_${type}_${id}_${actionType})`;
|
||||
finalSetAttrs[`${type}s_chat_var`] += `{{${title}=${finalSetAttrs[`${type}s_macro_var`]}}}`;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
findClosest(array, goal) {
|
||||
return array.reduce((prev, curr) => {
|
||||
return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev);
|
||||
});
|
||||
}
|
||||
getCorrectAbilityBasedOnBonus(finalSetAttrs, repeatingString, fieldName, bonus, spellMods, meleeMods, spellAttack, rangedAttack, dexMod) {
|
||||
let closest;
|
||||
if (bonus) {
|
||||
if (spellAttack) {
|
||||
closest = this.findClosest(spellMods, bonus);
|
||||
bonus -= closest;
|
||||
if (closest === spellMods[0]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'intelligence';
|
||||
} else if (closest === spellMods[1]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'wisdom';
|
||||
} else if (closest === spellMods[2]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'charisma';
|
||||
}
|
||||
} else {
|
||||
if (rangedAttack) {
|
||||
finalSetAttrs[`${repeatingString}attack_ability`] = 'dexterity';
|
||||
bonus -= dexMod;
|
||||
} else {
|
||||
closest = this.findClosest(meleeMods, bonus);
|
||||
bonus -= closest;
|
||||
if (closest === meleeMods[0]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'strength';
|
||||
} else if (closest === meleeMods[1]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'dexterity';
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
finalSetAttrs[repeatingString + fieldName] = 0;
|
||||
}
|
||||
return bonus;
|
||||
}
|
||||
getAnyCorrectAbilityBasedOnBonus(finalSetAttrs, repeatingString, fieldName, bonus, abilityMods) {
|
||||
const closest = this.findClosest(abilityMods, bonus);
|
||||
if (bonus) {
|
||||
bonus -= closest;
|
||||
|
||||
if (closest === abilityMods[0]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'strength';
|
||||
} else if (closest === abilityMods[1]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'dexterity';
|
||||
} else if (closest === abilityMods[2]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'constitution';
|
||||
} else if (closest === abilityMods[3]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'intelligence';
|
||||
} else if (closest === abilityMods[4]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'wisdom';
|
||||
} else if (closest === abilityMods[5]) {
|
||||
finalSetAttrs[repeatingString + fieldName] = 'charisma';
|
||||
}
|
||||
} else {
|
||||
finalSetAttrs[repeatingString + fieldName] = 0;
|
||||
}
|
||||
return bonus;
|
||||
}
|
||||
parseDamage(finalSetAttrs, repeatingString, freetext, regex, name, spellMods, meleeMods, spellAttack, rangedAttack, dexMod) {
|
||||
const damageParseRegex = /(\d+d?\d+)(?:\s?(?:\+|\-)\s?(\d+))?/gi;
|
||||
const damage = regex.exec(freetext);
|
||||
let damageBonus;
|
||||
if (damage) {
|
||||
/*
|
||||
1 is damage with dice. Example '2d6+4'
|
||||
2 is damage type. Example 'slashing' or 'lightning or thunder'
|
||||
*/
|
||||
if (damage[1]) {
|
||||
const damageParsed = damageParseRegex.exec(damage[1]);
|
||||
if (damageParsed) {
|
||||
if (damageParsed[1]) {
|
||||
finalSetAttrs[repeatingString + name] = damageParsed[1];
|
||||
}
|
||||
if (damageParsed[2]) {
|
||||
damageBonus = damageParsed[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
damageBonus = this.getCorrectAbilityBasedOnBonus(finalSetAttrs, repeatingString, `${name}_ability`, damageBonus, spellMods, meleeMods, spellAttack, rangedAttack, dexMod);
|
||||
if (damage[2]) {
|
||||
finalSetAttrs[`${repeatingString}${name}_type`] = damage[2];
|
||||
}
|
||||
if (damageBonus) {
|
||||
finalSetAttrs[`${repeatingString}${name}_bonus`] = damageBonus;
|
||||
}
|
||||
freetext = freetext.replace(regex, '');
|
||||
finalSetAttrs[`${repeatingString}${name}_toggle`] = TOGGLE_VARS[name];
|
||||
}
|
||||
return freetext;
|
||||
}
|
||||
parse(type, rowId) {
|
||||
const collectionArray = ['level', 'challenge', 'global_attack_bonus', 'global_melee_attack_bonus', 'global_ranged_attack_bonus', 'global_damage_bonus', 'global_melee_damage_bonus', 'global_ranged_damage_bonus', 'default_ability'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
}
|
||||
const damageSyntax = /(?:(\d+d?\d+(?:\s\+\s\d+)?)(?:\))?)\s*?/;
|
||||
const damageType = /((?:[a-zA-Z]+|[a-zA-Z]+\s(?:or|and)\s[a-zA-Z]+)(?:\s*?\([a-zA-Z\s]+\))?)\s*damage\s?(\([a-zA-Z'\s]+\))?/;
|
||||
const altDamageSyntax = /(?:,\s*?or\s*?)/;
|
||||
const plus = /\s*?plus\s*?/;
|
||||
const savingThrowRe = /(?:DC)\s*?(\d+)\s*?([a-zA-Z]*)\s*?(?:saving throw)/;
|
||||
const saveSuccess = /or\s(.*)?\son a successful one./;
|
||||
const damageRegex = new RegExp(damageSyntax.source + damageType.source, 'i');
|
||||
const damagePlusRegex = new RegExp(plus.source + damageSyntax.source + damageType.source, 'i');
|
||||
const altDamageRegex = new RegExp(altDamageSyntax.source + damageSyntax.source + damageType.source, 'i');
|
||||
const savingThrowRegex = new RegExp(savingThrowRe.source, 'i');
|
||||
const saveSuccessRegex = new RegExp(saveSuccess.source, 'i');
|
||||
|
||||
const typeRegex = /(melee|ranged|melee or ranged)\s*(spell|weapon)\s*attack/gi;
|
||||
const toHitRegex = /:\s?\+\s?(\d+)\s*(?:to hit)/gi;
|
||||
const reachRegex = /(?:reach)\s?(\d+)\s?(?:ft)/gi;
|
||||
const rangeRegex = /(?:range)\s?(\d+)\/(\d+)\s?(ft)/gi;
|
||||
const spellcastingRegex = /(\d+)\w+\slevel\s\((\d+)\s?slot(?:s)?\)/gi;
|
||||
const spellcastingLevelRegex = /(\d+)(?:st|dn|rd|th)-level spellcaster/i;
|
||||
const spellcastingAbilityRegex = /spellcasting ability is (\w+)/i;
|
||||
|
||||
getSetRepeatingItems('actions.parse', {
|
||||
repeatingItems: [`repeating_${type}`],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['name', 'freetext', 'type'],
|
||||
rowId,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
const pb = proficiencyBonus.get(v.level, v.challenge);
|
||||
const strMod = getIntValue(v.strength_mod);
|
||||
const dexMod = getIntValue(v.dexterity_mod);
|
||||
const conMod = getIntValue(v.constitution_mod);
|
||||
const intMod = getIntValue(v.intelligence_mod);
|
||||
const wisMod = getIntValue(v.wisdom_mod);
|
||||
const chaMod = getIntValue(v.charisma_mod);
|
||||
const meleeMods = [strMod, dexMod];
|
||||
const spellMods = [intMod, wisMod, chaMod];
|
||||
const abilityMods = [strMod, dexMod, conMod, intMod, wisMod, chaMod];
|
||||
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
let rangedAttack = false;
|
||||
let spellAttack = false;
|
||||
|
||||
const name = v[`${repeatingString}name`];
|
||||
let freetext = v[`${repeatingString}freetext`];
|
||||
|
||||
if (name && name.indexOf('Spellcasting') !== -1) {
|
||||
const spellcastingSearch = spellcastingAbilityRegex.exec(freetext);
|
||||
if (spellcastingSearch && spellcastingSearch[1]) {
|
||||
const spellcastingAbility = spellcastingSearch[1].toLowerCase();
|
||||
finalSetAttrs.default_ability = `@{${spellcastingAbility}_mod}`;
|
||||
}
|
||||
const spellcastingLevelSearch = spellcastingLevelRegex.exec(freetext);
|
||||
if (spellcastingLevelSearch && spellcastingLevelSearch[1]) {
|
||||
finalSetAttrs.caster_level = spellcastingLevelSearch[1];
|
||||
}
|
||||
|
||||
let match;
|
||||
while ((match = spellcastingRegex.exec(freetext)) !== null) {
|
||||
if (match && match[1] && match[2]) {
|
||||
finalSetAttrs[`spell_slots_l${match[1]}_bonus`] = match[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const actionType = typeRegex.exec(freetext);
|
||||
if (actionType) {
|
||||
if (actionType[1]) {
|
||||
actionType[1] = actionType[1].toLowerCase();
|
||||
if (isUndefined(v[`${repeatingString}type`]) && actionType[1] === 'melee') {
|
||||
finalSetAttrs[`${repeatingString}type`] = 'Melee Weapon';
|
||||
} else if (isUndefined(v[`${repeatingString}type`]) && actionType[1] === 'ranged') {
|
||||
finalSetAttrs[`${repeatingString}type`] = 'Ranged Weapon';
|
||||
rangedAttack = true;
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}type`] = 'Other';
|
||||
}
|
||||
}
|
||||
if (actionType[2]) {
|
||||
actionType[2] = actionType[2].toLowerCase();
|
||||
if (actionType[2] === 'spell') {
|
||||
spellAttack = true;
|
||||
}
|
||||
}
|
||||
freetext = freetext.replace(typeRegex, '');
|
||||
}
|
||||
|
||||
const reach = reachRegex.exec(freetext);
|
||||
if (reach && reach[1]) {
|
||||
finalSetAttrs[`${repeatingString}reach`] = `${reach[1]}ft.`;
|
||||
freetext = freetext.replace(reachRegex, '');
|
||||
}
|
||||
const range = rangeRegex.exec(freetext);
|
||||
if (range && range[1] && range[2]) {
|
||||
finalSetAttrs[`${repeatingString}range`] = `${range[1]}ft.`;
|
||||
freetext = freetext.replace(rangeRegex, '');
|
||||
}
|
||||
|
||||
const toHit = toHitRegex.exec(freetext);
|
||||
if (toHit && toHit[1]) {
|
||||
let hitBonus = toHit[1];
|
||||
hitBonus -= pb;
|
||||
|
||||
hitBonus = this.getCorrectAbilityBasedOnBonus(finalSetAttrs, repeatingString, 'attack_ability', hitBonus, spellMods, meleeMods, spellAttack, rangedAttack, dexMod);
|
||||
|
||||
if (hitBonus) {
|
||||
finalSetAttrs[`${repeatingString}attack_bonus`] = hitBonus;
|
||||
}
|
||||
freetext = freetext.replace(toHitRegex, '');
|
||||
finalSetAttrs[`${repeatingString}roll_toggle`] = TOGGLE_VARS.roll;
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}roll_toggle`] = '0';
|
||||
}
|
||||
|
||||
const savingThrow = savingThrowRegex.exec(freetext);
|
||||
if (savingThrow) {
|
||||
if (savingThrow[1]) {
|
||||
let savingThrowTotal = savingThrow[1];
|
||||
savingThrowTotal -= 8;
|
||||
savingThrowTotal -= pb;
|
||||
|
||||
savingThrowTotal = this.getAnyCorrectAbilityBasedOnBonus(finalSetAttrs, repeatingString, 'saving_throw_ability', savingThrowTotal, abilityMods);
|
||||
|
||||
if (savingThrowTotal) {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_bonus`] = savingThrowTotal;
|
||||
}
|
||||
freetext = freetext.replace(savingThrowRegex, '');
|
||||
finalSetAttrs[`${repeatingString}saving_throw_toggle`] = TOGGLE_VARS.saving_throw;
|
||||
}
|
||||
if (savingThrow[2]) {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_vs_ability`] = savingThrow[2].toUpperCase();
|
||||
}
|
||||
const halfDamage = saveSuccessRegex.exec(freetext);
|
||||
if (halfDamage && halfDamage[1]) {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_success`] = halfDamage[1];
|
||||
freetext = freetext.replace(saveSuccessRegex, '');
|
||||
}
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_toggle`] = '0';
|
||||
}
|
||||
|
||||
freetext = this.parseDamage(finalSetAttrs, repeatingString, freetext, damageRegex, 'damage', spellMods, meleeMods, spellAttack, rangedAttack, dexMod);
|
||||
freetext = this.parseDamage(finalSetAttrs, repeatingString, freetext, altDamageRegex, 'second_damage', spellMods, meleeMods, spellAttack, rangedAttack, dexMod);
|
||||
freetext = this.parseDamage(finalSetAttrs, repeatingString, freetext, damagePlusRegex, 'second_damage', spellMods, meleeMods, spellAttack, rangedAttack, dexMod);
|
||||
if (!exists(finalSetAttrs[`${repeatingString}second_damage`])) {
|
||||
freetext = this.parseDamage(finalSetAttrs, repeatingString, freetext, damageRegex, 'second_damage', spellMods, meleeMods, spellAttack, rangedAttack, dexMod);
|
||||
}
|
||||
|
||||
finalSetAttrs[`${repeatingString}extras_toggle`] = TOGGLE_VARS.extras;
|
||||
finalSetAttrs[`${repeatingString}toggle_details`] = 0;
|
||||
}
|
||||
},
|
||||
setFinalAttrsCallback: () => {
|
||||
this.update(type, rowId);
|
||||
},
|
||||
});
|
||||
}
|
||||
count(type) {
|
||||
getSetRepeatingItems('actions.count', {
|
||||
repeatingItems: [`repeating_${type}`],
|
||||
collectionArray: [`${type}s_exist`],
|
||||
callback: (v, finalSetAttrs, ids) => {
|
||||
if (ids.length > 0) {
|
||||
finalSetAttrs[`${type}s_exist`] = 1;
|
||||
} else if (exists(v[`${type}s_exist`])) {
|
||||
finalSetAttrs[`${type}s_exist`] = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:pb', () => {
|
||||
this.update();
|
||||
});
|
||||
on('change:repeating_trait', (eventInfo) => {
|
||||
this.updateIfTriggered('trait', eventInfo);
|
||||
});
|
||||
on('change:repeating_action', (eventInfo) => {
|
||||
this.updateIfTriggered('action', eventInfo);
|
||||
});
|
||||
on('change:repeating_reaction', (eventInfo) => {
|
||||
this.updateIfTriggered('reaction', eventInfo);
|
||||
});
|
||||
on('change:repeating_legendaryaction', (eventInfo) => {
|
||||
this.updateIfTriggered('legendaryaction', eventInfo);
|
||||
});
|
||||
on('change:repeating_lairaction', (eventInfo) => {
|
||||
this.updateIfTriggered('lairaction', eventInfo);
|
||||
});
|
||||
on('change:repeating_regionaleffect', (eventInfo) => {
|
||||
this.updateIfTriggered('regionaleffect', eventInfo);
|
||||
});
|
||||
on('change:repeating_trait remove:repeating_trait', () => {
|
||||
this.count('trait');
|
||||
this.updateChatMacro('trait');
|
||||
});
|
||||
on('change:repeating_action remove:repeating_action', () => {
|
||||
this.count('action');
|
||||
this.updateChatMacro('action');
|
||||
});
|
||||
on('change:repeating_reaction remove:repeating_reaction', () => {
|
||||
this.count('reaction');
|
||||
this.updateChatMacro('reaction');
|
||||
});
|
||||
on('change:repeating_legendaryaction remove:repeating_legendaryaction', () => {
|
||||
this.count('legendaryaction');
|
||||
this.updateChatMacro('legendaryaction');
|
||||
});
|
||||
on('change:repeating_lairaction remove:repeating_lairaction', () => {
|
||||
this.count('lairaction');
|
||||
this.updateChatMacro('lairaction');
|
||||
});
|
||||
on('change:repeating_regionaleffect remove:repeating_regionaleffect', () => {
|
||||
this.count('regionaleffect');
|
||||
this.updateChatMacro('regionaleffect');
|
||||
});
|
||||
on('change:repeating_trait:freetext', (eventInfo) => {
|
||||
this.parse('trait', getRepeatingInfo('repeating_trait', eventInfo).rowId);
|
||||
});
|
||||
on('change:repeating_action:freetext', (eventInfo) => {
|
||||
this.parse('action', getRepeatingInfo('repeating_action', eventInfo).rowId);
|
||||
});
|
||||
on('change:repeating_reaction:freetext', (eventInfo) => {
|
||||
this.parse('reaction', getRepeatingInfo('repeating_reaction', eventInfo).rowId);
|
||||
});
|
||||
on('change:repeating_legendaryaction:freetext', (eventInfo) => {
|
||||
this.parse('legendaryaction', getRepeatingInfo('repeating_legendaryaction', eventInfo).rowId);
|
||||
});
|
||||
on('change:repeating_lairaction:freetext', (eventInfo) => {
|
||||
this.parse('lairaction', getRepeatingInfo('repeating_lairaction', eventInfo).rowId);
|
||||
});
|
||||
on('change:global_attack_bonus change:global_melee_attack_bonus change:global_ranged_attack_bonus change:global_damage_bonus change:global_melee_damage_bonus change:global_ranged_damage_bonus change:ammo_auto_use', () => {
|
||||
this.update('action');
|
||||
this.update('reaction');
|
||||
this.update('legendaryaction');
|
||||
this.update('lairaction');
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/* global on:false */
|
||||
|
||||
import { ABILITIES } from './constants';
|
||||
import { getSetRepeatingItems, exists } from './utilities';
|
||||
|
||||
export class Attachers {
|
||||
update() {
|
||||
const collectionArray = ['attacher_initiative', 'attacher_death_saving_throw', 'attacher_hit_dice', 'attacher_attack', 'attacher_spell', 'attacher_skill', 'attacher_crit'];
|
||||
const itemsToPush = ['initiative', 'death_saving_throw', 'hit_dice', 'attack', 'spell', 'skill'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`attacher_${ability}_check`);
|
||||
collectionArray.push(`attacher_${ability}_saving_throw`);
|
||||
itemsToPush.push(`${ability}_check`);
|
||||
itemsToPush.push(`${ability}_saving_throw`);
|
||||
}
|
||||
|
||||
getSetRepeatingItems('attachers.update', {
|
||||
repeatingItems: ['repeating_attacher'],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['name', 'freetext', 'freeform', 'crit_attacher'],
|
||||
itemsToPush,
|
||||
itemToPushSuffix: 'attacher',
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const itemToPush of itemsToPush) {
|
||||
finalSetAttrs[`attacher_${itemToPush}`] = '';
|
||||
}
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
for (const itemToPush of itemsToPush) {
|
||||
const attacher = v[`${repeatingString}${itemToPush}_attacher`];
|
||||
if (exists(attacher) && attacher === 'on') {
|
||||
const attacherName = v[`${repeatingString}name`] || '';
|
||||
|
||||
const freeText = v[`${repeatingString}freetext`];
|
||||
if (exists(attacherName) && exists(freeText)) {
|
||||
const critAttacher = v[`${repeatingString}crit_attacher`];
|
||||
if (critAttacher === 'on') {
|
||||
finalSetAttrs[`attacher_${itemToPush}`] += `{{crit_name=${attacherName}}} `;
|
||||
finalSetAttrs[`attacher_${itemToPush}`] += `{{crit_text=${freeText}}} `;
|
||||
} else {
|
||||
finalSetAttrs[`attacher_${itemToPush}`] += `{{${attacherName}=${freeText}}} `;
|
||||
}
|
||||
}
|
||||
const freeForm = v[`${repeatingString}freeform`];
|
||||
if (exists(freeForm)) {
|
||||
finalSetAttrs[`attacher_${itemToPush}`] += `${freeForm} `;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:repeating_attacher remove:repeating_attacher', () => {
|
||||
this.update();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
/* global on:false, generateRowID:false */
|
||||
import { ABILITIES } from './constants';
|
||||
import { updateAttackToggle, updateSavingThrowToggle, updateDamageToggle } from './updateToggles';
|
||||
import { getSetRepeatingItems, isUndefinedOrEmpty, setFinalAttrs, setCritDamage, sumRepeating, lowercaseDamageTypes, exists, getIntValue, getRepeatingInfo } from './utilities';
|
||||
|
||||
export class Attacks {
|
||||
findAmmo(name, callback) {
|
||||
let repeatingString;
|
||||
|
||||
getSetRepeatingItems('attacks.findAmmo', {
|
||||
repeatingItems: ['repeating_ammo'],
|
||||
collectionArrayAddItems: ['name', 'qty'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (v[`${repeatingString}name`] === name) {
|
||||
callback(`@{${repeatingString}qty}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
console.warn(`cannot find ammo field by the name ${name}, adding it`);
|
||||
repeatingString = `${repeatingItem}_${generateRowID()}_`;
|
||||
finalSetAttrs[`${repeatingString}name`] = name;
|
||||
finalSetAttrs[`${repeatingString}qty`] = 20;
|
||||
callback(`@{${repeatingString}qty}`);
|
||||
},
|
||||
});
|
||||
}
|
||||
update(rowId) {
|
||||
const collectionArray = ['pb', 'strength_mod', 'finesse_mod', 'global_attack_bonus', 'global_melee_attack_bonus', 'global_ranged_attack_bonus', 'global_damage_bonus', 'global_melee_damage_bonus', 'global_ranged_damage_bonus', 'default_ability', 'ammo_auto_use', 'base_dc'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
}
|
||||
|
||||
getSetRepeatingItems('attacks.update', {
|
||||
repeatingItems: ['repeating_attack'],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['name', 'type', 'roll_toggle', 'to_hit', 'attack_formula', 'proficiency', 'attack_ability', 'attack_bonus', 'ammo_toggle_var', 'ammo_field_name', 'ammo_used', 'saving_throw_toggle', 'saving_throw_ability', 'saving_throw_bonus', 'saving_throw_dc', 'damage_toggle', 'damage_formula', 'damage', 'damage_ability', 'damage_bonus', 'damage_type', 'damage_crit', 'second_damage_toggle', 'second_damage_formula', 'second_damage', 'second_damage_ability', 'second_damage_bonus', 'second_damage_type', 'second_damage_crit', 'damage_string', 'modifiers', 'properties', 'weight', 'parsed'],
|
||||
rowId,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
const attackName = v[`${repeatingString}name`];
|
||||
if (isUndefinedOrEmpty(attackName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}parsed`]) || v[`${repeatingString}parsed`].indexOf('modifiers') === -1) {
|
||||
const attackModifiers = v[`${repeatingString}modifiers`];
|
||||
if (exists(attackModifiers)) {
|
||||
const attackBonus = attackModifiers.replace(/.*(?:Melee|Ranged) Attacks \+(\d+).*/gi, '$1');
|
||||
const damageBonus = attackModifiers.replace(/.*(?:Melee|Ranged) Damage \+(\d+).*/gi, '$1');
|
||||
|
||||
finalSetAttrs[`${repeatingString}attack_bonus`] = attackBonus;
|
||||
finalSetAttrs[`${repeatingString}damage_bonus`] = damageBonus;
|
||||
if (!finalSetAttrs[`${repeatingString}parsed`]) {
|
||||
finalSetAttrs[`${repeatingString}parsed`] = '';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}parsed`] += ' modifiers';
|
||||
}
|
||||
}
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}parsed`]) || v[`${repeatingString}parsed`].indexOf('attackProperties') === -1) {
|
||||
const attackProperties = v[`${repeatingString}properties`];
|
||||
if (exists(attackProperties)) {
|
||||
if (attackProperties.indexOf('Reach') !== -1) {
|
||||
finalSetAttrs[`${repeatingString}reach`] = '10 ft';
|
||||
} else if (v[`${repeatingString}type`] === 'Melee Weapon') {
|
||||
finalSetAttrs[`${repeatingString}reach`] = '5 ft';
|
||||
}
|
||||
if (attackProperties.indexOf('Finesse') !== -1) {
|
||||
finalSetAttrs[`${repeatingString}attack_ability`] = 'finesse';
|
||||
finalSetAttrs[`${repeatingString}damage_ability`] = 'finesse';
|
||||
}
|
||||
if (!finalSetAttrs[`${repeatingString}parsed`]) {
|
||||
finalSetAttrs[`${repeatingString}parsed`] = '';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}parsed`] += ' attackProperties';
|
||||
}
|
||||
}
|
||||
|
||||
const attackOptions = {
|
||||
globalAttackBonus: v.global_attack_bonus,
|
||||
globalAttackBonusLabel: 'global attack bonus',
|
||||
globalMeleeAttackBonus: v.global_melee_attack_bonus,
|
||||
globalRangedAttackBonus: v.global_ranged_attack_bonus,
|
||||
type: 'attack',
|
||||
};
|
||||
updateAttackToggle(v, finalSetAttrs, repeatingString, attackOptions);
|
||||
|
||||
const ammoName = v[`${repeatingString}ammo_field_name`];
|
||||
const ammoUsed = getIntValue(v[`${repeatingString}ammo_used`], 1);
|
||||
if (!isUndefinedOrEmpty(ammoName)) {
|
||||
let ammoAutoUse;
|
||||
if (v.ammo_auto_use === '1') {
|
||||
ammoAutoUse = 1;
|
||||
} else {
|
||||
ammoAutoUse = 0;
|
||||
}
|
||||
|
||||
this.findAmmo(ammoName, (ammoQtyName) => {
|
||||
const setAmmo = {};
|
||||
setAmmo[`${repeatingString}ammo_toggle_var`] = `{{ammo=[[${ammoQtyName}-${ammoAutoUse * ammoUsed}]]}} {{ammo_name=${ammoName}}}`;
|
||||
setFinalAttrs(v, setAmmo, 'findAmmo');
|
||||
});
|
||||
}
|
||||
|
||||
updateSavingThrowToggle(v, finalSetAttrs, repeatingString);
|
||||
|
||||
const damageOptions = {
|
||||
globalDamageBonus: v.global_damage_bonus,
|
||||
globalMeleeDamageBonus: v.global_melee_damage_bonus,
|
||||
globalRangedDamageBonus: v.global_ranged_damage_bonus,
|
||||
type: 'attack',
|
||||
};
|
||||
updateDamageToggle(v, finalSetAttrs, repeatingString, damageOptions);
|
||||
if (v.damage_type) {
|
||||
finalSetAttrs.damage_type = lowercaseDamageTypes(v.damage_type);
|
||||
}
|
||||
if (v.second_damage_type) {
|
||||
finalSetAttrs.second_damage_type = lowercaseDamageTypes(v.second_damage_type);
|
||||
}
|
||||
setCritDamage(v, finalSetAttrs, repeatingString);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
weigh() {
|
||||
const options = {
|
||||
collection: 'attack',
|
||||
toggle: 'carried',
|
||||
qty: 'qty',
|
||||
};
|
||||
const sumItems = [
|
||||
{
|
||||
fieldToAdd: 'weight',
|
||||
itemTotal: 'weight_total',
|
||||
totalField: 'weight_attacks',
|
||||
},
|
||||
];
|
||||
sumRepeating(options, sumItems);
|
||||
}
|
||||
updateChatMacro() {
|
||||
getSetRepeatingItems('attacks.updateChatMacro', {
|
||||
repeatingItems: ['repeating_attack'],
|
||||
collectionArray: ['attacks_macro_var'],
|
||||
collectionArrayAddItems: ['name'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
finalSetAttrs.attacks_macro_var = '';
|
||||
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
let actionName = v[`${repeatingString}name`];
|
||||
if (actionName && actionName.length > 50) {
|
||||
actionName = `${actionName.substring(0, 50)}...`;
|
||||
}
|
||||
|
||||
if (id !== ids[0]) {
|
||||
finalSetAttrs.attacks_macro_var += ', ';
|
||||
}
|
||||
|
||||
finalSetAttrs.attacks_macro_var += `[${actionName}](~repeating_attack_${id}_attack)`;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:repeating_attack', (eventInfo) => {
|
||||
const repeatingInfo = getRepeatingInfo('repeating_attack', eventInfo);
|
||||
if (repeatingInfo && repeatingInfo.field !== 'roll_toggle' && repeatingInfo.field !== 'toggle_details' && repeatingInfo.field !== 'to_hit' && repeatingInfo.field !== 'attack_formula' && repeatingInfo.field !== 'damage_formula' && repeatingInfo.field !== 'damage_crit' && repeatingInfo.field !== 'second_damage_formula' && repeatingInfo.field !== 'second_damage_crit' && repeatingInfo.field !== 'damage_string' && repeatingInfo.field !== 'saving_throw_dc' && repeatingInfo.field !== 'qty' && repeatingInfo.field !== 'weight' && repeatingInfo.field !== 'parsed') {
|
||||
this.update(repeatingInfo.row);
|
||||
}
|
||||
});
|
||||
on('change:pb, change:global_attack_bonus change:global_melee_attack_bonus change:global_ranged_attack_bonus change:global_damage_bonus change:global_melee_damage_bonus change:global_ranged_damage_bonus change:ammo_auto_use', () => {
|
||||
this.update();
|
||||
});
|
||||
on('change:repeating_attack:carried change:repeating_attack:qty change:repeating_attack:weight remove:repeating_attack', () => {
|
||||
this.weigh();
|
||||
});
|
||||
on('change:repeating_attack remove:repeating_attack', () => {
|
||||
this.updateChatMacro();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
/* global on:false */
|
||||
|
||||
import { ABILITIES, CLASSES } from './constants';
|
||||
import { ClassFeatures } from './ClassFeatures';
|
||||
const classFeatures = new ClassFeatures();
|
||||
import { Spells } from './Spells';
|
||||
const spells = new Spells();
|
||||
import { getSetItems, getSetRepeatingItems, isUndefinedOrEmpty, getIntValue, exists, capitalize, getRepeatingInfo, updateHD } from './utilities';
|
||||
|
||||
export class Character {
|
||||
updateLevels(repeatingInfo) {
|
||||
const defaultClassDetails = {
|
||||
barbarian: {
|
||||
hd: 'd12',
|
||||
},
|
||||
bard: {
|
||||
hd: 'd8',
|
||||
spellcasting: 'full',
|
||||
},
|
||||
cleric: {
|
||||
hd: 'd8',
|
||||
spellcasting: 'full',
|
||||
},
|
||||
druid: {
|
||||
hd: 'd8',
|
||||
spellcasting: 'full',
|
||||
},
|
||||
fighter: {
|
||||
hd: 'd10',
|
||||
},
|
||||
monk: {
|
||||
hd: 'd8',
|
||||
},
|
||||
paladin: {
|
||||
hd: 'd10',
|
||||
spellcasting: 'half',
|
||||
},
|
||||
ranger: {
|
||||
hd: 'd10',
|
||||
spellcasting: 'half',
|
||||
},
|
||||
rogue: {
|
||||
hd: 'd8',
|
||||
},
|
||||
sorcerer: {
|
||||
hd: 'd6',
|
||||
spellcasting: 'full',
|
||||
},
|
||||
warlock: {
|
||||
hd: 'd8',
|
||||
spellcasting: 'warlock',
|
||||
},
|
||||
wizard: {
|
||||
hd: 'd6',
|
||||
spellcasting: 'full',
|
||||
},
|
||||
};
|
||||
const hd = {
|
||||
d20: 0,
|
||||
d12: 0,
|
||||
d10: 0,
|
||||
d8: 0,
|
||||
d6: 0,
|
||||
d4: 0,
|
||||
d2: 0,
|
||||
d0: 0,
|
||||
};
|
||||
const spellcasting = {
|
||||
full: 0,
|
||||
half: 0,
|
||||
third: 0,
|
||||
warlock: 0,
|
||||
};
|
||||
let totalLevel = 0;
|
||||
const classLevels = {};
|
||||
let classesWithSpellcasting = 0;
|
||||
const xpTable = [0, 300, 900, 2700, 6500, 14000, 23000, 34000, 48000, 64000, 85000, 100000, 120000, 140000, 165000, 195000, 225000, 265000, 305000, 355000, 385000, 405000, 435000, 465000, 495000, 525000, 555000, 585000, 605000, 635000, 665000];
|
||||
|
||||
const collectionArray = ['is_npc', 'caster_level', 'caster_type', 'class_and_level', 'level', 'xp_next_level'];
|
||||
for (const className of CLASSES) {
|
||||
collectionArray.push(`${className}_level`);
|
||||
collectionArray.push(`has_${className}_levels`);
|
||||
}
|
||||
for (const key in hd) {
|
||||
if (hd.hasOwnProperty(key)) {
|
||||
collectionArray.push(`hd_${key}_max`);
|
||||
collectionArray.push(`hd_${key}_query`);
|
||||
collectionArray.push(`hd_${key}_toggle`);
|
||||
}
|
||||
}
|
||||
|
||||
getSetRepeatingItems('character.updateLevels', {
|
||||
repeatingItems: ['repeating_class'],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['level', 'name', 'custom_name', 'hd', 'spellcasting', 'custom_class_toggle'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const className of CLASSES) {
|
||||
finalSetAttrs[`${className}_level`] = 0;
|
||||
}
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
let className = v[`${repeatingString}name`];
|
||||
let classLevel = v[`${repeatingString}level`];
|
||||
|
||||
if (isUndefinedOrEmpty(className) && isUndefinedOrEmpty(classLevel)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isUndefinedOrEmpty(className)) {
|
||||
className = 'barbarian';
|
||||
}
|
||||
if (className === 'custom') {
|
||||
finalSetAttrs[`${repeatingString}custom_class_toggle`] = 'on';
|
||||
const customName = v[`${repeatingString}custom_name`];
|
||||
if (exists(customName)) {
|
||||
className = customName;
|
||||
} else {
|
||||
className = 'custom';
|
||||
}
|
||||
} else if (v[`${repeatingString}custom_class_toggle`]) {
|
||||
finalSetAttrs[`${repeatingString}custom_class_toggle`] = 0;
|
||||
}
|
||||
|
||||
if (isUndefinedOrEmpty(classLevel)) {
|
||||
classLevel = 1;
|
||||
finalSetAttrs[`${repeatingString}level`] = classLevel;
|
||||
finalSetAttrs[`${className}_level`] = classLevel;
|
||||
} else {
|
||||
classLevel = getIntValue(classLevel);
|
||||
totalLevel += classLevel;
|
||||
if (classLevels[className]) {
|
||||
classLevels[className] += classLevel;
|
||||
} else {
|
||||
classLevels[className] = classLevel;
|
||||
}
|
||||
}
|
||||
|
||||
let classHd = v[`${repeatingString}hd`];
|
||||
if (isUndefinedOrEmpty(classHd) || (repeatingInfo && repeatingInfo.field === 'name')) {
|
||||
if (defaultClassDetails.hasOwnProperty(className)) {
|
||||
classHd = defaultClassDetails[className].hd;
|
||||
} else {
|
||||
classHd = 'd12';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}hd`] = classHd;
|
||||
}
|
||||
if (classHd && classLevel) {
|
||||
hd[classHd] += classLevel;
|
||||
}
|
||||
|
||||
let classSpellcasting = v[`${repeatingString}spellcasting`];
|
||||
if (isUndefinedOrEmpty(classSpellcasting)) {
|
||||
if (defaultClassDetails.hasOwnProperty(className)) {
|
||||
classSpellcasting = defaultClassDetails[className].spellcasting;
|
||||
if (classSpellcasting) {
|
||||
finalSetAttrs[`${repeatingString}spellcasting`] = classSpellcasting;
|
||||
}
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}spellcasting`] = 'none';
|
||||
}
|
||||
} else if (classSpellcasting === 'warlock') {
|
||||
spellcasting[classSpellcasting] += classLevel;
|
||||
} else {
|
||||
classesWithSpellcasting += 1;
|
||||
spellcasting[classSpellcasting] += classLevel;
|
||||
}
|
||||
}
|
||||
|
||||
finalSetAttrs.number_of_classes = 0;
|
||||
finalSetAttrs.class_and_level = '';
|
||||
for (const prop in classLevels) {
|
||||
if (classLevels.hasOwnProperty(prop)) {
|
||||
finalSetAttrs.number_of_classes = finalSetAttrs.number_of_classes + 1;
|
||||
if (classLevels.hasOwnProperty(prop)) {
|
||||
finalSetAttrs[`${prop}_level`] = classLevels[prop];
|
||||
if (finalSetAttrs.class_and_level !== '') {
|
||||
finalSetAttrs.class_and_level += ', ';
|
||||
}
|
||||
finalSetAttrs.class_and_level += `${capitalize(prop)} ${classLevels[prop]}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finalSetAttrs.level = totalLevel;
|
||||
|
||||
let xpForNextLevel = 0;
|
||||
if (!totalLevel) {
|
||||
totalLevel = 0;
|
||||
}
|
||||
if (totalLevel > 30) {
|
||||
xpForNextLevel = xpTable[30];
|
||||
} else {
|
||||
xpForNextLevel = xpTable[totalLevel];
|
||||
}
|
||||
finalSetAttrs.xp_next_level = xpForNextLevel;
|
||||
|
||||
for (const className of CLASSES) {
|
||||
if (finalSetAttrs[`${className}_level`] > 0) {
|
||||
finalSetAttrs[`has_${className}_levels`] = 1;
|
||||
} else if (!isUndefinedOrEmpty(v[`has_${className}_levels`])) {
|
||||
finalSetAttrs[`has_${className}_levels`] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
updateHD(v, finalSetAttrs, hd);
|
||||
|
||||
let casterLevel = 0;
|
||||
if (!v.is_npc || v.is_npc === '0' || v.is_npc === 0) {
|
||||
if (classesWithSpellcasting > 1) {
|
||||
casterLevel += spellcasting.full;
|
||||
casterLevel += Math.floor(spellcasting.half / 2);
|
||||
casterLevel += Math.floor(spellcasting.third / 3);
|
||||
} else {
|
||||
casterLevel = spellcasting.full + spellcasting.half + spellcasting.third;
|
||||
}
|
||||
finalSetAttrs.caster_level = casterLevel;
|
||||
}
|
||||
|
||||
if (classesWithSpellcasting > 1 || spellcasting.full) {
|
||||
finalSetAttrs.caster_type = 'full';
|
||||
} else if (spellcasting.half) {
|
||||
finalSetAttrs.caster_type = 'half';
|
||||
} else if (spellcasting.third) {
|
||||
finalSetAttrs.caster_type = 'third';
|
||||
}
|
||||
},
|
||||
setFinalAttrsCallback: () => {
|
||||
classFeatures.set();
|
||||
spells.updateSlots();
|
||||
},
|
||||
});
|
||||
}
|
||||
watchForClassLevelChanges() {
|
||||
const classFeatureWatch = [];
|
||||
for (const ability of ABILITIES) {
|
||||
classFeatureWatch.push(`change:${ability}_mod`);
|
||||
}
|
||||
classFeatureWatch.push('change:careful_spell_toggle');
|
||||
classFeatureWatch.push('change:distant_spell_toggle');
|
||||
classFeatureWatch.push('change:empowered_spell_toggle');
|
||||
classFeatureWatch.push('change:extended_spell_toggle');
|
||||
classFeatureWatch.push('change:heightened_spell_toggle');
|
||||
classFeatureWatch.push('change:quickened_spell_toggle');
|
||||
classFeatureWatch.push('change:subtle_spell_toggle');
|
||||
classFeatureWatch.push('change:twinned_spell_toggle');
|
||||
|
||||
on(classFeatureWatch.join(' '), () => {
|
||||
classFeatures.set();
|
||||
});
|
||||
}
|
||||
updateJackOfAllTrades() {
|
||||
getSetItems('character.updateJackOfAllTrades', {
|
||||
collectionArray: ['pb', 'jack_of_all_trades'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.jack_of_all_trades = Math.floor(getIntValue(v.pb) / 2);
|
||||
},
|
||||
});
|
||||
}
|
||||
updateRemarkableAthlete() {
|
||||
getSetItems('character.updateRemarkableAthlete', {
|
||||
collectionArray: ['pb', 'remarkable_athlete'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.remarkable_athlete = Math.ceil(getIntValue(v.pb) / 2);
|
||||
},
|
||||
});
|
||||
}
|
||||
updateD20Mod() {
|
||||
getSetItems('character.updateD20Mod', {
|
||||
collectionArray: ['halfling_luck'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.halfling_luck === 'on') {
|
||||
finalSetAttrs.d20_mod = 'ro<1';
|
||||
} else {
|
||||
finalSetAttrs.d20_mod = '';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateAlignment() {
|
||||
getSetItems('character.updateAlignment', {
|
||||
collectionArray: ['alignment', 'is_npc'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.alignment && v.is_npc === '1') {
|
||||
finalSetAttrs.alignment = v.alignment.toLowerCase();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:repeating_class', (eventInfo) => {
|
||||
const repeatingInfo = getRepeatingInfo('repeating_class', eventInfo);
|
||||
if (repeatingInfo) {
|
||||
this.updateLevels(repeatingInfo);
|
||||
}
|
||||
});
|
||||
on('remove:repeating_class', () => {
|
||||
this.updateLevels();
|
||||
});
|
||||
on('change:halfling_luck', () => {
|
||||
this.updateD20Mod();
|
||||
});
|
||||
on('change:alignment', () => {
|
||||
this.updateAlignment();
|
||||
});
|
||||
on('change:pb change:remarkable_athlete_toggle', () => {
|
||||
this.updateRemarkableAthlete();
|
||||
});
|
||||
on('change:pb change:jack_of_all_trades_toggle', () => {
|
||||
this.updateJackOfAllTrades();
|
||||
});
|
||||
this.watchForClassLevelChanges();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,966 @@
|
||||
/* global getTranslationByKey:false */
|
||||
|
||||
import { getSetItems, isUndefinedOrEmpty, getIntValue } from './utilities';
|
||||
import { CLASSES, ABILITIES, TOGGLE_VARS } from './constants';
|
||||
import { Traits } from './Traits';
|
||||
const traits = new Traits();
|
||||
|
||||
export class ClassFeatures {
|
||||
extraAttack(v) {
|
||||
if (v.fighter_level >= 5) {
|
||||
let extraAttackTimes;
|
||||
if (v.fighter_level >= 20) {
|
||||
extraAttackTimes = getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK_FOUR');
|
||||
} else if (v.fighter_level >= 11) {
|
||||
extraAttackTimes = getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK_THREE');
|
||||
} else {
|
||||
extraAttackTimes = getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK_TWICE');
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK_TEXT').replace('NUMBER_OF_TIMES', extraAttackTimes),
|
||||
name: getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK'),
|
||||
storageName: 'Extra Attack',
|
||||
});
|
||||
} else if (v.barbarian_level >= 5 || v.monk_level >= 5 || v.paladin_level >= 5 || v.ranger_level >= 5) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK_TEXT').replace('NUMBER_OF_TIMES', getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK_TWICE')),
|
||||
name: getTranslationByKey('CLASS_FEATURE_EXTRA_ATTACK'),
|
||||
storageName: 'Extra Attack',
|
||||
});
|
||||
}
|
||||
}
|
||||
barbarian(v, finalSetAttrs) {
|
||||
if (v.barbarian_level) {
|
||||
let rageUses;
|
||||
if (v.barbarian_level >= 20) {
|
||||
rageUses = 999999;
|
||||
} else if (v.barbarian_level >= 17) {
|
||||
rageUses = 6;
|
||||
} else if (v.barbarian_level >= 12) {
|
||||
rageUses = 5;
|
||||
} else if (v.barbarian_level >= 6) {
|
||||
rageUses = 4;
|
||||
} else if (v.barbarian_level >= 3) {
|
||||
rageUses = 3;
|
||||
} else {
|
||||
rageUses = 2;
|
||||
}
|
||||
|
||||
let rageDamage;
|
||||
if (v.barbarian_level >= 16) {
|
||||
rageDamage = 4;
|
||||
} else if (v.barbarian_level >= 9) {
|
||||
rageDamage = 3;
|
||||
} else {
|
||||
rageDamage = 2;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_RAGE_TEXT').replace('RAGE_DAMAGE', rageDamage),
|
||||
name: getTranslationByKey('CLASS_FEATURE_RAGE'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Rage',
|
||||
type: 'Other',
|
||||
uses_max: rageUses,
|
||||
});
|
||||
|
||||
if (isUndefinedOrEmpty(v.ac_unarmored_ability)) {
|
||||
finalSetAttrs.ac_unarmored_ability = 'constitution';
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_UNARMORED_DEFENSE_BARBARIAN_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_UNARMORED_DEFENSE'),
|
||||
storageName: 'Unarmored Defense Barbarian',
|
||||
});
|
||||
|
||||
if (v.barbarian_level >= 2) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_RECKLESS_ATTACK_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_RECKLESS_ATTACK'),
|
||||
storageName: 'Reckless Attack',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_DANGER_SENSE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_DANGER_SENSE'),
|
||||
storageName: 'Danger Sense',
|
||||
});
|
||||
}
|
||||
if (v.barbarian_level >= 5) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_FAST_MOVEMENT_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_FAST_MOVEMENT'),
|
||||
storageName: 'Fast Movement',
|
||||
});
|
||||
}
|
||||
if (v.barbarian_level >= 7) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_FERAL_INSTINCT_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_FERAL_INSTINCT'),
|
||||
storageName: 'Feral Instinct',
|
||||
});
|
||||
}
|
||||
if (v.barbarian_level >= 9) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_BRUTAL_CRITICAL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_BRUTAL_CRITICAL'),
|
||||
storageName: 'Brutal Critical',
|
||||
});
|
||||
}
|
||||
if (v.barbarian_level >= 11) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_RELENTLESS_RAGE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_RELENTLESS_RAGE'),
|
||||
storageName: 'Relentless Rage',
|
||||
});
|
||||
}
|
||||
if (v.barbarian_level >= 15) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_PERSISTENT_RAGE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_PERSISTENT_RAGE'),
|
||||
storageName: 'Persistent Rage',
|
||||
});
|
||||
}
|
||||
if (v.barbarian_level >= 18) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_INDOMITABLE_MIGHT_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_INDOMITABLE_MIGHT'),
|
||||
storageName: 'Indomitable Might',
|
||||
});
|
||||
}
|
||||
if (v.barbarian_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_PRIMAL_CHAMPION_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_PRIMAL_CHAMPION'),
|
||||
storageName: 'Primal Champion',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
bard(v, finalSetAttrs) {
|
||||
if (v.bard_level) {
|
||||
let die;
|
||||
if (v.bard_level >= 15) {
|
||||
die = 'd12';
|
||||
} else if (v.bard_level >= 10) {
|
||||
die = 'd10';
|
||||
} else if (v.bard_level >= 5) {
|
||||
die = 'd8';
|
||||
} else {
|
||||
die = 'd6';
|
||||
}
|
||||
let recharge = 'Long Rest';
|
||||
if (v.bard_level >= 5) {
|
||||
recharge = 'Short Rest';
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_BARDIC_INSPIRATION_TEXT').replace('d6', die),
|
||||
name: getTranslationByKey('CLASS_FEATURE_BARDIC_INSPIRATION'),
|
||||
recharge,
|
||||
storageName: 'Bardic Inspiration',
|
||||
uses_max: Math.max(getIntValue(v.charisma_mod), 1),
|
||||
});
|
||||
|
||||
if (v.bard_level >= 2) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_JACK_OF_ALL_TRADES_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_JACK_OF_ALL_TRADES'),
|
||||
storageName: 'Jack of All Trades',
|
||||
});
|
||||
finalSetAttrs.jack_of_all_trades_toggle = '@{jack_of_all_trades}';
|
||||
|
||||
let heal;
|
||||
if (v.bard_level >= 17) {
|
||||
heal = 'd12';
|
||||
} else if (v.bard_level >= 13) {
|
||||
heal = 'd10';
|
||||
} else if (v.bard_level >= 9) {
|
||||
heal = 'd8';
|
||||
} else {
|
||||
heal = 'd6';
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SONG_OF_REST_TEXT'),
|
||||
heal,
|
||||
name: getTranslationByKey('CLASS_FEATURE_SONG_OF_REST'),
|
||||
storageName: 'Song of Rest',
|
||||
});
|
||||
}
|
||||
if (v.bard_level >= 3) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_EXPERTISE_BARD_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_EXPERTISE'),
|
||||
storageName: 'Expertise Bard',
|
||||
});
|
||||
}
|
||||
if (v.bard_level >= 6) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_COUNTERCHARM_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_COUNTERCHARM'),
|
||||
storageName: 'Countercharm',
|
||||
});
|
||||
}
|
||||
if (v.bard_level >= 10) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_MAGICAL_SECRETS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_MAGICAL_SECRETS'),
|
||||
storageName: 'Magical Secrets',
|
||||
});
|
||||
}
|
||||
if (v.bard_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SUPERIOR_INSPIRATION_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SUPERIOR_INSPIRATION'),
|
||||
storageName: 'Superior Inspiration',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
cleric(v) {
|
||||
if (v.cleric_level) {
|
||||
if (v.cleric_level >= 2) {
|
||||
let channelDivinityUses;
|
||||
if (v.cleric_level >= 18) {
|
||||
channelDivinityUses = 3;
|
||||
} else if (v.cleric_level >= 6) {
|
||||
channelDivinityUses = 2;
|
||||
} else {
|
||||
channelDivinityUses = 1;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_CHANNEL_DIVINITY_CLERIC_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_CHANNEL_DIVINITY'),
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Channel Divinity Cleric',
|
||||
uses_max: channelDivinityUses,
|
||||
});
|
||||
|
||||
let turnUndeadText = getTranslationByKey('CLASS_FEATURE_CHANNEL_DIVINITY_TURN_UNDEAD_TEXT');
|
||||
if (v.cleric_level >= 5) {
|
||||
let turnUndeadDestroyCR;
|
||||
if (v.cleric_level >= 17) {
|
||||
turnUndeadDestroyCR = '4';
|
||||
} else if (v.cleric_level >= 14) {
|
||||
turnUndeadDestroyCR = '3';
|
||||
} else if (v.cleric_level >= 11) {
|
||||
turnUndeadDestroyCR = '2';
|
||||
} else if (v.cleric_level >= 8) {
|
||||
turnUndeadDestroyCR = '1';
|
||||
} else {
|
||||
turnUndeadDestroyCR = '1/2';
|
||||
}
|
||||
turnUndeadText += `\n${getTranslationByKey('CLASS_FEATURE_CHANNEL_DIVINITY_TURN_UNDEAD_TEXT_PART_2').replace('CHALLENGE_RATING', turnUndeadDestroyCR)}`;
|
||||
}
|
||||
traits.set({
|
||||
freetext: turnUndeadText,
|
||||
name: getTranslationByKey('CLASS_FEATURE_CHANNEL_DIVINITY_TURN_UNDEAD'),
|
||||
saving_throw_ability: 'wisdom',
|
||||
saving_throw_vs_ability: 'WISDOM',
|
||||
storageName: 'Turn Undead',
|
||||
});
|
||||
if (v.cleric_level >= 10) {
|
||||
traits.set({
|
||||
freeform: '{{text_top=[[d100]] > [[@{cleric_level}]]}}',
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_DIVINE_INTERVENTION_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_DIVINE_INTERVENTION'),
|
||||
storageName: 'Divine Intervention',
|
||||
uses_max: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
druid(v) {
|
||||
if (v.druid_level) {
|
||||
if (v.druid_level >= 2) {
|
||||
const wildShapeHours = Math.floor(v.druid_level / 2);
|
||||
let wildShapeUses;
|
||||
let wildShapeCR;
|
||||
let wildShapeLimitations;
|
||||
|
||||
if (v.druid_level >= 4) {
|
||||
wildShapeCR = '1/2';
|
||||
wildShapeLimitations = getTranslationByKey('CLASS_FEATURE_WILD_SHAPE_NO_FLYING');
|
||||
} else if (v.druid_level >= 8) {
|
||||
wildShapeCR = 1;
|
||||
wildShapeLimitations = '';
|
||||
} else {
|
||||
wildShapeCR = '1/4';
|
||||
wildShapeLimitations = getTranslationByKey('CLASS_FEATURE_WILD_SHAPE_NO_FLYING_OR_SWIMMING');
|
||||
}
|
||||
if (v.druid_level >= 20) {
|
||||
wildShapeUses = 999999;
|
||||
} else {
|
||||
wildShapeUses = 2;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_WILD_SHAPE_TEXT')
|
||||
.replace('WILD_SHAPE_HOURS', wildShapeHours)
|
||||
.replace('CHALLENGE_RATING', wildShapeCR)
|
||||
.replace('LIMITATIONS', ` ${wildShapeLimitations}`),
|
||||
name: getTranslationByKey('CLASS_FEATURE_WILD_SHAPE'),
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Wild Shape',
|
||||
uses_max: wildShapeUses,
|
||||
});
|
||||
}
|
||||
if (v.druid_level >= 18) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_TIMELESS_BODY_DRUID_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_TIMELESS_BODY'),
|
||||
storageName: 'Timeless Body',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_BEAST_SPELLS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_BEAST_SPELLS'),
|
||||
storageName: 'Beast Spells',
|
||||
});
|
||||
}
|
||||
if (v.druid_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_ARCHDRUID_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_ARCHDRUID'),
|
||||
storageName: 'Archdruid',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
fighter(v) {
|
||||
if (v.fighter_level) {
|
||||
traits.set({
|
||||
freetext: `${getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE_TEXT')} ${getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE_FIGHTER_OPTIONS')}`,
|
||||
name: getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE'),
|
||||
storageName: 'Fighting Style',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SECOND_WIND_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SECOND_WIND'),
|
||||
heal: 'd10 + @{fighter_level}',
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Second Wind',
|
||||
uses_max: 1,
|
||||
});
|
||||
|
||||
if (v.fighter_level >= 2) {
|
||||
let actionSurgeUses;
|
||||
if (v.fighter_level >= 17) {
|
||||
actionSurgeUses = 2;
|
||||
} else {
|
||||
actionSurgeUses = 1;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_ACTION_SURGE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_ACTION_SURGE'),
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Action Surge',
|
||||
uses_max: actionSurgeUses,
|
||||
});
|
||||
}
|
||||
if (v.fighter_level >= 9) {
|
||||
let indomitableUses;
|
||||
if (v.fighter_level >= 17) {
|
||||
indomitableUses = 3;
|
||||
} else if (v.fighter_level >= 13) {
|
||||
indomitableUses = 2;
|
||||
} else {
|
||||
indomitableUses = 1;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_INDOMITABLE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_INDOMITABLE'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Indomitable',
|
||||
uses_max: indomitableUses,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
monk(v, finalSetAttrs) {
|
||||
if (v.monk_level) {
|
||||
if (isUndefinedOrEmpty(v.ac_unarmored_ability)) {
|
||||
finalSetAttrs.ac_unarmored_ability = 'wisdom';
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_UNARMORED_DEFENSE_MONK_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_UNARMORED_DEFENSE'),
|
||||
storageName: 'Unarmored Defense Monk',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_MARTIAL_ARTS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_MARTIAL_ARTS'),
|
||||
storageName: 'Martial Arts',
|
||||
});
|
||||
if (v.monk_level >= 2) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_KI_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_KI'),
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Ki',
|
||||
uses_max: v.monk_level,
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_FLURRY_OF_BLOWS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_FLURRY_OF_BLOWS'),
|
||||
storageName: 'Flurry of Blows',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_PATIENT_DEFENSE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_PATIENT_DEFENSE'),
|
||||
storageName: 'Patient Defense',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_STEP_OF_THE_WIND_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_STEP_OF_THE_WIND'),
|
||||
storageName: 'Step of the Wind',
|
||||
});
|
||||
|
||||
let unarmoredMovementFeet;
|
||||
if (v.monk_level >= 18) {
|
||||
unarmoredMovementFeet = 30;
|
||||
} else if (v.monk_level >= 14) {
|
||||
unarmoredMovementFeet = 25;
|
||||
} else if (v.monk_level >= 10) {
|
||||
unarmoredMovementFeet = 20;
|
||||
} else if (v.monk_level >= 6) {
|
||||
unarmoredMovementFeet = 15;
|
||||
} else {
|
||||
unarmoredMovementFeet = 10;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_UNARMORED_MOVEMENT_TEXT').replace('UNARMORED_MOVEMENT_FEET', unarmoredMovementFeet),
|
||||
name: getTranslationByKey('CLASS_FEATURE_UNARMORED_MOVEMENT'),
|
||||
storageName: 'Unarmored Movement',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 3) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_DEFLECT_MISSILES_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_DEFLECT_MISSILES'),
|
||||
storageName: 'Deflect Missiles',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 4) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SLOW_FALL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SLOW_FALL'),
|
||||
storageName: 'Slow Fall',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 5) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_STUNNING_STRIKE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_STUNNING_STRIKE'),
|
||||
saving_throw_ability: 'wisdom',
|
||||
saving_throw_failure: getTranslationByKey('CLASS_FEATURE_STUNNING_STRIKE_SAVING_THROW_FAILURE'),
|
||||
saving_throw_vs_ability: 'CONSTITUTION',
|
||||
storageName: 'Stunning Strike',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 6) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_KI_EMPOWERED_STRIKES_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_KI_EMPOWERED_STRIKES'),
|
||||
storageName: 'Ki-Empowered Strikes',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 7) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_EVASION_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_EVASION'),
|
||||
storageName: 'Evasion',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_STILLNESS_OF_MIND_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_STILLNESS_OF_MIND'),
|
||||
storageName: 'Stillness of Mind',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 10) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_PURITY_OF_BODY_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_PURITY_OF_BODY'),
|
||||
storageName: 'Purity of Body',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 13) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_TONGUE_OF_THE_SUN_AND_MOON_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_TONGUE_OF_THE_SUN_AND_MOON'),
|
||||
storageName: 'Tongue of the Sun and Moon',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 14) {
|
||||
finalSetAttrs.death_saving_throw_prof = '@{pb}';
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_DIAMOND_SOUL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_DIAMOND_SOUL'),
|
||||
storageName: 'Diamond Soul',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 15) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_TIMELESS_BODY_MONK_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_TIMELESS_BODY'),
|
||||
storageName: 'Timeless Body',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 15) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_EMPTY_BODY_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_EMPTY_BODY'),
|
||||
storageName: 'Empty Body',
|
||||
});
|
||||
}
|
||||
if (v.monk_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_PERFECT_SELF_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_PERFECT_SELF'),
|
||||
storageName: 'Perfect Self',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
paladin(v) {
|
||||
if (v.paladin_level) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_DIVINE_SENSE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_DIVINE_SENSE'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Divine Sense',
|
||||
uses_max: Math.max(1 + v.charisma_mod, 1),
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_LAY_ON_HANDS_TEXT'),
|
||||
heal_query_toggle: TOGGLE_VARS.heal_query,
|
||||
name: getTranslationByKey('CLASS_FEATURE_LAY_ON_HANDS'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Lay on Hands',
|
||||
uses_max: 5 * v.paladin_level,
|
||||
});
|
||||
|
||||
if (v.paladin_level >= 2) {
|
||||
traits.set({
|
||||
freetext: `${getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE_TEXT')} ${getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE_PALADIN_OPTIONS')}`,
|
||||
name: getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE'),
|
||||
storageName: 'Fighting Style',
|
||||
});
|
||||
traits.set({
|
||||
damage: '(?{Spell Level|1|2|3|4+, 4} + 1)d8',
|
||||
damage_type: getTranslationByKey('RADIANT'),
|
||||
freeform: '{{subheader=(as ?{Spell Level|1|2|3|4+})}}',
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_DIVINE_SMITE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_DIVINE_SMITE'),
|
||||
second_damage: 'd8',
|
||||
second_damage_type: getTranslationByKey('VS_FIEND_OR_UNDEAD'),
|
||||
storageName: 'Divine Smite',
|
||||
type: 'Other',
|
||||
});
|
||||
}
|
||||
if (v.paladin_level >= 3) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_DIVINE_HEALTH_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_DIVINE_HEALTH'),
|
||||
storageName: 'Divine Health',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_CHANNEL_DIVINITY_PALADIN_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_CHANNEL_DIVINITY'),
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Channel Divinity Paladin',
|
||||
uses_max: 1,
|
||||
});
|
||||
}
|
||||
if (v.paladin_level >= 6) {
|
||||
let auraRange;
|
||||
if (v.paladin_level >= 18) {
|
||||
auraRange = 30;
|
||||
} else {
|
||||
auraRange = 10;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_AURA_OF_PROTECTION_TEXT').replace('AURA_RANGE', auraRange),
|
||||
name: getTranslationByKey('CLASS_FEATURE_AURA_OF_PROTECTION'),
|
||||
storageName: 'Aura of Protection',
|
||||
});
|
||||
|
||||
if (v.paladin_level >= 10) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_AURA_OF_COURAGE_TEXT').replace('AURA_RANGE', auraRange),
|
||||
name: getTranslationByKey('CLASS_FEATURE_AURA_OF_COURAGE'),
|
||||
storageName: 'Aura of Courage',
|
||||
});
|
||||
}
|
||||
}
|
||||
if (v.paladin_level >= 11) {
|
||||
traits.set({
|
||||
damage: '1d8',
|
||||
damage_type: 'radiant',
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_IMPROVED_DIVINE_SMITE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_IMPROVED_DIVINE_SMITE'),
|
||||
storageName: 'Improved Divine Smite',
|
||||
type: 'Other',
|
||||
});
|
||||
}
|
||||
if (v.paladin_level >= 14) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_CLEANSING_TOUCH_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_CLEANSING_TOUCH'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Cleaning Touch',
|
||||
uses_max: Math.max(getIntValue(v.charisma_mod), 1),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
ranger(v) {
|
||||
if (v.ranger_level) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_FAVORED_ENEMY_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_FAVORED_ENEMY'),
|
||||
storageName: 'Favored Enemy',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_NATURAL_EXPLORER_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_NATURAL_EXPLORER'),
|
||||
storageName: 'Natural Explorer',
|
||||
});
|
||||
if (v.ranger_level >= 2) {
|
||||
traits.set({
|
||||
freetext: `${getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE_TEXT')} ${getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE_RANGER_OPTIONS')}`,
|
||||
name: getTranslationByKey('CLASS_FEATURE_FIGHTING_STYLE'),
|
||||
storageName: 'Fighting Style',
|
||||
});
|
||||
}
|
||||
if (v.ranger_level >= 3) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_PRIMEVAL_AWARENESS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_PRIMEVAL_AWARENESS'),
|
||||
storageName: 'Primeval Awareness',
|
||||
});
|
||||
}
|
||||
if (v.ranger_level >= 8) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_LANDS_STRIDE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_LANDS_STRIDE'),
|
||||
storageName: 'Land\'s Stride',
|
||||
});
|
||||
}
|
||||
if (v.ranger_level >= 10) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_HIDE_IN_PLAIN_SIGHT_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_HIDE_IN_PLAIN_SIGHT'),
|
||||
storageName: 'Hide in Plain Sight',
|
||||
});
|
||||
}
|
||||
if (v.ranger_level >= 14) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_VANISH_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_VANISH'),
|
||||
storageName: 'Vanish',
|
||||
});
|
||||
}
|
||||
if (v.ranger_level >= 18) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_FERAL_SENSES_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_FERAL_SENSES'),
|
||||
storageName: 'Feral Senses',
|
||||
});
|
||||
}
|
||||
if (v.ranger_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_FOE_SLAYER_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_FOE_SLAYER'),
|
||||
storageName: 'Foe Slayer',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
rogue(v) {
|
||||
if (v.rogue_level) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_EXPERTISE_ROGUE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_EXPERTISE'),
|
||||
storageName: 'Expertise Rogue',
|
||||
});
|
||||
traits.set({
|
||||
damage: `${Math.ceil(getIntValue(v.rogue_level) / 2)}d6`,
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SNEAK_ATTACK_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SNEAK_ATTACK'),
|
||||
storageName: 'Sneak Attack',
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_THIEVES_CANT_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_THIEVES_CANT'),
|
||||
storageName: 'Thieves\' Cant',
|
||||
});
|
||||
if (v.rogue_level >= 2) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_CUNNING_ACTION_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_CUNNING_ACTION'),
|
||||
storageName: 'Cunning Action',
|
||||
});
|
||||
}
|
||||
if (v.rogue_level >= 5) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_UNCANNY_DODGE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_UNCANNY_DODGE'),
|
||||
storageName: 'Uncanny Dodge',
|
||||
});
|
||||
}
|
||||
if (v.rogue_level >= 7) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_EVASION_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_EVASION'),
|
||||
storageName: 'Evasion',
|
||||
});
|
||||
}
|
||||
if (v.rogue_level >= 11) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_RELIABLE_TALENT_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_RELIABLE_TALENT'),
|
||||
storageName: 'Reliable Talent',
|
||||
});
|
||||
}
|
||||
if (v.rogue_level >= 14) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_BLINDSENSE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_BLINDSENSE'),
|
||||
storageName: 'Blindsense',
|
||||
});
|
||||
}
|
||||
if (v.rogue_level >= 15) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SLIPPERY_MIND_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SLIPPERY_MIND'),
|
||||
storageName: 'Slippery Mind',
|
||||
});
|
||||
}
|
||||
if (v.rogue_level >= 18) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_ELUSIVE_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_ELUSIVE'),
|
||||
storageName: 'Elusive',
|
||||
});
|
||||
}
|
||||
if (v.rogue_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_STROKE_OF_LUCK_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_STROKE_OF_LUCK'),
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Stroke of Luck',
|
||||
uses_max: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
sorcerer(v) {
|
||||
if (v.sorcerer_level) {
|
||||
if (v.sorcerer_level >= 2) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SORCERY_POINTS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SORCERY_POINTS'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Sorcery Points',
|
||||
uses_max: v.sorcerer_level,
|
||||
});
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_FLEXIBLE_CASTING_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_FLEXIBLE_CASTING'),
|
||||
storageName: 'Flexible Casting',
|
||||
});
|
||||
if (v.sorcerer_level >= 3) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC'),
|
||||
storageName: 'Metamagic',
|
||||
});
|
||||
}
|
||||
if (v.sorcerer_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SORCEROUS_RESTORATION_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SORCEROUS_RESTORATION'),
|
||||
storageName: 'Sorcerous Restoration',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
warlock(v) {
|
||||
if (v.warlock_level) {
|
||||
let warlockSpellSlots;
|
||||
if (v.warlock_level >= 17) {
|
||||
warlockSpellSlots = 4;
|
||||
} else if (v.warlock_level >= 11) {
|
||||
warlockSpellSlots = 3;
|
||||
} else if (v.warlock_level >= 2) {
|
||||
warlockSpellSlots = 2;
|
||||
} else {
|
||||
warlockSpellSlots = 1;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_WARLOCK_SPELL_SLOTS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_WARLOCK_SPELL_SLOTS'),
|
||||
recharge: 'Short Rest',
|
||||
storageName: 'Warlock Spell Slots',
|
||||
uses_max: warlockSpellSlots,
|
||||
});
|
||||
|
||||
if (v.warlock_level >= 2) {
|
||||
let eldritchInvocations;
|
||||
if (v.warlock_level >= 17) {
|
||||
eldritchInvocations = 8;
|
||||
} else if (v.warlock_level >= 15) {
|
||||
eldritchInvocations = 7;
|
||||
} else if (v.warlock_level >= 12) {
|
||||
eldritchInvocations = 6;
|
||||
} else if (v.warlock_level >= 9) {
|
||||
eldritchInvocations = 5;
|
||||
} else if (v.warlock_level >= 7) {
|
||||
eldritchInvocations = 4;
|
||||
} else if (v.warlock_level >= 5) {
|
||||
eldritchInvocations = 3;
|
||||
} else {
|
||||
eldritchInvocations = 2;
|
||||
}
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_ELDRITCH_INVOCATIONS_TEXT').replace('NUMBER_OF_INVOCATIONS_KNOWN', eldritchInvocations),
|
||||
name: getTranslationByKey('CLASS_FEATURE_ELDRITCH_INVOCATIONS'),
|
||||
storageName: 'Eldritch Invocations',
|
||||
});
|
||||
}
|
||||
if (v.warlock_level >= 3) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_PACT_BOON_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_PACT_BOON'),
|
||||
storageName: 'Pact Boon',
|
||||
});
|
||||
}
|
||||
if (v.warlock_level >= 11) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_MYSTIC_ARCANUM_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_MYSTIC_ARCANUM'),
|
||||
storageName: 'Mystic Arcanum',
|
||||
});
|
||||
}
|
||||
if (v.warlock_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_ELDRITCH_MASTER_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_ELDRITCH_MASTER'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Eldritch Master',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
wizard(v) {
|
||||
if (v.wizard_level) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_ARCANE_RECOVERY_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_ARCANE_RECOVERY'),
|
||||
recharge: 'Long Rest',
|
||||
storageName: 'Arcane Recovery',
|
||||
uses_max: 1,
|
||||
});
|
||||
if (v.wizard_level >= 18) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SPELL_MASTERY_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SPELL_MASTERY'),
|
||||
storageName: 'Spell Mastery',
|
||||
});
|
||||
}
|
||||
if (v.wizard_level >= 20) {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_SIGNATURE_SPELLS_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_SIGNATURE_SPELLS'),
|
||||
storageName: 'Signature Spells',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
metamagic(v) {
|
||||
if (v.careful_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_CAREFUL_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_CAREFUL_SPELL'),
|
||||
storageName: 'Careful Spell',
|
||||
});
|
||||
}
|
||||
if (v.distant_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_DISTANT_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_DISTANT_SPELL'),
|
||||
storageName: 'Distant Spell',
|
||||
});
|
||||
}
|
||||
if (v.empowered_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_EMPOWERED_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_EMPOWERED_SPELL'),
|
||||
storageName: 'Empowered Spell',
|
||||
});
|
||||
}
|
||||
if (v.extended_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_EXTENDED_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_EXTENDED_SPELL'),
|
||||
storageName: 'Extended Spell',
|
||||
});
|
||||
}
|
||||
if (v.heightened_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_HEIGHTENED_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_HEIGHTENED_SPELL'),
|
||||
storageName: 'Heightened Spell',
|
||||
});
|
||||
}
|
||||
if (v.quickened_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_QUICKENED_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_QUICKENED_SPELL'),
|
||||
storageName: 'Quickened Spell',
|
||||
});
|
||||
}
|
||||
if (v.subtle_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_SUBTLE_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_SUBTLE_SPELL'),
|
||||
storageName: 'Subtle Spell',
|
||||
});
|
||||
}
|
||||
if (v.twinned_spell_toggle === '1') {
|
||||
traits.set({
|
||||
freetext: getTranslationByKey('CLASS_FEATURE_METAMAGIC_TWINNED_SPELL_TEXT'),
|
||||
name: getTranslationByKey('CLASS_FEATURE_METAMAGIC_TWINNED_SPELL'),
|
||||
storageName: 'Twinned Spell',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
set() {
|
||||
const collectionArray = ['ac_unarmored_ability', 'jack_of_all_trades_toggle', 'careful_spell_toggle', 'distant_spell_toggle', 'empowered_spell_toggle', 'extended_spell_toggle', 'heightened_spell_toggle', 'quickened_spell_toggle', 'subtle_spell_toggle', 'twinned_spell_toggle'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
}
|
||||
for (const className of CLASSES) {
|
||||
collectionArray.push(`${className}_level`);
|
||||
}
|
||||
|
||||
getSetItems('classFeatures.set', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
this.extraAttack(v);
|
||||
this.barbarian(v, finalSetAttrs);
|
||||
this.bard(v, finalSetAttrs);
|
||||
this.cleric(v);
|
||||
this.druid(v);
|
||||
this.fighter(v);
|
||||
this.monk(v, finalSetAttrs);
|
||||
this.paladin(v);
|
||||
this.ranger(v);
|
||||
this.rogue(v);
|
||||
this.sorcerer(v);
|
||||
this.warlock(v);
|
||||
this.wizard(v);
|
||||
this.metamagic(v);
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/* global on:false */
|
||||
|
||||
import { ABILITIES, SKILLS } from './constants';
|
||||
import { getSetItems, getSetRepeatingItems, getSkillIdByStorageName, getFloatValue, sumRepeating, isUndefinedOrEmpty, getRepeatingInfo, exists, round } from './utilities';
|
||||
|
||||
export class Equipment {
|
||||
setAdvantageOnStealth(mode) {
|
||||
getSetRepeatingItems('equipment.setAdvantageOnStealth', {
|
||||
repeatingItems: ['repeating_skill'],
|
||||
collectionArrayAddItems: ['storage_name', 'skill_d20'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const prop in SKILLS) {
|
||||
if (SKILLS.hasOwnProperty(prop)) {
|
||||
const skillId = getSkillIdByStorageName(v, repeatingItem, ids, prop);
|
||||
const repeatingString = `${repeatingItem}_${skillId}_`;
|
||||
|
||||
if (v[`${repeatingString}storage_name`] === 'STEALTH') {
|
||||
if (mode === 'dis') {
|
||||
finalSetAttrs[`${repeatingString}skill_d20`] = '2d20@{d20_mod}kl1';
|
||||
} else if (mode === 'normal') {
|
||||
finalSetAttrs[`${repeatingString}skill_d20`] = '@{shaped_d20}';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateArmor(rowId) {
|
||||
let stealthPenalty;
|
||||
|
||||
getSetRepeatingItems('equipment.updateArmor', {
|
||||
repeatingItems: ['repeating_armor'],
|
||||
collectionArrayAddItems: ['parsed', 'modifiers', 'stealth'],
|
||||
rowId,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}parsed`]) || v[`${repeatingString}parsed`].indexOf('acBonus') === -1) {
|
||||
const armorModifiers = v[`${repeatingString}modifiers`];
|
||||
if (exists(armorModifiers)) {
|
||||
finalSetAttrs[`${repeatingString}ac_bonus`] = armorModifiers.replace(/^\D+/g, '');
|
||||
}
|
||||
if (isUndefinedOrEmpty(finalSetAttrs[`${repeatingString}parsed`])) {
|
||||
finalSetAttrs[`${repeatingString}parsed`] = '';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}parsed`] += ' acBonus';
|
||||
}
|
||||
|
||||
if (v[`${repeatingString}stealth`] === 'Disadvantage') {
|
||||
stealthPenalty = true;
|
||||
}
|
||||
}
|
||||
if (stealthPenalty) {
|
||||
this.setAdvantageOnStealth('dis');
|
||||
} else {
|
||||
this.setAdvantageOnStealth('normal');
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
const options = {
|
||||
collection: 'armor',
|
||||
getExtraFields: ['medium_armor_max_dex', 'dexterity_mod', 'ac_unarmored_ability', 'is_npc'],
|
||||
toggle: 'worn',
|
||||
};
|
||||
for (const ability of ABILITIES) {
|
||||
options.getExtraFields.push(`${ability}_mod`);
|
||||
}
|
||||
const sumItems = [
|
||||
{
|
||||
fieldToAdd: 'weight',
|
||||
totalField: 'weight_armor',
|
||||
},
|
||||
{
|
||||
fieldToAdd: 'ac_base',
|
||||
bonus: 'ac_bonus',
|
||||
armorType: 'type',
|
||||
itemTotal: 'ac_total',
|
||||
totalField: 'ac_armored_calc',
|
||||
totalFieldSecondary: 'ac_unarmored_calc',
|
||||
},
|
||||
];
|
||||
sumRepeating(options, sumItems);
|
||||
}
|
||||
update(rowId) {
|
||||
getSetRepeatingItems('equipment.update', {
|
||||
repeatingItems: ['repeating_equipment'],
|
||||
collectionArrayAddItems: ['content'],
|
||||
rowId,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}parsed`]) || v[`${repeatingString}parsed`].indexOf('content') === -1) {
|
||||
let content = v[`${repeatingString}content`];
|
||||
if (exists(content)) {
|
||||
content = content.replace(/\s(\d+d\d+\s(?:\+|\-)\s\d+)\s/g, ' [[$1]] ')
|
||||
.replace(/\s(\d+d\d+)\s/g, ' [[$1]] ')
|
||||
.replace(/\s(\d+)\s/g, ' [[$1]] ');
|
||||
|
||||
finalSetAttrs[`${repeatingString}content`] = content;
|
||||
|
||||
if (isUndefinedOrEmpty(finalSetAttrs[`${repeatingString}parsed`])) {
|
||||
finalSetAttrs[`${repeatingString}parsed`] = '';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}parsed`] += ' content';
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
weigh() {
|
||||
const options = {
|
||||
collection: 'equipment',
|
||||
toggle: 'carried',
|
||||
qty: 'qty',
|
||||
};
|
||||
const sumItems = [
|
||||
{
|
||||
fieldToAdd: 'weight',
|
||||
itemTotal: 'weight_total',
|
||||
totalField: 'weight_equipment',
|
||||
},
|
||||
];
|
||||
sumRepeating(options, sumItems);
|
||||
}
|
||||
updateWeight() {
|
||||
getSetItems('equipment.updateWeight', {
|
||||
collectionArray: ['weight_attacks', 'weight_ammo', 'weight_armor', 'weight_equipment', 'weight_coinage'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.weight_total = round((getFloatValue(v.weight_attacks) + getFloatValue(v.weight_ammo) + getFloatValue(v.weight_armor) + getFloatValue(v.weight_equipment) + getFloatValue(v.weight_coinage)), 2);
|
||||
},
|
||||
});
|
||||
}
|
||||
weighAmmo() {
|
||||
const options = {
|
||||
collection: 'ammo',
|
||||
qty: 'qty',
|
||||
};
|
||||
const sumItems = [
|
||||
{
|
||||
fieldToAdd: 'weight',
|
||||
totalField: 'weight_ammo',
|
||||
},
|
||||
];
|
||||
sumRepeating(options, sumItems);
|
||||
}
|
||||
calculateGold() {
|
||||
getSetItems('equipment.calculateGold', {
|
||||
collectionArray: ['cp', 'copper_per_gold', 'sp', 'silver_per_gold', 'ep', 'electrum_per_gold', 'gp', 'pp', 'platinum_per_gold'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const copperPieces = getFloatValue(v.cp);
|
||||
const silverPieces = getFloatValue(v.sp);
|
||||
const electrumPieces = getFloatValue(v.ep);
|
||||
const goldPieces = getFloatValue(v.gp);
|
||||
const platinumPieces = getFloatValue(v.pp);
|
||||
const copperPerGold = getFloatValue(v.copper_per_gold, 100);
|
||||
const silverPerGold = getFloatValue(v.silver_per_gold, 10);
|
||||
const electrumPerGold = getFloatValue(v.electrum_per_gold, 2);
|
||||
const platinumPerGold = getFloatValue(v.platinum_per_gold, 10);
|
||||
|
||||
finalSetAttrs.total_gp = ((copperPieces / copperPerGold) + (silverPieces / silverPerGold) + (electrumPieces / electrumPerGold) + goldPieces + (platinumPieces * platinumPerGold)).toFixed(2);
|
||||
finalSetAttrs.weight_coinage = (copperPieces + silverPieces + electrumPieces + goldPieces + platinumPieces) / 50;
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:repeating_armor', (eventInfo) => {
|
||||
const repeatingInfo = getRepeatingInfo('repeating_armor', eventInfo);
|
||||
if (repeatingInfo && repeatingInfo.field !== 'ac_total') {
|
||||
this.updateArmor(repeatingInfo.rowId);
|
||||
}
|
||||
});
|
||||
on('change:dexterity_mod change:medium_armor_max_dex change:ac_unarmored_ability remove:repeating_armor', () => {
|
||||
this.updateArmor();
|
||||
});
|
||||
on('change:repeating_equipment', (eventInfo) => {
|
||||
this.update(getRepeatingInfo('repeating_equipment', eventInfo).rowId);
|
||||
});
|
||||
on('change:repeating_equipment:carried change:repeating_equipment:qty change:repeating_equipment:weight remove:repeating_equipment', () => {
|
||||
this.weigh();
|
||||
});
|
||||
on('change:repeating_ammo:weight change:repeating_ammo:qty', () => {
|
||||
this.weighAmmo();
|
||||
});
|
||||
on('change:weight_attacks change:weight_ammo change:weight_armor change:weight_equipment change:weight_coinage', () => {
|
||||
this.updateWeight();
|
||||
});
|
||||
on('change:cp change:copper_per_gold change:sp change:silver_per_gold change:ep change:electrum_per_gold change:gp change:pp change:platinum_per_gold', () => {
|
||||
this.calculateGold();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/* global on:false, generateRowID:false */
|
||||
|
||||
import { Initialize } from './Initialize';
|
||||
const initialize = new Initialize();
|
||||
import { getSetItems } from './utilities';
|
||||
|
||||
export class ImportData {
|
||||
import() {
|
||||
getSetItems('importData.import', {
|
||||
collectionArray: ['import_data', 'version'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.import_data) {
|
||||
const importObject = JSON.parse(v.import_data);
|
||||
|
||||
if (importObject.npc) {
|
||||
if (!v.version) {
|
||||
initialize.sheetOpened();
|
||||
}
|
||||
for (const prop in importObject.npc) {
|
||||
if (importObject.npc.hasOwnProperty(prop)) {
|
||||
finalSetAttrs[prop] = importObject.npc[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (importObject.spells) {
|
||||
importObject.spells.forEach(spell => {
|
||||
const repeatingString = `repeating_spell_${generateRowID()}_`;
|
||||
for (const prop in spell) {
|
||||
if (spell.hasOwnProperty(prop)) {
|
||||
finalSetAttrs[`${repeatingString}${prop}`] = spell[prop];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
finalSetAttrs.import_data = '';
|
||||
finalSetAttrs.import_data_present = 'off';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
delete() {
|
||||
getSetItems('importData.delete', {
|
||||
collectionArray: ['import_data', 'version'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const importObject = JSON.parse(v.import_data);
|
||||
if (importObject.npc && !v.version) {
|
||||
initialize.sheetOpened(); // NPC import will have wiped all the existing attributes
|
||||
}
|
||||
finalSetAttrs.import_data = '';
|
||||
finalSetAttrs.import_data_present = 'off';
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:accept_import', () => {
|
||||
this.import();
|
||||
});
|
||||
on('change:reject_import', () => {
|
||||
this.delete();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/* global on:false, generateRowID:false, getTranslationByKey:false */
|
||||
|
||||
import { Abilities } from './Abilities';
|
||||
const abilities = new Abilities();
|
||||
import { AbilityChecks } from './AbilityChecks';
|
||||
const abilityChecks = new AbilityChecks();
|
||||
import { Character } from './Character';
|
||||
const character = new Character();
|
||||
import { SKILLS } from './constants';
|
||||
import { Equipment } from './Equipment';
|
||||
const equipment = new Equipment();
|
||||
import { ProficiencyBonus } from './ProficiencyBonus';
|
||||
const proficiencyBonus = new ProficiencyBonus();
|
||||
import { SavingThrows } from './SavingThrows';
|
||||
const savingThrows = new SavingThrows();
|
||||
import { Spells } from './Spells';
|
||||
const spells = new Spells();
|
||||
import { Upgrade } from './Upgrade';
|
||||
const upgrade = new Upgrade();
|
||||
import { getSetItems, getSetRepeatingItems, isUndefinedOrEmpty, setFinalAttrs, getSkillIdByStorageName } from './utilities';
|
||||
import { currentVersion } from './version';
|
||||
|
||||
|
||||
export class Initialize {
|
||||
generateSkills() {
|
||||
getSetRepeatingItems('initialize.generateSkills', {
|
||||
repeatingItems: ['repeating_skill'],
|
||||
collectionArrayAddItems: ['storage_name', 'name', 'ability'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const prop in SKILLS) {
|
||||
if (SKILLS.hasOwnProperty(prop)) {
|
||||
let skillId = getSkillIdByStorageName(v, repeatingItem, ids, prop);
|
||||
|
||||
if (!skillId) {
|
||||
skillId = generateRowID();
|
||||
}
|
||||
const repeatingString = `${repeatingItem}_${skillId}_`;
|
||||
|
||||
finalSetAttrs[`${repeatingString}storage_name`] = prop;
|
||||
finalSetAttrs[`${repeatingString}name`] = getTranslationByKey(prop);
|
||||
finalSetAttrs[`${repeatingString}ability`] = SKILLS[prop];
|
||||
abilityChecks.updateSkill(skillId);
|
||||
}
|
||||
}
|
||||
},
|
||||
setFinalAttrsCallback: () => {
|
||||
abilityChecks.updateMacro();
|
||||
},
|
||||
});
|
||||
}
|
||||
checkVersionFormat(version, finalSetAttrs) {
|
||||
const versionRegex = /\d+\.\d+\.\d+/gi;
|
||||
const versionIsProperFormat = versionRegex.exec(version);
|
||||
|
||||
if (version && !versionIsProperFormat) {
|
||||
finalSetAttrs.version = version = currentVersion;
|
||||
}
|
||||
return version;
|
||||
}
|
||||
sheetOpened() {
|
||||
console.log('initialize.sheetOpened');
|
||||
getSetItems('initialize.sheetOpened', {
|
||||
collectionArray: ['version', 'strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma', 'import_data', 'roll_setting'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const version = this.checkVersionFormat(v.version, finalSetAttrs);
|
||||
|
||||
if (!version) {
|
||||
if (!v.import_data) {
|
||||
finalSetAttrs.edit_mode = 'on';
|
||||
}
|
||||
if (isUndefinedOrEmpty(v.roll_setting)) { // API Script import sets this when making characters
|
||||
finalSetAttrs.roll_setting = '{{ignore=[[0';
|
||||
}
|
||||
const setAbilities = {};
|
||||
if (isUndefinedOrEmpty(v.strength)) {
|
||||
setAbilities.strength = 10;
|
||||
}
|
||||
if (isUndefinedOrEmpty(v.dexterity)) {
|
||||
setAbilities.dexterity = 10;
|
||||
}
|
||||
if (isUndefinedOrEmpty(v.constitution)) {
|
||||
setAbilities.constitution = 10;
|
||||
}
|
||||
if (isUndefinedOrEmpty(v.intelligence)) {
|
||||
setAbilities.intelligence = 10;
|
||||
}
|
||||
if (isUndefinedOrEmpty(v.wisdom)) {
|
||||
setAbilities.wisdom = 10;
|
||||
}
|
||||
if (isUndefinedOrEmpty(v.charisma)) {
|
||||
setAbilities.charisma = 10;
|
||||
}
|
||||
setFinalAttrs(v, setAbilities, 'initialize', () => {
|
||||
proficiencyBonus.update();
|
||||
this.generateSkills();
|
||||
savingThrows.update();
|
||||
character.updateLevels();
|
||||
abilityChecks.updateInitiative();
|
||||
equipment.updateArmor();
|
||||
spells.updateShowHide();
|
||||
abilities.updateModifiers();
|
||||
});
|
||||
} else {
|
||||
upgrade.upgrade();
|
||||
}
|
||||
|
||||
if (isUndefinedOrEmpty(version) || !version || version !== currentVersion) {
|
||||
finalSetAttrs.version = currentVersion;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:generate_skills', () => {
|
||||
this.generateSkills();
|
||||
});
|
||||
on('sheet:opened', () => {
|
||||
this.sheetOpened();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,434 @@
|
||||
/* global on:false, generateRowID:false */
|
||||
|
||||
import { ABILITIES } from './constants';
|
||||
import { getSetItems, getIntValue, isUndefinedOrEmpty, addArithmeticOperator, getAbilityMod, numberWithCommas, exists, updateHD } from './utilities';
|
||||
|
||||
export class Npc {
|
||||
updateType() {
|
||||
getSetItems('npc.updateType', {
|
||||
collectionArray: ['type'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.type) {
|
||||
finalSetAttrs.type = v.type.toLowerCase();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateSize() {
|
||||
getSetItems('npc.updateSize', {
|
||||
collectionArray: ['size'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const creatureSize = v.size || 'Large';
|
||||
const sizeToHdSize = {
|
||||
Tiny: 4,
|
||||
Small: 6,
|
||||
Medium: 8,
|
||||
Large: 10,
|
||||
Huge: 12,
|
||||
Gargantuan: 20,
|
||||
};
|
||||
finalSetAttrs.hit_die = `d${sizeToHdSize[creatureSize]}`;
|
||||
},
|
||||
});
|
||||
}
|
||||
updateAC() {
|
||||
getSetItems('npc.updateAC', {
|
||||
collectionArray: ['ac_srd', 'ac', 'ac_note', 'dexterity_mod'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (exists(v.ac_srd)) {
|
||||
const match = v.ac_srd.match(/(\d+)\s?(.*)/);
|
||||
if (match && match[1]) {
|
||||
finalSetAttrs.AC = match[1];
|
||||
}
|
||||
if (match && match[2]) {
|
||||
finalSetAttrs.ac_note = match[2].replace(/\(|\)/g, '');
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
switchTo() {
|
||||
getSetItems('npc.switchTo', {
|
||||
collectionArray: ['is_npc', 'size'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const isNPC = getIntValue(v.is_npc) === 1;
|
||||
|
||||
if (isNPC && isUndefinedOrEmpty(v.size)) {
|
||||
finalSetAttrs.size = 'Large';
|
||||
}
|
||||
|
||||
if (isNPC) {
|
||||
finalSetAttrs.hit_dice_output_option = '/w GM';
|
||||
} else {
|
||||
finalSetAttrs.hit_dice_output_option = '';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateChallenge() {
|
||||
const xpPerChallenge = {
|
||||
0: 0,
|
||||
'1/8': 25,
|
||||
'1/4': 50,
|
||||
'1/2': 100,
|
||||
1: 200,
|
||||
2: 450,
|
||||
3: 700,
|
||||
4: 1100,
|
||||
5: 1800,
|
||||
6: 2300,
|
||||
7: 2900,
|
||||
8: 3900,
|
||||
9: 5000,
|
||||
10: 5900,
|
||||
11: 7200,
|
||||
12: 8400,
|
||||
13: 10000,
|
||||
14: 11500,
|
||||
15: 13000,
|
||||
16: 15000,
|
||||
17: 18000,
|
||||
18: 20000,
|
||||
19: 22000,
|
||||
20: 25000,
|
||||
21: 33000,
|
||||
22: 41000,
|
||||
23: 50000,
|
||||
24: 62000,
|
||||
25: 75000,
|
||||
26: 90000,
|
||||
27: 105000,
|
||||
28: 120000,
|
||||
29: 135000,
|
||||
30: 155000,
|
||||
};
|
||||
|
||||
getSetItems('npc.updateChallenge', {
|
||||
collectionArray: ['challenge', 'xp'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const challenge = v.challenge;
|
||||
|
||||
finalSetAttrs.xp = xpPerChallenge[challenge];
|
||||
finalSetAttrs.xp_readable = numberWithCommas(finalSetAttrs.xp);
|
||||
|
||||
finalSetAttrs.level = challenge;
|
||||
if (finalSetAttrs.level < 1) {
|
||||
finalSetAttrs.level = 1;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateHPFromSRD() {
|
||||
getSetItems('npc.updateHPFromSRD', {
|
||||
collectionArray: ['hp_srd', 'constitution', 'constitution_mod', 'constitution_bonus', 'global_ability_bonus'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (exists(v.hp_srd)) {
|
||||
const match = v.hp_srd.match(/\((\d+)d(\d+)(?:\s?(\+|\-)\s?(\d+))?\)/i);
|
||||
if (!match || !match[1] || !match[2]) {
|
||||
console.warn('Character doesn\'t have valid HP/HD format');
|
||||
} else {
|
||||
const hdNum = getIntValue(match[1]);
|
||||
|
||||
let conMod = getIntValue(v.constitution_mod);
|
||||
if (!conMod) {
|
||||
const conScore = getIntValue(v.constitution);
|
||||
const conBonus = getIntValue(v.constitution_bonus);
|
||||
const globalAbilityBonus = getIntValue(v.global_ability_bonus);
|
||||
|
||||
conMod = getAbilityMod((conScore + conBonus + globalAbilityBonus));
|
||||
}
|
||||
|
||||
finalSetAttrs.hit_dice = hdNum;
|
||||
finalSetAttrs.hit_die = `d${getIntValue(match[2])}`;
|
||||
|
||||
const hpExpectedBonus = hdNum * conMod;
|
||||
const hpBonusSign = match[3];
|
||||
const hpBonus = getIntValue(match[4]);
|
||||
if (hpBonus !== hpExpectedBonus) {
|
||||
if (hpBonusSign === '-') {
|
||||
finalSetAttrs.hp_extra = hpBonus + hpExpectedBonus;
|
||||
} else {
|
||||
finalSetAttrs.hp_extra = hpBonus - hpExpectedBonus;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateHP() {
|
||||
getSetItems('npc.updateHP', {
|
||||
collectionArray: ['HP', 'HP_max', 'hp_formula', 'hit_dice', 'hit_die', 'hp_extra', 'constitution_mod'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const hdNum = getIntValue(v.hit_dice);
|
||||
const hdSize = getIntValue(v.hit_die.replace('d', ''));
|
||||
const hdAverage = (hdSize / 2) + 0.5;
|
||||
let hpFormula = `${hdNum}d${hdSize}`;
|
||||
const conMod = getIntValue(v.constitution_mod);
|
||||
let totalHP = Math.floor(hdNum * hdAverage);
|
||||
let amount;
|
||||
|
||||
if (conMod !== 0) {
|
||||
const bonusHP = hdNum * conMod;
|
||||
totalHP += bonusHP;
|
||||
hpFormula += addArithmeticOperator(hpFormula, bonusHP);
|
||||
}
|
||||
|
||||
if (exists(v.hp_extra)) {
|
||||
const regex = (/(?:(\+|\-)\s?)?(\d+)(?:d(\d+))?/gi);
|
||||
let splitFormula;
|
||||
|
||||
while ((splitFormula = regex.exec(v.hp_extra)) !== null) {
|
||||
if (!splitFormula || !splitFormula[2]) {
|
||||
console.warn('Character doesn\'t have valid hp formula');
|
||||
} else {
|
||||
amount = 0;
|
||||
|
||||
if (!splitFormula[3]) {
|
||||
amount = getIntValue(splitFormula[2]);
|
||||
} else {
|
||||
const extraHdNum = getIntValue(splitFormula[2]);
|
||||
const extraHdSize = getIntValue(splitFormula[3]);
|
||||
const extraHdAverage = (extraHdSize / 2) + 0.5;
|
||||
amount = Math.floor(extraHdNum * extraHdAverage);
|
||||
}
|
||||
|
||||
if (!splitFormula[1] || splitFormula[1] === '+') {
|
||||
totalHP += amount;
|
||||
hpFormula += ` + ${amount}`;
|
||||
} else if (splitFormula[1] === '-') {
|
||||
totalHP -= amount;
|
||||
hpFormula += ` - ${amount}`;
|
||||
}
|
||||
}
|
||||
v.hp_extra.toString().replace(splitFormula[0], '');
|
||||
}
|
||||
}
|
||||
|
||||
if (totalHP) {
|
||||
finalSetAttrs.HP = totalHP;
|
||||
finalSetAttrs.HP_max = totalHP;
|
||||
finalSetAttrs.hp_formula = hpFormula;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateHD() {
|
||||
const hd = {
|
||||
d20: 0,
|
||||
d12: 0,
|
||||
d10: 0,
|
||||
d8: 0,
|
||||
d6: 0,
|
||||
d4: 0,
|
||||
d2: 0,
|
||||
d0: 0,
|
||||
};
|
||||
const collectionArray = ['hit_dice', 'hit_die'];
|
||||
for (const key in hd) {
|
||||
if (hd.hasOwnProperty(key)) {
|
||||
collectionArray.push(`hd_${key}_max`);
|
||||
collectionArray.push(`hd_${key}_query`);
|
||||
collectionArray.push(`hd_${key}_toggle`);
|
||||
}
|
||||
}
|
||||
getSetItems('npc.updateHD', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const hdNum = getIntValue(v.hit_dice);
|
||||
const hdSize = v.hit_die;
|
||||
|
||||
if (hdNum && hdSize) {
|
||||
hd[hdSize] = hdNum;
|
||||
|
||||
updateHD(v, finalSetAttrs, hd);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
parseSRDContentSection(content, finalSetAttrs, title, name) {
|
||||
const re = /@(.*)@:\s([^@]+)/gi;
|
||||
let match;
|
||||
let section;
|
||||
|
||||
if (content.indexOf(title) !== -1) {
|
||||
const contentSplit = content.split(`${title}\n`);
|
||||
section = contentSplit[1];
|
||||
content = contentSplit[0];
|
||||
}
|
||||
if (exists(section)) {
|
||||
if (name === 'legendaryaction') {
|
||||
const legendaryActionsMatch = section.match(/Can take (\d+) Legendary Actions/i);
|
||||
if (legendaryActionsMatch && legendaryActionsMatch[1]) {
|
||||
finalSetAttrs.legendary_action_amount = legendaryActionsMatch[1];
|
||||
}
|
||||
}
|
||||
|
||||
while ((match = re.exec(section.replace(/\*\*/g, '@'))) !== null) {
|
||||
if (match && match[1] && match[2]) {
|
||||
const repeatingString = `repeating_${name}_${generateRowID()}_`;
|
||||
finalSetAttrs[`${repeatingString}name`] = match[1];
|
||||
const text = match[2].trim();
|
||||
if (name === 'trait') {
|
||||
finalSetAttrs[`${repeatingString}display_text`] = text;
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}freetext`] = text;
|
||||
} else {
|
||||
console.warn(`Character doesn\'t have a valid ${name} format`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return content;
|
||||
}
|
||||
setDefaultAbility(v, finalSetAttrs) {
|
||||
const abilityScores = [getIntValue(v.intelligence), getIntValue(v.wisdom), getIntValue(v.charisma)];
|
||||
const highestAbilityScore = Math.max.apply(Math, abilityScores);
|
||||
let highestAbilityName = 'intelligence';
|
||||
|
||||
if (highestAbilityScore === abilityScores[1]) {
|
||||
highestAbilityName = 'wisdom';
|
||||
} else if (highestAbilityScore === abilityScores[2]) {
|
||||
highestAbilityName = 'charisma';
|
||||
}
|
||||
|
||||
finalSetAttrs.default_ability = highestAbilityName;
|
||||
}
|
||||
updateContent() {
|
||||
const collectionArray = ['content_srd'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(ability);
|
||||
}
|
||||
|
||||
getSetItems('npc.updateContent', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
let content = v.content_srd;
|
||||
let regionalEffects;
|
||||
let lairActions;
|
||||
let repeatingString;
|
||||
|
||||
this.setDefaultAbility(v, finalSetAttrs);
|
||||
|
||||
if (exists(content)) {
|
||||
if (content.indexOf('Regional Effects') !== -1) {
|
||||
const regionalEffectsSplit = content.split(/Regional Effects\n/);
|
||||
regionalEffects = regionalEffectsSplit[1];
|
||||
content = regionalEffectsSplit[0];
|
||||
}
|
||||
if (exists(regionalEffects)) {
|
||||
const regionalEffectsList = regionalEffects.split(/\*\*/);
|
||||
regionalEffectsList.slice(1, -1).forEach((regionalEffect) => {
|
||||
repeatingString = `repeating_regionaleffect_${generateRowID()}_`;
|
||||
finalSetAttrs[`${repeatingString}freetext`] = regionalEffect.trim();
|
||||
});
|
||||
finalSetAttrs.regional_effects_fade = regionalEffectsList.slice(-1)[0];
|
||||
}
|
||||
if (content.indexOf('Lair Actions') !== -1) {
|
||||
const lairActionsSplit = content.split(/Lair Actions\n/);
|
||||
lairActions = lairActionsSplit[1];
|
||||
content = lairActionsSplit[0];
|
||||
}
|
||||
if (exists(lairActions)) {
|
||||
lairActions.split(/\*\*/).slice(1).forEach((lairAction) => {
|
||||
repeatingString = `repeating_lairaction_${generateRowID()}_`;
|
||||
finalSetAttrs[`${repeatingString}freetext`] = lairAction.trim();
|
||||
});
|
||||
}
|
||||
|
||||
content = this.parseSRDContentSection(content, finalSetAttrs, 'Legendary Actions', 'legendaryaction');
|
||||
content = this.parseSRDContentSection(content, finalSetAttrs, 'Reactions', 'reaction');
|
||||
content = this.parseSRDContentSection(content, finalSetAttrs, 'Actions', 'action');
|
||||
this.parseSRDContentSection(content, finalSetAttrs, 'Traits', 'trait');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateSenses() {
|
||||
getSetItems('npc.updateSenses', {
|
||||
collectionArray: ['senses'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.senses) {
|
||||
finalSetAttrs.senses_exist = 1;
|
||||
finalSetAttrs.senses = v.senses.toLowerCase();
|
||||
} else {
|
||||
finalSetAttrs.senses_exist = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateLanguages() {
|
||||
getSetItems('npc.updateLanguages', {
|
||||
collectionArray: ['languages', 'languages_exist', 'languages_chat_var'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.languages_exist = 0;
|
||||
finalSetAttrs.languages_chat_var = '';
|
||||
|
||||
if (v.languages) {
|
||||
finalSetAttrs.languages_exist = 1;
|
||||
finalSetAttrs.languages_chat_var = '{{Languages=@{languages}}}';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateSpeed() {
|
||||
getSetItems('npc.updateSpeed', {
|
||||
collectionArray: ['npc_speed'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.npc_speed = v.npc_speed.toLowerCase();
|
||||
const match = finalSetAttrs.npc_speed.match(/^\s*(\d+)\s*ft/);
|
||||
if (match && match[1]) {
|
||||
finalSetAttrs.speed = match[1];
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateACNote() {
|
||||
getSetItems('npc.updateACNote', {
|
||||
collectionArray: ['ac_note'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.ac_note = v.ac_note.toLowerCase();
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:type', () => {
|
||||
this.updateType();
|
||||
});
|
||||
on('change:size', () => {
|
||||
this.updateSize();
|
||||
});
|
||||
on('change:ac_srd', () => {
|
||||
this.updateAC();
|
||||
});
|
||||
on('change:is_npc', () => {
|
||||
this.switchTo();
|
||||
});
|
||||
on('change:challenge', () => {
|
||||
this.updateChallenge();
|
||||
});
|
||||
on('change:hp_srd', () => {
|
||||
this.updateHPFromSRD();
|
||||
});
|
||||
on('change:hit_dice change:hit_die change:hp_extra change:constitution_mod', () => {
|
||||
this.updateHP();
|
||||
});
|
||||
on('change:hit_dice change:hit_die', () => {
|
||||
this.updateHD();
|
||||
});
|
||||
on('change:content_srd', () => {
|
||||
this.updateContent();
|
||||
});
|
||||
on('change:senses', () => {
|
||||
this.updateSenses();
|
||||
});
|
||||
on('change:languages', () => {
|
||||
this.updateLanguages();
|
||||
});
|
||||
on('change:npc_speed', () => {
|
||||
this.updateSpeed();
|
||||
});
|
||||
on('change:ac_note', () => {
|
||||
this.updateACNote();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* global on:false */
|
||||
|
||||
import { getSetItems, getIntValue, exists } from './utilities';
|
||||
|
||||
export class ProficiencyBonus {
|
||||
get(level, challenge) {
|
||||
let pb = 2;
|
||||
|
||||
level = getIntValue(level);
|
||||
if (challenge === '1/8' || challenge === '1/4' || challenge === '1/2') {
|
||||
challenge = 1;
|
||||
} else {
|
||||
getIntValue(challenge);
|
||||
}
|
||||
const levelOrChallenge = Math.max(level, challenge);
|
||||
|
||||
if (exists(levelOrChallenge)) {
|
||||
pb += Math.floor(Math.abs((levelOrChallenge - 1) / 4));
|
||||
}
|
||||
return pb;
|
||||
}
|
||||
update() {
|
||||
getSetItems('proficiencyBonus.update', {
|
||||
collectionArray: ['level', 'challenge', 'pb', 'exp', 'h_PB'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const pb = this.get(v.level, v.challenge);
|
||||
finalSetAttrs.pb = pb;
|
||||
finalSetAttrs.exp = pb * 2;
|
||||
finalSetAttrs.h_PB = pb / 2;
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:level', () => {
|
||||
this.update();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/* global on:false */
|
||||
|
||||
import { getSetItems, lowercaseDamageTypes } from './utilities';
|
||||
|
||||
export class Resistances {
|
||||
updateDamageResistancesVar() {
|
||||
getSetItems('resistances.updateDamageResistancesVar', {
|
||||
collectionArray: ['damage_resistances_var', 'damage_vulnerabilities_exist', 'damage_resistances_exist', 'damage_immunities_exist', 'condition_immunities_exist'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const resistancesVar = [];
|
||||
|
||||
if (v.damage_vulnerabilities_exist) {
|
||||
resistancesVar.push('{{Damage Vulnerabilities=@{damage_vulnerabilities}}}');
|
||||
}
|
||||
if (v.damage_resistances_exist) {
|
||||
resistancesVar.push('{{Damage Resistances=@{damage_resistances}}}');
|
||||
}
|
||||
if (v.damage_immunities_exist) {
|
||||
resistancesVar.push('{{Damage Immunities=@{damage_immunities}}}');
|
||||
}
|
||||
if (v.condition_immunities_exist) {
|
||||
resistancesVar.push('{{Condition Immunities=@{condition_immunities}}}');
|
||||
}
|
||||
|
||||
finalSetAttrs.damage_resistances_var = resistancesVar.join(' ');
|
||||
},
|
||||
});
|
||||
}
|
||||
updateDamageVulnerabilities() {
|
||||
getSetItems('resistances.updateDamageVulnerabilities', {
|
||||
collectionArray: ['damage_vulnerabilities'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.damage_vulnerabilities) {
|
||||
finalSetAttrs.damage_vulnerabilities_exist = 1;
|
||||
finalSetAttrs.damage_vulnerabilities = lowercaseDamageTypes(v.damage_vulnerabilities);
|
||||
} else {
|
||||
finalSetAttrs.damage_vulnerabilities_exist = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateDamageResistances() {
|
||||
getSetItems('resistances.updateDamageResistances', {
|
||||
collectionArray: ['damage_resistances'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.damage_resistances) {
|
||||
finalSetAttrs.damage_resistances_exist = 1;
|
||||
finalSetAttrs.damage_resistances = lowercaseDamageTypes(v.damage_resistances);
|
||||
} else {
|
||||
finalSetAttrs.damage_resistances_exist = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateDamageImmunities() {
|
||||
getSetItems('resistances.updateDamageImmunities', {
|
||||
collectionArray: ['damage_immunities'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.damage_immunities) {
|
||||
finalSetAttrs.damage_immunities_exist = 1;
|
||||
finalSetAttrs.damage_immunities = lowercaseDamageTypes(v.damage_immunities);
|
||||
} else {
|
||||
finalSetAttrs.damage_immunities_exist = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateConditionImmunities() {
|
||||
getSetItems('resistances.updateConditionImmunities', {
|
||||
collectionArray: ['condition_immunities'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.condition_immunities) {
|
||||
finalSetAttrs.condition_immunities_exist = 1;
|
||||
finalSetAttrs.condition_immunities = lowercaseDamageTypes(v.condition_immunities);
|
||||
} else {
|
||||
finalSetAttrs.condition_immunities_exist = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:damage_vulnerabilities change:damage_resistances change:damage_immunities change:condition_immunities', () => {
|
||||
this.updateDamageResistancesVar();
|
||||
});
|
||||
on('change:damage_vulnerabilities', () => {
|
||||
this.updateDamageVulnerabilities();
|
||||
});
|
||||
on('change:damage_resistances', () => {
|
||||
this.updateDamageResistances();
|
||||
});
|
||||
on('change:damage_immunities', () => {
|
||||
this.updateDamageImmunities();
|
||||
});
|
||||
on('change:condition_immunities', () => {
|
||||
this.updateConditionImmunities();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/* global on:false */
|
||||
|
||||
import { getSetItems, getIntValue, getAbilityShortName, addArithmeticOperator, isUndefinedOrEmpty, exists, showSign, getAbilityMod } from './utilities';
|
||||
import { ABILITIES } from './constants';
|
||||
|
||||
export class SavingThrows {
|
||||
getHighestOfAbilityScoresForSavingThrow(v, savingThrowName) {
|
||||
let abilityName;
|
||||
let highestValue = 0;
|
||||
for (const ability of ABILITIES) {
|
||||
const abilityMod = getIntValue(v[`${ability}_mod`]);
|
||||
if (v[`${savingThrowName}_${ability}`] === '1' && (highestValue === 0 || abilityMod > highestValue)) {
|
||||
highestValue = abilityMod;
|
||||
abilityName = ability;
|
||||
}
|
||||
}
|
||||
return abilityName;
|
||||
}
|
||||
findHighest(arr) {
|
||||
const highestAbility = Math.max.apply(Math, arr.map((ability) => ability.score));
|
||||
return arr.find((ability) => ability.score === highestAbility);
|
||||
}
|
||||
getHighestAbilityScores(v, savingThrowName) {
|
||||
const abilities = [];
|
||||
for (const ability of ABILITIES) {
|
||||
if (v[`${savingThrowName}_${ability}`] === '1') {
|
||||
abilities.push({
|
||||
name: ability,
|
||||
score: getIntValue(v[`${ability}_calculated`]),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const highestAbilities = [];
|
||||
if (abilities.length > 0) {
|
||||
const highestAbilityObj = this.findHighest(abilities);
|
||||
|
||||
highestAbilities.push(highestAbilityObj);
|
||||
abilities.splice(abilities.findIndex((ability) => ability.name === highestAbilityObj.name), 1);
|
||||
}
|
||||
if (abilities.length > 0) {
|
||||
const secondHighestAbilityObj = this.findHighest(abilities);
|
||||
highestAbilities.push(secondHighestAbilityObj);
|
||||
}
|
||||
|
||||
return highestAbilities;
|
||||
}
|
||||
getAverageOfHighestAbilityScoresForSavingThrow(v, savingThrowName) {
|
||||
const obj = {
|
||||
abilitiesUsed: [],
|
||||
};
|
||||
let sum = 0;
|
||||
|
||||
const highestAbilities = this.getHighestAbilityScores(v, savingThrowName);
|
||||
for (const ability of highestAbilities) {
|
||||
obj.abilitiesUsed.push(getAbilityShortName(ability.name));
|
||||
sum += getAbilityMod(v[`${ability.name}_calculated`]);
|
||||
}
|
||||
|
||||
if (obj.abilitiesUsed.length > 0) {
|
||||
obj.avg = Math.floor(sum / obj.abilitiesUsed.length);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
setCustomSaveProf(v, finalSetAttrs, savingThrowName) {
|
||||
const pbVar = '@{PB}';
|
||||
for (const ability of ABILITIES) {
|
||||
if (v[`${savingThrowName}_${ability}`] === '1' && v[`${ability}_save_prof`] === pbVar && !exists(v[`${savingThrowName}_save_prof`])) {
|
||||
finalSetAttrs[`${savingThrowName}_save_prof`] = pbVar;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateSavingThrow(savingThrowName) {
|
||||
const collectionArray = ['pb', `${savingThrowName}_save_prof`, `${savingThrowName}_save_bonus`, 'global_saving_throw_bonus', 'saving_throws_half_proficiency', 'average_of_abilities'];
|
||||
const customSaves = ['fortitude', 'reflex', 'will'];
|
||||
const customSavingThrow = customSaves.indexOf(savingThrowName) !== -1;
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_calculated`);
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
collectionArray.push(`${savingThrowName}_${ability}`);
|
||||
if (customSavingThrow) {
|
||||
collectionArray.push(`${ability}_save_prof`);
|
||||
}
|
||||
}
|
||||
|
||||
getSetItems('savingThrows.updateSavingThrow', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
let total = 0;
|
||||
let totalFormula = '';
|
||||
let ability;
|
||||
|
||||
if (customSavingThrow) {
|
||||
if (v.average_of_abilities === '1') {
|
||||
const obj = this.getAverageOfHighestAbilityScoresForSavingThrow(v, savingThrowName);
|
||||
|
||||
if (obj.avg) {
|
||||
total = obj.avg;
|
||||
totalFormula = `${obj.avg}[${obj.abilitiesUsed.join(' ')} avg]`;
|
||||
}
|
||||
} else {
|
||||
ability = this.getHighestOfAbilityScoresForSavingThrow(v, savingThrowName);
|
||||
}
|
||||
this.setCustomSaveProf(v, finalSetAttrs, savingThrowName);
|
||||
} else {
|
||||
ability = savingThrowName;
|
||||
}
|
||||
|
||||
if (ability) {
|
||||
const abilityMod = getIntValue(v[`${ability}_mod`]);
|
||||
total = abilityMod;
|
||||
totalFormula = `${abilityMod}[${getAbilityShortName(ability)}]`;
|
||||
}
|
||||
|
||||
const pb = getIntValue(v.pb);
|
||||
if (v[`${savingThrowName}_save_prof`] === '@{PB}') {
|
||||
total += pb;
|
||||
totalFormula += `${addArithmeticOperator(totalFormula, pb)}[proficient]`;
|
||||
} else if (v.saving_throws_half_proficiency === 'on') {
|
||||
const halfPB = Math.floor(pb / 2);
|
||||
total += halfPB;
|
||||
totalFormula += `${addArithmeticOperator(totalFormula, halfPB)}[half proficiency]`;
|
||||
}
|
||||
|
||||
const abilitySavingThrowBonus = getIntValue(v[`${savingThrowName}_save_bonus`]);
|
||||
if (abilitySavingThrowBonus) {
|
||||
total += abilitySavingThrowBonus;
|
||||
totalFormula += `${addArithmeticOperator(totalFormula, abilitySavingThrowBonus)}[${getAbilityShortName(ability)}saving throw bonus]`;
|
||||
}
|
||||
|
||||
const globalSavingThrowBonus = v.global_saving_throw_bonus;
|
||||
if (!isUndefinedOrEmpty(globalSavingThrowBonus)) {
|
||||
if (!isNaN(globalSavingThrowBonus)) {
|
||||
total += getIntValue(globalSavingThrowBonus);
|
||||
}
|
||||
totalFormula += `${addArithmeticOperator(totalFormula, globalSavingThrowBonus)}[global saving throw bonus]`;
|
||||
}
|
||||
|
||||
finalSetAttrs[`${savingThrowName}_saving_throw_mod`] = totalFormula;
|
||||
finalSetAttrs[`${savingThrowName}_saving_throw_mod_with_sign`] = showSign(total);
|
||||
},
|
||||
});
|
||||
}
|
||||
updateCustomSavingThrows() {
|
||||
this.updateSavingThrow('fortitude');
|
||||
this.updateSavingThrow('reflex');
|
||||
this.updateSavingThrow('will');
|
||||
}
|
||||
updateCustomSavingThrowToggle() {
|
||||
getSetItems('savingThrows.updateCustomSavingThrowToggle', {
|
||||
collectionArray: ['use_custom_saving_throws', 'saving_throw_macro_var_to_use'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.use_custom_saving_throws === '1') {
|
||||
finalSetAttrs.saving_throw_macro_var_to_use = '@{custom_saving_throw_macro_var}';
|
||||
} else {
|
||||
finalSetAttrs.saving_throw_macro_var_to_use = '@{saving_throw_macro_var}';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
update() {
|
||||
this.updateSavingThrow('strength');
|
||||
this.updateSavingThrow('dexterity');
|
||||
this.updateSavingThrow('constitution');
|
||||
this.updateSavingThrow('intelligence');
|
||||
this.updateSavingThrow('wisdom');
|
||||
this.updateSavingThrow('charisma');
|
||||
this.updateCustomSavingThrows();
|
||||
}
|
||||
updateFromSRD() {
|
||||
getSetItems('savingThrows.updateFromSRD', {
|
||||
collectionArray: ['saving_throws_srd'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const savingThrowsFromSRD = v.saving_throws_srd;
|
||||
const pbVar = '@{PB}';
|
||||
|
||||
if (savingThrowsFromSRD.indexOf('Str') !== -1) {
|
||||
finalSetAttrs.strength_save_prof = pbVar;
|
||||
}
|
||||
if (savingThrowsFromSRD.indexOf('Dex') !== -1) {
|
||||
finalSetAttrs.dexterity_save_prof = pbVar;
|
||||
}
|
||||
if (savingThrowsFromSRD.indexOf('Con') !== -1) {
|
||||
finalSetAttrs.constitution_save_prof = pbVar;
|
||||
}
|
||||
if (savingThrowsFromSRD.indexOf('Int') !== -1) {
|
||||
finalSetAttrs.intelligence_save_prof = pbVar;
|
||||
}
|
||||
if (savingThrowsFromSRD.indexOf('Wis') !== -1) {
|
||||
finalSetAttrs.wisdom_save_prof = pbVar;
|
||||
}
|
||||
if (savingThrowsFromSRD.indexOf('Cha') !== -1) {
|
||||
finalSetAttrs.charisma_save_prof = pbVar;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
watchForCustomSavingThrowChanges(savingThrowName) {
|
||||
const classFeatureWatch = [`change:${savingThrowName}_save_prof`, `change:${savingThrowName}_save_bonus`, 'change:average_of_abilities'];
|
||||
for (const ability of ABILITIES) {
|
||||
classFeatureWatch.push(`change:${savingThrowName}_${ability}`);
|
||||
}
|
||||
on(classFeatureWatch.join(' '), () => {
|
||||
this.updateSavingThrow(savingThrowName);
|
||||
});
|
||||
}
|
||||
watchAbilityChanges() {
|
||||
const classFeatureWatch = [];
|
||||
for (const ability of ABILITIES) {
|
||||
classFeatureWatch.push(`change:${ability}`);
|
||||
classFeatureWatch.push(`change:${ability}_mod`);
|
||||
}
|
||||
on(classFeatureWatch.join(' '), () => {
|
||||
this.updateCustomSavingThrows();
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:strength_mod change:strength_save_prof change:strength_save_bonus', () => {
|
||||
this.updateSavingThrow('strength');
|
||||
});
|
||||
on('change:dexterity_mod change:dexterity_save_prof change:dexterity_save_bonus', () => {
|
||||
this.updateSavingThrow('dexterity');
|
||||
});
|
||||
on('change:constitution_mod change:constitution_save_prof change:constitution_save_bonus', () => {
|
||||
this.updateSavingThrow('constitution');
|
||||
});
|
||||
on('change:intelligence_mod change:intelligence_save_prof change:intelligence_save_bonus', () => {
|
||||
this.updateSavingThrow('intelligence');
|
||||
});
|
||||
on('change:wisdom_mod change:wisdom_save_prof change:wisdom_save_bonus', () => {
|
||||
this.updateSavingThrow('wisdom');
|
||||
});
|
||||
on('change:charisma_mod change:charisma_save_prof change:charisma_save_bonus', () => {
|
||||
this.updateSavingThrow('charisma');
|
||||
});
|
||||
on('change:pb change:global_saving_throw_bonus change:saving_throws_half_proficiency', () => {
|
||||
this.update();
|
||||
});
|
||||
on('change:use_custom_saving_throws', () => {
|
||||
this.updateCustomSavingThrowToggle();
|
||||
});
|
||||
on('change:saving_throws_srd', () => {
|
||||
this.updateFromSRD();
|
||||
});
|
||||
this.watchForCustomSavingThrowChanges('fortitude');
|
||||
this.watchForCustomSavingThrowChanges('reflex');
|
||||
this.watchForCustomSavingThrowChanges('will');
|
||||
this.watchAbilityChanges();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/* global on:false */
|
||||
|
||||
import { getSetItems } from './utilities';
|
||||
|
||||
export class Settings {
|
||||
updateShapedD20() {
|
||||
getSetItems('settings.updateShapedD20', {
|
||||
collectionArray: ['roll_setting', 'roll_info', 'shaped_d20'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
finalSetAttrs.roll_info = '';
|
||||
finalSetAttrs.shaped_d20 = 'd20';
|
||||
|
||||
if (v.roll_setting === 'adv {{ignore=[[0') {
|
||||
finalSetAttrs.roll_info = '{{advantage=1}}';
|
||||
finalSetAttrs.shaped_d20 = '2d20@{d20_mod}kh1';
|
||||
} else if (v.roll_setting === 'dis {{ignore=[[0') {
|
||||
finalSetAttrs.roll_info = '{{disadvantage=1}}';
|
||||
finalSetAttrs.shaped_d20 = '2d20@{d20_mod}kl1';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
setup() {
|
||||
on('change:roll_setting', () => {
|
||||
this.updateShapedD20();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
/* global on:false, generateRowID:false */
|
||||
|
||||
import { ABILITIES, TOGGLE_VARS } from './constants';
|
||||
import { updateAttackToggle, updateSavingThrowToggle, updateDamageToggle, updateHealToggle, updateHigherLevelToggle } from './updateToggles';
|
||||
import { getSetItems, getSetRepeatingItems, ordinalSpellLevel, getIntValue, isUndefined, isUndefinedOrEmpty, setCritDamage, fromVOrFinalSetAttrs, lowercaseDamageTypes, getRepeatingInfo, exists } from './utilities';
|
||||
|
||||
export class Spells {
|
||||
parseSRD(v, finalSetAttrs, repeatingString) {
|
||||
if (v[`${repeatingString}spell_level_from_srd`]) {
|
||||
finalSetAttrs[`${repeatingString}spell_level`] = ordinalSpellLevel(v[`${repeatingString}spell_level_from_srd`]);
|
||||
finalSetAttrs[`${repeatingString}spell_level_from_srd`] = '';
|
||||
}
|
||||
if (v[`${repeatingString}school_from_srd`]) {
|
||||
finalSetAttrs[`${repeatingString}school`] = v[`${repeatingString}school_from_srd`].toUpperCase();
|
||||
finalSetAttrs[`${repeatingString}school_from_srd`] = '';
|
||||
}
|
||||
if (v[`${repeatingString}casting_time_from_srd`]) {
|
||||
finalSetAttrs[`${repeatingString}casting_time`] = v[`${repeatingString}casting_time_from_srd`].trim().toUpperCase().replace(/\s/g, '_');
|
||||
finalSetAttrs[`${repeatingString}casting_time_from_srd`] = '';
|
||||
}
|
||||
if (v[`${repeatingString}components_from_srd`]) {
|
||||
finalSetAttrs[`${repeatingString}components`] = `COMPONENTS_${v[`${repeatingString}components_from_srd`].trim().toUpperCase().replace(/\s/g, '_')}`;
|
||||
finalSetAttrs[`${repeatingString}components_from_srd`] = '';
|
||||
}
|
||||
if (v[`${repeatingString}duration_from_srd`]) {
|
||||
let duration = '';
|
||||
if (v[`${repeatingString}duration_from_srd`].toLowerCase().indexOf('up to') !== -1) {
|
||||
duration += 'CONCENTRATION_';
|
||||
}
|
||||
duration += v[`${repeatingString}duration_from_srd`].trim().toUpperCase().replace(/\s/g, '_');
|
||||
finalSetAttrs[`${repeatingString}duration`] = duration;
|
||||
finalSetAttrs[`${repeatingString}duration_from_srd`] = '';
|
||||
}
|
||||
if (v[`${repeatingString}saving_throw_vs_ability_from_srd`]) {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_vs_ability`] = v[`${repeatingString}saving_throw_vs_ability_from_srd`].toUpperCase();
|
||||
finalSetAttrs[`${repeatingString}saving_throw_vs_ability_from_srd`] = '';
|
||||
}
|
||||
}
|
||||
updateFromSRD() {
|
||||
getSetItems('spells.updateFromSRD', {
|
||||
collectionArray: ['spells_srd'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const spellsFromSrd = v.spells_srd.split(', ');
|
||||
|
||||
for (const spell of spellsFromSrd) {
|
||||
const repeatingString = `repeating_spell_${generateRowID()}_`;
|
||||
finalSetAttrs[`${repeatingString}name`] = spell;
|
||||
finalSetAttrs[`${repeatingString}toggle_details`] = 0;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
update(rowId) {
|
||||
const collectionArray = ['is_npc', 'pb', 'finesse_mod', 'global_spell_attack_bonus', 'global_spell_damage_bonus', 'global_spell_dc_bonus', 'global_spell_heal_bonus', 'default_ability', 'caster_level', 'base_dc'];
|
||||
for (const ability of ABILITIES) {
|
||||
collectionArray.push(`${ability}_mod`);
|
||||
}
|
||||
getSetRepeatingItems('spells.update', {
|
||||
repeatingItems: ['repeating_spell'],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['name', 'school', 'spell_level', 'spell_level_from_srd', 'school_from_srd', 'casting_time', 'casting_time_from_srd', 'components', 'components_from_srd', 'concentration', 'duration', 'duration_from_srd', 'type', 'roll_toggle', 'to_hit', 'attack_formula', 'proficiency', 'attack_ability', 'attack_bonus', 'saving_throw_toggle', 'saving_throw_ability', 'saving_throw_vs_ability', 'saving_throw_vs_ability_from_srd', 'saving_throw_bonus', 'saving_throw_dc', 'damage_toggle', 'damage_formula', 'damage', 'damage_ability', 'damage_bonus', 'damage_type', 'damage_crit', 'second_damage_toggle', 'second_damage_formula', 'second_damage', 'second_damage_ability', 'second_damage_bonus', 'second_damage_type', 'second_damage_crit', 'damage_string', 'parsed', 'heal_toggle', 'heal', 'heal_ability', 'heal_bonus', 'heal_query_toggle', 'add_casting_modifier', 'add_second_casting_modifier', 'higher_level_toggle', 'higher_level_dice', 'higher_level_die', 'second_higher_level_dice', 'second_higher_level_die', 'higher_level_heal', 'ritual', 'ritual_output', 'materials', 'materials_show', 'extras_toggle', 'emote', 'freetext', 'freeform'],
|
||||
rowId,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
this.parseSRD(v, finalSetAttrs, repeatingString);
|
||||
|
||||
if (v[`${repeatingString}spell_level`] === 'CANTRIP') {
|
||||
finalSetAttrs[`${repeatingString}is_prepared`] = 'on';
|
||||
}
|
||||
|
||||
if (!isUndefined(fromVOrFinalSetAttrs(v, finalSetAttrs, `${repeatingString}duration`)) && fromVOrFinalSetAttrs(v, finalSetAttrs, `${repeatingString}duration`).indexOf('CONCENTRATION') !== -1) {
|
||||
finalSetAttrs[`${repeatingString}concentration`] = 'Yes';
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}concentration`] = '';
|
||||
}
|
||||
if (v[`${repeatingString}ritual`] === 'Yes') {
|
||||
finalSetAttrs[`${repeatingString}ritual_output`] = '?{Cast as|Ritual,{{ritual=1}}|Spell,}';
|
||||
} else {
|
||||
finalSetAttrs[`${repeatingString}ritual_output`] = '';
|
||||
}
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}materials`])) {
|
||||
finalSetAttrs[`${repeatingString}materials_show`] = 1;
|
||||
} else if (!isUndefinedOrEmpty(v[`${repeatingString}materials_show`])) {
|
||||
finalSetAttrs[`${repeatingString}materials_show`] = 0;
|
||||
}
|
||||
|
||||
const attackOptions = {
|
||||
attackAbility: true,
|
||||
globalAttackBonus: v.global_spell_attack_bonus,
|
||||
globalAttackBonusLabel: 'global spell attack bonus',
|
||||
type: 'spell',
|
||||
};
|
||||
updateAttackToggle(v, finalSetAttrs, repeatingString, attackOptions);
|
||||
|
||||
const savingThrowOptions = {
|
||||
bonusDC: v.global_spell_dc_bonus,
|
||||
};
|
||||
updateSavingThrowToggle(v, finalSetAttrs, repeatingString, savingThrowOptions);
|
||||
|
||||
const damageOptions = {
|
||||
globalDamageBonus: v.global_spell_damage_bonus,
|
||||
globalDamageBonusLabel: 'global spell damage bonus',
|
||||
type: 'spell',
|
||||
};
|
||||
updateDamageToggle(v, finalSetAttrs, repeatingString, damageOptions);
|
||||
if (v.damage_type) {
|
||||
finalSetAttrs.damage_type = lowercaseDamageTypes(v.damage_type);
|
||||
}
|
||||
if (v.second_damage_type) {
|
||||
finalSetAttrs.second_damage_type = lowercaseDamageTypes(v.second_damage_type);
|
||||
}
|
||||
setCritDamage(v, finalSetAttrs, repeatingString);
|
||||
|
||||
if (getIntValue(v.is_npc) === 1 && v.caster_level && v[`${repeatingString}damage`] && v[`${repeatingString}damage`].indexOf('@{level}') !== -1) {
|
||||
finalSetAttrs[`${repeatingString}damage`] = v[`${repeatingString}damage`].replace('@{level}', '@{caster_level}');
|
||||
}
|
||||
|
||||
updateHealToggle(v, finalSetAttrs, repeatingString);
|
||||
|
||||
updateHigherLevelToggle(v, finalSetAttrs, repeatingString);
|
||||
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}extras_toggle`]) && (v[`${repeatingString}emote`] || v[`${repeatingString}freetext`] || v[`${repeatingString}freeform`])) {
|
||||
finalSetAttrs[`${repeatingString}extras_toggle`] = TOGGLE_VARS.extras;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateSlots() {
|
||||
const collectionArray = ['caster_level', 'caster_type'];
|
||||
const spellSlots = {
|
||||
1: 0,
|
||||
2: 0,
|
||||
3: 0,
|
||||
4: 0,
|
||||
5: 0,
|
||||
6: 0,
|
||||
7: 0,
|
||||
8: 0,
|
||||
9: 0,
|
||||
};
|
||||
for (const level in spellSlots) {
|
||||
if (spellSlots.hasOwnProperty(level)) {
|
||||
const repeatingString = `spell_slots_l${level}`;
|
||||
collectionArray.push(`${repeatingString}_calc`);
|
||||
collectionArray.push(`${repeatingString}_bonus`);
|
||||
collectionArray.push(`${repeatingString}_max`);
|
||||
collectionArray.push(`${repeatingString}_toggle`);
|
||||
}
|
||||
}
|
||||
|
||||
getSetItems('spells.updateSlots', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const casterLevel = getIntValue(v.caster_level);
|
||||
const casterType = v.caster_type;
|
||||
|
||||
if (casterType === 'full') {
|
||||
if (casterLevel >= 3) {
|
||||
spellSlots[1] = 4;
|
||||
} else if (casterLevel === 2) {
|
||||
spellSlots[1] = 3;
|
||||
} else if (casterLevel === 1) {
|
||||
spellSlots[1] = 2;
|
||||
}
|
||||
if (casterLevel >= 4) {
|
||||
spellSlots[2] = 3;
|
||||
} else if (casterLevel === 3) {
|
||||
spellSlots[2] = 2;
|
||||
}
|
||||
if (casterLevel >= 6) {
|
||||
spellSlots[3] = 3;
|
||||
} else if (casterLevel === 5) {
|
||||
spellSlots[3] = 2;
|
||||
}
|
||||
if (casterLevel >= 9) {
|
||||
spellSlots[4] = 3;
|
||||
} else if (casterLevel === 8) {
|
||||
spellSlots[4] = 2;
|
||||
} else if (casterLevel === 7) {
|
||||
spellSlots[4] = 1;
|
||||
}
|
||||
if (casterLevel >= 18) {
|
||||
spellSlots[5] = 3;
|
||||
} else if (casterLevel >= 10) {
|
||||
spellSlots[5] = 2;
|
||||
} else if (casterLevel === 9) {
|
||||
spellSlots[5] = 1;
|
||||
}
|
||||
if (casterLevel >= 19) {
|
||||
spellSlots[6] = 2;
|
||||
} else if (casterLevel >= 11) {
|
||||
spellSlots[6] = 1;
|
||||
}
|
||||
if (casterLevel >= 20) {
|
||||
spellSlots[7] = 2;
|
||||
} else if (casterLevel >= 13) {
|
||||
spellSlots[7] = 1;
|
||||
}
|
||||
if (casterLevel >= 15) {
|
||||
spellSlots[8] = 1;
|
||||
}
|
||||
if (casterLevel >= 17) {
|
||||
spellSlots[9] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (casterType === 'half') {
|
||||
if (casterLevel >= 5) {
|
||||
spellSlots[1] = 4;
|
||||
} else if (casterLevel >= 3) {
|
||||
spellSlots[1] = 3;
|
||||
} else if (casterLevel === 2) {
|
||||
spellSlots[1] = 2;
|
||||
}
|
||||
if (casterLevel >= 7) {
|
||||
spellSlots[2] = 3;
|
||||
} else if (casterLevel >= 5) {
|
||||
spellSlots[2] = 2;
|
||||
}
|
||||
if (casterLevel >= 11) {
|
||||
spellSlots[3] = 3;
|
||||
} else if (casterLevel >= 9) {
|
||||
spellSlots[3] = 2;
|
||||
}
|
||||
if (casterLevel >= 17) {
|
||||
spellSlots[4] = 3;
|
||||
} else if (casterLevel >= 15) {
|
||||
spellSlots[4] = 2;
|
||||
} else if (casterLevel >= 13) {
|
||||
spellSlots[4] = 1;
|
||||
}
|
||||
if (casterLevel >= 19) {
|
||||
spellSlots[5] = 2;
|
||||
} else if (casterLevel >= 17) {
|
||||
spellSlots[5] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (casterType === 'third') {
|
||||
if (casterLevel >= 7) {
|
||||
spellSlots[1] = 4;
|
||||
} else if (casterLevel >= 4) {
|
||||
spellSlots[1] = 3;
|
||||
} else if (casterLevel === 3) {
|
||||
spellSlots[1] = 2;
|
||||
}
|
||||
if (casterLevel >= 10) {
|
||||
spellSlots[2] = 3;
|
||||
} else if (casterLevel >= 7) {
|
||||
spellSlots[2] = 2;
|
||||
}
|
||||
if (casterLevel >= 16) {
|
||||
spellSlots[3] = 3;
|
||||
} else if (casterLevel >= 13) {
|
||||
spellSlots[3] = 2;
|
||||
}
|
||||
if (casterLevel >= 19) {
|
||||
spellSlots[4] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (const level in spellSlots) {
|
||||
if (spellSlots.hasOwnProperty(level)) {
|
||||
const repeatingString = `spell_slots_l${level}`;
|
||||
finalSetAttrs[repeatingString] = 0;
|
||||
if (spellSlots[level] !== 0 || exists(v[`${repeatingString}_calc`])) {
|
||||
finalSetAttrs[`spell_slots_l${level}_calc`] = spellSlots[level];
|
||||
}
|
||||
|
||||
const slots = v[`${repeatingString}`];
|
||||
const slotBonus = getIntValue(v[`${repeatingString}_bonus`]);
|
||||
const spellSlotMax = spellSlots[level] + slotBonus;
|
||||
|
||||
if (spellSlotMax > 0) {
|
||||
finalSetAttrs[`${repeatingString}_max`] = spellSlotMax;
|
||||
if (isUndefinedOrEmpty(slots)) {
|
||||
finalSetAttrs[repeatingString] = spellSlotMax;
|
||||
}
|
||||
} else {
|
||||
if (exists(v[`${repeatingString}_max`])) {
|
||||
finalSetAttrs[`${repeatingString}_max`] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateShowHide() {
|
||||
const collectionArray = ['spells_show_spell_level_if_all_slots_are_used'];
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
collectionArray.push(`spell_slots_l${i}`);
|
||||
collectionArray.push(`spell_slots_l${i}_max`);
|
||||
collectionArray.push(`spell_slots_l${i}_toggle`);
|
||||
collectionArray.push(`spells_level_${i}_macro_var`);
|
||||
collectionArray.push(`spells_level_${i}_show`);
|
||||
}
|
||||
|
||||
getSetItems('spells.updateShowHide', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
const showLevelIfAllSlotsAreUsed = isUndefinedOrEmpty(v.spells_show_spell_level_if_all_slots_are_used) || v.spells_show_spell_level_if_all_slots_are_used === 'on';
|
||||
|
||||
for (let level = 0; level <= 9; level++) {
|
||||
if (v[`spells_level_${level}_macro_var`] || getIntValue(v[`spell_slots_l${level}`]) || getIntValue(v[`spell_slots_l${level}_max`])) {
|
||||
finalSetAttrs[`spell_slots_l${level}_toggle`] = 'on';
|
||||
} else {
|
||||
finalSetAttrs[`spell_slots_l${level}_toggle`] = 0;
|
||||
}
|
||||
|
||||
const hasSlots = getIntValue(v[`spell_slots_l${level}`]);
|
||||
const hasSpells = v[`spells_level_${level}_macro_var`];
|
||||
|
||||
if ((hasSlots || showLevelIfAllSlotsAreUsed) && (hasSlots || hasSpells)) {
|
||||
finalSetAttrs[`spells_level_${level}_show`] = true;
|
||||
} else {
|
||||
finalSetAttrs[`spells_level_${level}_show`] = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
updateChatMacro() {
|
||||
const spellSlots = {
|
||||
0: [],
|
||||
1: [],
|
||||
2: [],
|
||||
3: [],
|
||||
4: [],
|
||||
5: [],
|
||||
6: [],
|
||||
7: [],
|
||||
8: [],
|
||||
9: [],
|
||||
};
|
||||
|
||||
const collectionArray = ['spells_show_unprepared'];
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
collectionArray.push(`spells_level_${0}_macro_var`);
|
||||
}
|
||||
getSetRepeatingItems('spells.updateChatMacro', {
|
||||
repeatingItems: ['repeating_spell'],
|
||||
collectionArray,
|
||||
collectionArrayAddItems: ['name', 'spell_level', 'is_prepared'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
const showUnprepared = v.spells_show_unprepared === 'on' || isUndefinedOrEmpty(v.spells_show_unprepared);
|
||||
const spellName = v[`${repeatingString}name`];
|
||||
const spellLevel = getIntValue(v[`${repeatingString}spell_level`], 0);
|
||||
const spellPrepared = v[`${repeatingString}is_prepared`] === 'on';
|
||||
|
||||
if (spellName && spellPrepared) {
|
||||
spellSlots[spellLevel].push(`[${spellName}](~repeating_spell_${id}_spell)`);
|
||||
} else if (spellName && showUnprepared) {
|
||||
spellSlots[spellLevel].push(`<span class="sheet-unprepared">[${spellName}](~repeating_spell_${id}_spell)</span>`);
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
if (spellSlots[i].length > 0) {
|
||||
finalSetAttrs[`spells_level_${i}_macro_var`] = spellSlots[i].join(', ');
|
||||
} else {
|
||||
finalSetAttrs[`spells_level_${i}_macro_var`] = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
generateHigherLevelQueries() {
|
||||
const collectionArray = ['warlock_level', 'number_of_classes'];
|
||||
for (let i = 1; i <= 8; i++) {
|
||||
collectionArray.push(`cast_as_level_${i}`);
|
||||
collectionArray.push(`higher_level_query_${i}`);
|
||||
}
|
||||
for (let i = 1; i <= 9; i++) {
|
||||
collectionArray.push(`spell_slots_l${i}`);
|
||||
}
|
||||
|
||||
getSetItems('spells.generateHigherLevelQueries', {
|
||||
collectionArray,
|
||||
callback: (v, finalSetAttrs) => {
|
||||
for (let i = 1; i <= 8; i++) {
|
||||
let higherLevelQuery = '';
|
||||
|
||||
if (i < 6 && v.number_of_classes === 1 && v.warlock_level > 0 && Math.ceil(getIntValue(v.warlock_level) / 2) >= i) {
|
||||
let spellLevel = 1;
|
||||
if (v.warlock_level >= 9) {
|
||||
spellLevel = 5;
|
||||
} else if (v.warlock_level >= 7) {
|
||||
spellLevel = 4;
|
||||
} else if (v.warlock_level >= 5) {
|
||||
spellLevel = 3;
|
||||
} else if (v.warlock_level >= 3) {
|
||||
spellLevel = 2;
|
||||
}
|
||||
higherLevelQuery = spellLevel;
|
||||
} else {
|
||||
let levelQuery = '';
|
||||
for (let j = i; j <= 9; j++) {
|
||||
if (getIntValue(v[`spell_slots_l${j}`])) {
|
||||
levelQuery += `|${j}`;
|
||||
}
|
||||
}
|
||||
higherLevelQuery = `?{Spell Level${levelQuery}}`;
|
||||
}
|
||||
if (higherLevelQuery !== '') {
|
||||
finalSetAttrs[`higher_level_query_${i}`] = higherLevelQuery;
|
||||
} else {
|
||||
finalSetAttrs[`higher_level_query_${i}`] = i;
|
||||
}
|
||||
if (v[`spell_slots_l${i}`] === '0' && higherLevelQuery !== i) {
|
||||
finalSetAttrs[`cast_as_level_${i}`] = higherLevelQuery;
|
||||
} else {
|
||||
finalSetAttrs[`cast_as_level_${i}`] = '';
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
watchForChanges() {
|
||||
const spellsWatch = ['change:spells_show_spell_level_if_all_slots_are_used'];
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
spellsWatch.push(`change:spells_level_${i}_macro_var`);
|
||||
spellsWatch.push(`change:spell_slots_l${i}`);
|
||||
spellsWatch.push(`change:spell_slots_l${i}_max`);
|
||||
}
|
||||
on(spellsWatch.join(' '), () => {
|
||||
this.updateShowHide();
|
||||
});
|
||||
}
|
||||
setup() {
|
||||
on('change:repeating_spell', (eventInfo) => {
|
||||
const repeatingInfo = getRepeatingInfo('repeating_spell', eventInfo);
|
||||
if (repeatingInfo && repeatingInfo.field !== 'roll_toggle' && repeatingInfo.field !== 'toggle_details' && repeatingInfo.field !== 'to_hit' && repeatingInfo.field !== 'attack_formula' && repeatingInfo.field !== 'damage_formula' && repeatingInfo.field !== 'damage_crit' && repeatingInfo.field !== 'second_damage_formula' && repeatingInfo.field !== 'second_damage_crit' && repeatingInfo.field !== 'damage_string' && repeatingInfo.field !== 'saving_throw_dc' && repeatingInfo.field !== 'heal_formula' && repeatingInfo.field !== 'higher_level_query' && repeatingInfo.field !== 'parsed') {
|
||||
this.update(repeatingInfo.rowId);
|
||||
}
|
||||
});
|
||||
on('change:pb change:global_spell_attack_bonus change:global_spell_damage_bonus change:global_spell_dc_bonus change:global_spell_heal_bonus', () => {
|
||||
this.update();
|
||||
});
|
||||
on('change:spells_srd', () => {
|
||||
this.updateFromSRD();
|
||||
});
|
||||
on('change:spell_slots_l1_bonus change:spell_slots_l2_bonus change:spell_slots_l3_bonus change:spell_slots_l4_bonus change:spell_slots_l5_bonus change:spell_slots_l6_bonus change:spell_slots_l7_bonus change:spell_slots_l8_bonus change:spell_slots_l9_bonus', () => {
|
||||
this.updateSlots();
|
||||
});
|
||||
this.watchForChanges();
|
||||
on('change:repeating_spell', (eventInfo) => {
|
||||
const repeatingInfo = getRepeatingInfo('repeating_spell', eventInfo);
|
||||
if (repeatingInfo && (repeatingInfo.field === 'name' || repeatingInfo.field === 'spell_level' || repeatingInfo.field === 'is_prepared')) {
|
||||
this.updateChatMacro();
|
||||
}
|
||||
});
|
||||
on('change:spells_show_unprepared remove:repeating_spell', () => {
|
||||
this.updateChatMacro();
|
||||
});
|
||||
on('change:warlock_level change:spell_slots_l1 change:spell_slots_l2 change:spell_slots_l3 change:spell_slots_l4 change:spell_slots_l5 change:spell_slots_l6 change:spell_slots_l7 change:spell_slots_l8 change:spell_slots_l9', () => {
|
||||
this.generateHigherLevelQueries();
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/* global generateRowID:falsee */
|
||||
|
||||
import { TOGGLE_VARS } from './constants';
|
||||
import { getSetRepeatingItems, isUndefinedOrEmpty } from './utilities';
|
||||
|
||||
export class Traits {
|
||||
calculatePercentDifference(oldValue, newValue) {
|
||||
return Math.abs(((oldValue - newValue) / oldValue) * 100);
|
||||
}
|
||||
set(obj) {
|
||||
if (!obj.name) {
|
||||
obj.name = obj.storageName;
|
||||
}
|
||||
const collectionArrayAddItems = ['storage_name', 'name', 'uses', 'freetext', 'saving_throw_toggle', 'damage_toggle', 'heal_toggle', 'extras_toggle', 'display_text'];
|
||||
for (const prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
collectionArrayAddItems.push(prop);
|
||||
}
|
||||
}
|
||||
let itemId;
|
||||
let repeatingString;
|
||||
|
||||
getSetRepeatingItems('traits.set', {
|
||||
repeatingItems: ['repeating_trait'],
|
||||
collectionArrayAddItems,
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
if (v[`${repeatingString}storage_name`] === obj.storageName) {
|
||||
itemId = id;
|
||||
}
|
||||
}
|
||||
if (!itemId) {
|
||||
itemId = generateRowID();
|
||||
}
|
||||
|
||||
repeatingString = `${repeatingItem}_${itemId}_`;
|
||||
if (!obj.clear && isUndefinedOrEmpty(v[`${repeatingString}storage_name`])) {
|
||||
finalSetAttrs[`${repeatingString}storage_name`] = obj.storageName;
|
||||
}
|
||||
if (!obj.clear && v[`${repeatingString}name`] !== obj.name) {
|
||||
finalSetAttrs[`${repeatingString}name`] = obj.name;
|
||||
}
|
||||
delete obj.storageName;
|
||||
|
||||
if (obj.clear) {
|
||||
delete obj.clear;
|
||||
for (const prop in obj) {
|
||||
if (obj.hasOwnProperty(prop) && !isUndefinedOrEmpty(v[`${repeatingString}${prop}`])) {
|
||||
finalSetAttrs[`${repeatingString}${prop}`] = obj[prop];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
if ((prop === 'name' || prop === 'freetext') && (isUndefinedOrEmpty(v[`${repeatingString}${prop}`]) || this.calculatePercentDifference(v[`${repeatingString}${prop}`].length, obj[prop].length) < 10)) {
|
||||
finalSetAttrs[`${repeatingString}${prop}`] = obj[prop];
|
||||
} else if (v[`${repeatingString}${prop}`] !== obj[prop]) {
|
||||
finalSetAttrs[`${repeatingString}${prop}`] = obj[prop];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (obj.type && isUndefinedOrEmpty(v[`${repeatingString}type`])) {
|
||||
finalSetAttrs[`${repeatingString}type`] = obj.type;
|
||||
}
|
||||
if (obj.saving_throw_ability || obj.saving_throw_bonus || obj.saving_throw_vs_ability) {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_toggle`] = TOGGLE_VARS.saving_throw;
|
||||
}
|
||||
if (obj.damage || obj.damage_ability || obj.damage_bonus) {
|
||||
finalSetAttrs[`${repeatingString}damage_toggle`] = TOGGLE_VARS.damage;
|
||||
}
|
||||
if (obj.heal || obj.heal_ability || obj.heal_bonus || obj.heal_query_toggle) {
|
||||
finalSetAttrs[`${repeatingString}heal_toggle`] = TOGGLE_VARS.heal;
|
||||
}
|
||||
if (obj.freetext && isUndefinedOrEmpty(v[`${repeatingString}extras_toggle`])) {
|
||||
finalSetAttrs[`${repeatingString}extras_toggle`] = TOGGLE_VARS.extras;
|
||||
}
|
||||
if (obj.uses_max && !obj.uses && isUndefinedOrEmpty(v[`${repeatingString}uses`])) {
|
||||
finalSetAttrs[`${repeatingString}uses`] = obj.uses_max;
|
||||
}
|
||||
if (obj.freetext && repeatingItem === 'repeating_trait' && (isUndefinedOrEmpty(v[`${repeatingString}display_text`]) ||
|
||||
this.calculatePercentDifference(v[`${repeatingString}display_text`].length, obj.freetext.length) < 10)) {
|
||||
finalSetAttrs[`${repeatingString}display_text`] = obj.freetext;
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}toggle_details`] = 0;
|
||||
}
|
||||
},
|
||||
returnCallback: () => {
|
||||
return itemId;
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,599 @@
|
||||
/* global on:false, generateRowID:false */
|
||||
|
||||
import { Abilities } from './Abilities';
|
||||
const abilities = new Abilities();
|
||||
import { AbilityChecks } from './AbilityChecks';
|
||||
const abilityChecks = new AbilityChecks();
|
||||
import { Actions } from './Actions';
|
||||
const actions = new Actions();
|
||||
import { Attachers } from './Attachers';
|
||||
const attachers = new Attachers();
|
||||
import { Attacks } from './Attacks';
|
||||
const attacks = new Attacks();
|
||||
import { Character } from './Character';
|
||||
const character = new Character();
|
||||
import { ClassFeatures } from './ClassFeatures';
|
||||
const classFeatures = new ClassFeatures();
|
||||
import { TOGGLE_VARS } from './constants';
|
||||
import { Equipment } from './Equipment';
|
||||
const equipment = new Equipment();
|
||||
import { Npc } from './Npc';
|
||||
const npc = new Npc();
|
||||
import { Resistances } from './Resistances';
|
||||
const resistances = new Resistances();
|
||||
import { SavingThrows } from './SavingThrows';
|
||||
const savingThrows = new SavingThrows();
|
||||
import { Settings } from './Settings';
|
||||
const settings = new Settings();
|
||||
import { Spells } from './Spells';
|
||||
const spells = new Spells();
|
||||
import { isUndefined, isUndefinedOrEmpty, getAbilityName, ordinalSpellLevel, getSetItems, getSetRepeatingItems } from './utilities';
|
||||
import { currentVersion } from './version';
|
||||
|
||||
export class Upgrade {
|
||||
extasToExtrasFix(repeatingSection) {
|
||||
getSetRepeatingItems('upgrade.extasToExtrasFix', {
|
||||
repeatingItems: [repeatingSection],
|
||||
collectionArrayAddItems: ['extas_toggle'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}extas_toggle`])) {
|
||||
finalSetAttrs[`${repeatingString}extras_toggle`] = v[`${repeatingString}extas_toggle`];
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
armorPlusDexRemoval() {
|
||||
getSetRepeatingItems('upgrade.armorPlusDexRemoval', {
|
||||
repeatingItems: ['repeating_armor'],
|
||||
collectionArrayAddItems: ['type'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
const armorType = v[`${repeatingString}type`];
|
||||
if (armorType === 'Armor + Dex') {
|
||||
finalSetAttrs[`${repeatingString}type`] = 'Light Armor';
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
fixRollTwo() {
|
||||
getSetItems('upgrade.fixRollTwo', {
|
||||
collectionArray: ['roll_setting'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (v.roll_setting === '@{attr_roll_2}') {
|
||||
finalSetAttrs.roll_setting = '{{roll2=[[d20@{d20_mod}';
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
defaultAbility() {
|
||||
getSetItems('upgrade.defaultAbility', {
|
||||
collectionArray: ['default_ability'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (!isUndefinedOrEmpty(v.default_ability)) {
|
||||
finalSetAttrs.default_ability = getAbilityName(v.default_ability);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
hideFreetext() {
|
||||
getSetItems('upgrade.hideFreetext', {
|
||||
collectionArray: ['hide_freetext', 'hide_action_freetext'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (!isUndefinedOrEmpty(v.hide_action_freetext)) {
|
||||
finalSetAttrs.hide_freetext = v.hide_action_freetext;
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
atSyntaxToAbilityName(v, finalSetAttrs, repeatingString, field) {
|
||||
if (v[`${repeatingString}${field}`]) {
|
||||
finalSetAttrs[`${repeatingString}${field}`] = getAbilityName(v[`${repeatingString}${field}`]);
|
||||
}
|
||||
}
|
||||
skillAbility() {
|
||||
getSetRepeatingItems('upgrade.skillAbility', {
|
||||
repeatingItems: ['repeating_skill'],
|
||||
collectionArrayAddItems: ['ability'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
this.atSyntaxToAbilityName(v, finalSetAttrs, repeatingString, 'ability');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
armorAbility() {
|
||||
getSetItems('upgrade.armorAbility', {
|
||||
collectionArray: ['ac_unarmored_ability'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
if (!isUndefinedOrEmpty(v.ac_unarmored_ability)) {
|
||||
finalSetAttrs.ac_unarmored_ability = getAbilityName(v.ac_unarmored_ability);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
actionComponents() {
|
||||
getSetRepeatingItems('upgrade.actionComponents', {
|
||||
repeatingItems: ['repeating_attack', 'repeating_spell', 'repeating_trait', 'repeating_action', 'repeating_reaction', 'repeating_legendaryaction', 'repeating_lairaction', 'repeating_regionaleffect'],
|
||||
collectionArrayAddItems: ['attack_ability', 'damage_ability', 'second_damage_ability', 'heal_ability', 'saving_throw_ability', 'saving_throw_vs_ability'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
this.atSyntaxToAbilityName(v, finalSetAttrs, repeatingString, 'attack_ability');
|
||||
this.atSyntaxToAbilityName(v, finalSetAttrs, repeatingString, 'damage_ability');
|
||||
this.atSyntaxToAbilityName(v, finalSetAttrs, repeatingString, 'second_damage_ability');
|
||||
this.atSyntaxToAbilityName(v, finalSetAttrs, repeatingString, 'heal_ability');
|
||||
this.atSyntaxToAbilityName(v, finalSetAttrs, repeatingString, 'saving_throw_ability');
|
||||
|
||||
if (v[`${repeatingString}saving_throw_vs_ability`]) {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_vs_ability`] = v[`${repeatingString}saving_throw_vs_ability`].toUpperCase();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
newAttackToggle() {
|
||||
getSetRepeatingItems('upgrade.newAttackToggle', {
|
||||
repeatingItems: ['repeating_attack', 'repeating_spell', 'repeating_action', 'repeating_reaction', 'repeating_legendaryaction', 'repeating_lairaction', 'repeating_regionaleffect'],
|
||||
collectionArrayAddItems: ['roll_toggle'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (v[`${repeatingString}roll_toggle`] === '{{vs_ac=1}} @{roll_info} {{roll1=[[@{shaped_d20}cs>@{crit_range} + @{attack_formula}]]}} @{roll_setting}cs>@{crit_range} + @{attack_formula}]]}} {{targetAC=@{attacks_vs_target_ac}}} {{targetName=@{attacks_vs_target_name}}}') {
|
||||
finalSetAttrs[`${repeatingString}roll_toggle`] = TOGGLE_VARS.roll;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
newAttackToggleTwo() {
|
||||
getSetRepeatingItems('upgrade.newAttackToggleTwo', {
|
||||
repeatingItems: ['repeating_attack', 'repeating_spell', 'repeating_action', 'repeating_reaction', 'repeating_legendaryaction', 'repeating_lairaction', 'repeating_regionaleffect'],
|
||||
collectionArrayAddItems: ['roll_toggle'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (v[`${repeatingString}roll_toggle`].indexOf('vs_saving_throw') !== -1) {
|
||||
finalSetAttrs[`${repeatingString}roll_toggle`] = TOGGLE_VARS.roll;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
newAbilityDefaults() {
|
||||
getSetRepeatingItems('upgrade.newAbilityDefaults', {
|
||||
repeatingItems: ['repeating_attack', 'repeating_action', 'repeating_reaction', 'repeating_legendaryaction', 'repeating_lairaction', 'repeating_regionaleffect'],
|
||||
collectionArrayAddItems: ['roll_toggle', 'roll_ability', 'damage_toggle', 'damage_ability'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}roll_toggle`]) && isUndefined(v[`${repeatingString}roll_ability`])) {
|
||||
finalSetAttrs[`${repeatingString}roll_ability`] = 'strength';
|
||||
}
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}damage_toggle`]) && isUndefined(v[`${repeatingString}damage_ability`])) {
|
||||
finalSetAttrs[`${repeatingString}damage_ability`] = 'strength';
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
changeOldToggleToNew(v, finalSetAttrs, field, oldValue, newValue) {
|
||||
if (v[field] === `@{${oldValue}}`) {
|
||||
finalSetAttrs[field] = newValue;
|
||||
}
|
||||
}
|
||||
removeToggleVar() {
|
||||
getSetItems('upgrade.removeToggleVar', {
|
||||
collectionArray: ['careful_spell_toggle', 'distant_spell_toggle', 'empowered_spell_toggle', 'extended_spell_toggle', 'heightened_spell_toggle', 'quickened_spell_toggle', 'subtle_spell_toggle', 'twinned_spell_toggle', 'initiative_tie_breaker', 'ammo_auto_use', 'hide_attack', 'hide_damage', 'hide_saving_throw_dc', 'hide_spell_content', 'hide_action_freetext', 'hide_saving_throw_failure', 'hide_saving_throw_success', 'hide_recharge', 'initiative_output_option', 'output_option', 'death_save_output_option', 'hit_dice_output_option', 'roll_setting', 'show_character_name', 'attacks_vs_target_ac', 'attacks_vs_target_name', 'initiative_roll', 'initiative_to_tracker'],
|
||||
callback: (v, finalSetAttrs) => {
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'careful_spell_toggle', 'careful_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'distant_spell_toggle', 'distant_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'empowered_spell_toggle', 'empowered_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'extended_spell_toggle', 'extended_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'heightened_spell_toggle', 'heightened_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'quickened_spell_toggle', 'quickened_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'subtle_spell_toggle', 'subtle_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'twinned_spell_toggle', 'twinned_spell_toggle_var', '1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_tie_breaker', 'initiative_tie_breaker_var', '[[@{initiative} / 100]][tie breaker]');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'ammo_auto_use', 'ammo_auto_use_var', '1');
|
||||
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_attack', 'hide_attack_var', '{{hide_attack=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_damage', 'hide_damage_var', '{{hide_damage=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_saving_throw_dc', 'hide_saving_throw_dc_var', '{{hide_saving_throw_dc=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_spell_content', 'hide_spell_content_var', '{{hide_spell_content=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_action_freetext', 'hide_action_freetext_var', '{{hide_freetext=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_saving_throw_failure', 'hide_saving_throw_failure_var', '{{hide_saving_throw_failure=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_saving_throw_success', 'hide_saving_throw_success_var', '{{hide_saving_throw_success=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hide_recharge', 'hide_recharge_var', '{{hide_recharge=1}}');
|
||||
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_output_option', 'output_to_all', '');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_output_option', 'output_to_gm', '/w GM');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'output_option', 'output_to_all', '');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'output_option', 'output_to_gm', '/w GM');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'death_save_output_option', 'output_to_all', '');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'death_save_output_option', 'output_to_gm', '/w GM');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hit_dice_output_option', 'output_to_all', '');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'hit_dice_output_option', 'output_to_gm', '/w GM');
|
||||
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'roll_setting', 'roll_advantage', 'adv {{ignore=[[0');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'roll_setting', 'roll_disadvantage', 'dis {{ignore=[[0');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'roll_setting', 'roll_1', '{{ignore=[[0');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'roll_setting', 'roll_2', '{{roll2=[[d20@{d20_mod}');
|
||||
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'show_character_name', 'show_character_name_no', '');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'show_character_name', 'show_character_name_yes', '{{show_character_name=1}}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'attacks_vs_target_ac', 'attacks_vs_target_ac_no', '');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'attacks_vs_target_ac', 'attacks_vs_target_ac_yes', '[[@{target|AC}]]');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'attacks_vs_target_name', 'attacks_vs_target_name_no', '');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'attacks_vs_target_name', 'attacks_vs_target_name_yes', '@{target|token_name}');
|
||||
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_roll', 'normal_initiative', '@{shaped_d20}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_roll', 'advantage_on_initiative', '2d20@{d20_mod}kh1');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_roll', 'disadvantage_on_initiative', '2d20@{d20_mod}kl1');
|
||||
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_to_tracker', 'initiative_to_tracker_yes', '@{selected|initiative_formula} &{tracker}');
|
||||
this.changeOldToggleToNew(v, finalSetAttrs, 'initiative_to_tracker', 'initiative_to_tracker_no', '@{initiative_formula}');
|
||||
},
|
||||
});
|
||||
}
|
||||
changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, field, oldValue, newValue) {
|
||||
if (v[`${repeatingString}${field}`] === `@{${oldValue}}`) {
|
||||
finalSetAttrs[`${repeatingString}${field}`] = newValue;
|
||||
}
|
||||
}
|
||||
actionComponentsToRemoveExtraFields() {
|
||||
getSetRepeatingItems('upgrade.actionComponentsToRemoveExtraFields', {
|
||||
repeatingItems: ['repeating_attack', 'repeating_spell', 'repeating_trait', 'repeating_action', 'repeating_reaction', 'repeating_legendaryaction', 'repeating_lairaction', 'repeating_regionaleffect'],
|
||||
collectionArrayAddItems: ['roll_toggle', 'content_toggle', 'saving_throw_toggle', 'damage_toggle', 'second_damage_toggle', 'extras_toggle', 'heal_toggle', 'heal_query_toggle', 'higher_level_toggle', 'special_effects_toggle'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'roll_toggle', 'roll_toggle_var', '{{vs_ac=1}} @{roll_info} {{roll1=[[@{shaped_d20}cs>@{crit_range} + @{attack_formula}]]}} @{roll_setting}cs>@{crit_range} + @{attack_formula}]]}} {{targetAC=@{attacks_vs_target_ac}}} {{targetName=@{attacks_vs_target_name}}}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'content_toggle', 'content_toggle_var', '{{content=@{content}}}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'saving_throw_toggle', 'saving_throw_toggle_var', '{{saving_throw_condition=@{saving_throw_condition}}} {{saving_throw_dc=@{saving_throw_dc}}} {{saving_throw_vs_ability=@{saving_throw_vs_ability}}} {{saving_throw_failure=@{saving_throw_failure}}} {{saving_throw_success=@{saving_throw_success}}} {{targetName=@{attacks_vs_target_name}}}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'damage_toggle', 'damage_toggle_var', '{{damage=[[@{damage_formula}]]}} {{damage_type=@{damage_type}}} {{crit_damage=[[0d0 + @{damage_crit}[crit damage] @{damage_crit_formula}]]}}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'second_damage_toggle', 'second_damage_toggle_var', '{{second_damage=[[@{second_damage_formula}]]}} {{second_damage_type=@{second_damage_type}}} {{second_crit_damage=[[0d0 + @{second_damage_crit}[crit damage] @{second_damage_crit_formula}]]}}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'extras_toggle', 'extras_var', '{{emote=@{emote}}} {{freetext=@{freetext}}} @{freeform}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'heal_toggle', 'heal_toggle_var', '{{heal=[[@{heal_formula}]]}}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'heal_query_toggle', 'heal_query', '?{Heal Bonus Amount|}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'higher_level_toggle', 'higher_level_toggle_var', '{{cast_as_level=@{higher_level_query}}}');
|
||||
this.changeOldRepeatingToggleToNew(v, finalSetAttrs, repeatingString, 'special_effects_toggle', 'special_effects_var', '{{fx=@{type}-@{color} @{points_of_origin}}}');
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
displayTextForTraits() {
|
||||
getSetRepeatingItems('upgrade.displayTextForTraits', {
|
||||
repeatingItems: ['repeating_trait'],
|
||||
collectionArrayAddItems: ['display_text', 'freetext'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}display_text`])) {
|
||||
finalSetAttrs[`${repeatingString}display_text`] = v[`${repeatingString}freetext`];
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
spellToTranslations() {
|
||||
getSetRepeatingItems('upgrade.spellToTranslations', {
|
||||
repeatingItems: ['repeating_spell'],
|
||||
collectionArrayAddItems: ['spell_level', 'school', 'casting_time', 'components', 'duration', 'concentration', 'saving_throw_vs_ability'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (v[`${repeatingString}spell_level`]) {
|
||||
finalSetAttrs[`${repeatingString}spell_level`] = ordinalSpellLevel(v[`${repeatingString}spell_level`]);
|
||||
}
|
||||
if (v[`${repeatingString}school`]) {
|
||||
finalSetAttrs[`${repeatingString}school`] = v[`${repeatingString}school`].toUpperCase();
|
||||
}
|
||||
if (v[`${repeatingString}casting_time`]) {
|
||||
finalSetAttrs[`${repeatingString}casting_time`] = v[`${repeatingString}casting_time`].trim().toUpperCase().replace(/\s/g, '_');
|
||||
}
|
||||
if (v[`${repeatingString}components`]) {
|
||||
finalSetAttrs[`${repeatingString}components`] = `COMPONENTS_${v[`${repeatingString}components`].trim().toUpperCase().replace(/\s/g, '_')}`;
|
||||
}
|
||||
if (v[`${repeatingString}duration`]) {
|
||||
let duration = '';
|
||||
if (v[`${repeatingString}concentration`] === 'Yes') {
|
||||
duration += 'CONCENTRATION_';
|
||||
}
|
||||
duration += v[`${repeatingString}duration`].trim().toUpperCase().replace(/\s/g, '_');
|
||||
finalSetAttrs[`${repeatingString}duration`] = duration;
|
||||
}
|
||||
if (finalSetAttrs[`${repeatingString}saving_throw_vs_ability`]) {
|
||||
finalSetAttrs[`${repeatingString}saving_throw_vs_ability`] = v[`${repeatingString}saving_throw_vs_ability`].toUpperCase();
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
spellLevelForCantrips() {
|
||||
getSetRepeatingItems('upgrade.spellLevelForCantrips', {
|
||||
repeatingItems: ['repeating_spell'],
|
||||
collectionArrayAddItems: ['spell_level'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}spell_level`]) || v[`${repeatingString}spell_level`] === '0' || v[`${repeatingString}spell_level`] === 0) {
|
||||
finalSetAttrs[`${repeatingString}spell_level`] = 'CANTRIP';
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
spellEffectsNaming() {
|
||||
getSetRepeatingItems('upgrade.spellEffectsNaming', {
|
||||
repeatingItems: ['repeating_spell'],
|
||||
collectionArrayAddItems: ['special_effects_toggle', 'type', 'color', 'points_of_origin'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}special_effects_toggle`])) {
|
||||
finalSetAttrs[`${repeatingString}special_effects_toggle`] = '{{fx=@{special_effects_type}-@{special_effects_color} @{special_effects_points_of_origin}}}';
|
||||
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}type`]) && v[`${repeatingString}type`] !== 'Ranged' && v[`${repeatingString}type`] !== 'Melee') {
|
||||
finalSetAttrs[`${repeatingString}special_effects_type`] = v[`${repeatingString}type`];
|
||||
}
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}color`])) {
|
||||
finalSetAttrs[`${repeatingString}special_effects_color`] = v[`${repeatingString}color`];
|
||||
}
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}points_of_origin`])) {
|
||||
finalSetAttrs[`${repeatingString}special_effects_points_of_origin`] = v[`${repeatingString}points_of_origin`];
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
critDamage() {
|
||||
getSetRepeatingItems('upgrade.critDamage', {
|
||||
repeatingItems: ['repeating_attack', 'repeating_spell', 'repeating_trait', 'repeating_action', 'repeating_reaction', 'repeating_legendaryaction', 'repeating_lairaction', 'repeating_regionaleffect'],
|
||||
collectionArrayAddItems: ['damage', 'damage_crit', 'second_damage', 'second_damage_crit'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (!v[`${repeatingString}damage_crit`] && v[`${repeatingString}damage`]) {
|
||||
finalSetAttrs[`${repeatingString}damage_crit`] = v[`${repeatingString}damage`];
|
||||
} else if (v[`${repeatingString}damage`] && v[`${repeatingString}damage_crit`]) {
|
||||
finalSetAttrs[`${repeatingString}damage_crit`] = `${v[`${repeatingString}damage`]} + ${v[`${repeatingString}damage_crit`]}`;
|
||||
}
|
||||
if (!v[`${repeatingString}second_damage_crit`] && v[`${repeatingString}second_damage`]) {
|
||||
finalSetAttrs[`${repeatingString}second_damage_crit`] = v[`${repeatingString}second_damage`];
|
||||
} else if (v[`${repeatingString}second_damage`] && v[`${repeatingString}second_damage_crit`]) {
|
||||
finalSetAttrs[`${repeatingString}second_damage_crit`] = `${v[`${repeatingString}second_damage`]} + ${v[`${repeatingString}second_damage_crit`]}`;
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
oldValueToNew(v, finalSetAttrs, repeatingString, newRepeatingString, field) {
|
||||
finalSetAttrs[`${newRepeatingString}${field}`] = v[`${repeatingString}${field}`];
|
||||
}
|
||||
resourcesToTraits() {
|
||||
getSetRepeatingItems('upgrade.resourcesToTraits', {
|
||||
repeatingItems: ['repeating_resource'],
|
||||
collectionArrayAddItems: ['name', 'uses', 'uses_max', 'toggle_details', 'recharge', 'extras_toggle', 'freetext', 'freeform'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
const fieldsToSwap = ['name', 'uses', 'uses_max', 'toggle_details', 'recharge', 'extras_toggle', 'freetext', 'freeform'];
|
||||
for (const id of ids) {
|
||||
for (const field of fieldsToSwap) {
|
||||
this.oldValueToNew(v, finalSetAttrs, `${repeatingItem}_${id}_`, `repeating_trait_${generateRowID()}_`, field);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
classFeaturesToTraits() {
|
||||
getSetRepeatingItems('upgrade.classFeaturesToTraits', {
|
||||
repeatingItems: ['repeating_classfeature'],
|
||||
collectionArrayAddItems: ['name', 'uses', 'uses_max', 'recharge', 'saving_throw_toggle', 'saving_throw_condition', 'saving_throw_ability', 'saving_throw_bonus', 'saving_throw_vs_ability', 'saving_throw_failure', 'saving_throw_success', 'damage_toggle', 'damage', 'damage_ability', 'damage_bonus', 'damage_type', 'second_damage_toggle', 'second_damage', 'second_damage_ability', 'second_damage_bonus', 'second_damage_type', 'heal', 'heal_ability', 'heal_bonus', 'heal_query_toggle', 'extras_toggle', 'emote', 'freetext', 'freeform'],
|
||||
callback: (v, finalSetAttrs, ids, repeatingItem) => {
|
||||
const fieldsToSwap = ['name', 'uses', 'uses_max', 'recharge', 'saving_throw_toggle', 'saving_throw_condition', 'saving_throw_ability', 'saving_throw_bonus', 'saving_throw_vs_ability', 'saving_throw_failure', 'saving_throw_success', 'damage_toggle', 'damage', 'damage_ability', 'damage_bonus', 'damage_type', 'second_damage_toggle', 'second_damage', 'second_damage_ability', 'second_damage_bonus', 'second_damage_type', 'heal', 'heal_ability', 'heal_bonus', 'heal_query_toggle', 'extras_toggle', 'emote', 'freetext', 'display_text', 'freeform'];
|
||||
|
||||
for (const id of ids) {
|
||||
for (const field of fieldsToSwap) {
|
||||
this.oldValueToNew(v, finalSetAttrs, `${repeatingItem}_${id}_`, `repeating_trait_${generateRowID()}_`, field);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
versionCompare(v1, v2, options) {
|
||||
const lexicographical = options && options.lexicographical;
|
||||
const zeroExtend = options && options.zeroExtend;
|
||||
let v1parts = v1.split('.');
|
||||
let v2parts = v2.split('.');
|
||||
|
||||
const isValidPart = (x) => {
|
||||
return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x);
|
||||
};
|
||||
|
||||
if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) {
|
||||
return NaN;
|
||||
}
|
||||
|
||||
if (zeroExtend) {
|
||||
while (v1parts.length < v2parts.length) {
|
||||
v1parts.push('0');
|
||||
}
|
||||
while (v2parts.length < v1parts.length) {
|
||||
v2parts.push('0');
|
||||
}
|
||||
}
|
||||
|
||||
if (!lexicographical) {
|
||||
v1parts = v1parts.map(Number);
|
||||
v2parts = v2parts.map(Number);
|
||||
}
|
||||
|
||||
for (let i = 0; i < v1parts.length; ++i) {
|
||||
if (v2parts.length === i) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (v1parts[i] === v2parts[i]) {
|
||||
continue;
|
||||
} else if (v1parts[i] > v2parts[i]) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (v1parts.length !== v2parts.length) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
upgrade() {
|
||||
if (this.versionCompare(currentVersion, '2.1.0') < 0) {
|
||||
npc.updateChallenge();
|
||||
resistances.updateDamageVulnerabilities();
|
||||
resistances.updateDamageResistances();
|
||||
resistances.updateDamageImmunities();
|
||||
resistances.updateConditionImmunities();
|
||||
npc.updateLanguages();
|
||||
npc.updateSenses();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.1.3') < 0) {
|
||||
npc.updateType();
|
||||
character.updateAlignment();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.1.5') < 0) {
|
||||
npc.updateAC();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.1.10') < 0) {
|
||||
savingThrows.update();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.1.13') < 0) {
|
||||
equipment.weigh();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.1.15') < 0) {
|
||||
this.displayTextForTraits();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.2.2') < 0) {
|
||||
this.resourcesToTraits();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.2.4') < 0) {
|
||||
abilityChecks.updateInitiative();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.2.5') < 0) {
|
||||
equipment.weighAmmo();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.2.6') < 0) {
|
||||
character.updateLevels();
|
||||
this.extasToExtrasFix('repeating_attack');
|
||||
this.extasToExtrasFix('repeating_action');
|
||||
this.extasToExtrasFix('repeating_spell');
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.3.3') < 0) {
|
||||
attachers.update();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.4.2') < 0) {
|
||||
abilities.updateModifiers();
|
||||
actions.updateChatMacro('trait');
|
||||
actions.updateChatMacro('action');
|
||||
actions.updateChatMacro('reaction');
|
||||
actions.updateChatMacro('legendaryaction');
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.4.3') < 0) {
|
||||
classFeatures.set();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.4.7') < 0) {
|
||||
this.classFeaturesToTraits();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.4.8') < 0) {
|
||||
this.fixRollTwo();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '2.4.12') < 0) {
|
||||
this.armorPlusDexRemoval();
|
||||
equipment.updateArmor();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '3.1.0') < 0) {
|
||||
attacks.updateChatMacro();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '3.2.1') < 0) {
|
||||
this.critDamage();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '3.2.3') < 0) {
|
||||
resistances.updateDamageResistancesVar();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '3.5.0') < 0) {
|
||||
spells.updateChatMacro();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '3.5.1') < 0) {
|
||||
spells.updateSlots();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '3.6.1') < 0) {
|
||||
npc.updateHD();
|
||||
npc.switchTo();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.1.4') < 0) {
|
||||
this.armorAbility();
|
||||
this.actionComponents();
|
||||
this.skillAbility();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.1.5') < 0) {
|
||||
abilityChecks.updateSkill();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.2.0') < 0) {
|
||||
character.updateD20Mod();
|
||||
settings.updateShapedD20();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.2.1') < 0) {
|
||||
this.actionComponentsToRemoveExtraFields();
|
||||
abilityChecks.updateMacro();
|
||||
this.removeToggleVar();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.2.3') < 0) {
|
||||
equipment.updateArmor();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.4.0') < 0) {
|
||||
savingThrows.updateCustomSavingThrows();
|
||||
this.newAttackToggle();
|
||||
spells.generateHigherLevelQueries();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.4.1') < 0) {
|
||||
this.newAbilityDefaults();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '4.4.2') < 0) {
|
||||
spells.updateShowHide();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '5.0.0') < 0) {
|
||||
this.spellToTranslations();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '5.0.3') < 0) {
|
||||
savingThrows.updateCustomSavingThrowToggle();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '5.0.4') < 0) {
|
||||
this.defaultAbility();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '5.0.6') < 0) {
|
||||
this.spellLevelForCantrips();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '5.2.3') < 0) {
|
||||
this.hideFreetext();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '6.0.1') < 0) {
|
||||
this.newAttackToggleTwo();
|
||||
spells.update();
|
||||
attacks.update();
|
||||
actions.updateAll();
|
||||
}
|
||||
if (this.versionCompare(currentVersion, '6.0.4') < 0) {
|
||||
this.spellEffectsNaming();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
const SKILLS = {
|
||||
ACROBATICS: 'dexterity',
|
||||
ANIMALHANDLING: 'wisdom',
|
||||
ARCANA: 'intelligence',
|
||||
ATHLETICS: 'strength',
|
||||
DECEPTION: 'charisma',
|
||||
HISTORY: 'intelligence',
|
||||
INSIGHT: 'wisdom',
|
||||
INTIMIDATION: 'charisma',
|
||||
INVESTIGATION: 'intelligence',
|
||||
MEDICINE: 'wisdom',
|
||||
NATURE: 'intelligence',
|
||||
PERCEPTION: 'wisdom',
|
||||
PERFORMANCE: 'charisma',
|
||||
PERSUASION: 'charisma',
|
||||
RELIGION: 'intelligence',
|
||||
SLEIGHTOFHAND: 'dexterity',
|
||||
STEALTH: 'dexterity',
|
||||
SURVIVAL: 'wisdom',
|
||||
};
|
||||
const CLASSES = ['barbarian', 'bard', 'cleric', 'druid', 'fighter', 'monk', 'paladin', 'ranger', 'rogue', 'sorcerer', 'warlock', 'wizard'];
|
||||
const ABILITIES = ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma'];
|
||||
const TOGGLE_VARS = {
|
||||
roll: '{{vs_ac=1}} @{roll_info} {{roll1=[[@{shaped_d20}cs>@{crit_range} + @{attack_formula}]]}} @{roll_setting}cs>@{crit_range} + @{attack_formula}]]}} {{targetAC=@{attacks_vs_target_ac}}} {{targetName=@{attacks_vs_target_name}}}',
|
||||
saving_throw: '{{saving_throw_condition=@{saving_throw_condition}}} {{saving_throw_dc=@{saving_throw_dc}}} {{saving_throw_vs_ability=@{saving_throw_vs_ability}}} {{saving_throw_failure=@{saving_throw_failure}}} {{saving_throw_success=@{saving_throw_success}}} {{targetName=@{attacks_vs_target_name}}}',
|
||||
damage: '{{damage=[[@{damage_formula}]]}} {{damage_type=@{damage_type}}} {{crit_damage=[[0d0 + @{damage_crit}[crit damage] @{damage_crit_formula}]]}}',
|
||||
second_damage: '{{second_damage=[[@{second_damage_formula}]]}} {{second_damage_type=@{second_damage_type}}} {{second_crit_damage=[[0d0 + @{second_damage_crit}[crit damage] @{second_damage_crit_formula}]]}}',
|
||||
heal: '{{heal=[[@{heal_formula}]]}}',
|
||||
heal_query: '?{Heal Bonus Amount|}',
|
||||
extras: '{{emote=@{emote}}} {{freetext=@{freetext}}} @{freeform}',
|
||||
higher_level: '{{cast_as_level=@{higher_level_query}}}',
|
||||
};
|
||||
|
||||
export { SKILLS, CLASSES, ABILITIES, TOGGLE_VARS };
|
||||
@@ -0,0 +1,47 @@
|
||||
/* global setAttrs:false, getAttrs:false, on:false, getSectionIDs:false, generateRowID:false, getTranslationByKey:false */
|
||||
|
||||
import { Abilities } from './Abilities';
|
||||
const abilities = new Abilities();
|
||||
abilities.setup();
|
||||
import { AbilityChecks } from './AbilityChecks';
|
||||
const abilityChecks = new AbilityChecks();
|
||||
abilityChecks.setup();
|
||||
import { Actions } from './Actions';
|
||||
const actions = new Actions();
|
||||
actions.setup();
|
||||
import { Attachers } from './Attachers';
|
||||
const attachers = new Attachers();
|
||||
attachers.setup();
|
||||
import { Attacks } from './Attacks';
|
||||
const attacks = new Attacks();
|
||||
attacks.setup();
|
||||
import { Character } from './Character';
|
||||
const character = new Character();
|
||||
character.setup();
|
||||
import { Equipment } from './Equipment';
|
||||
const equipment = new Equipment();
|
||||
equipment.setup();
|
||||
import { ImportData } from './ImportData';
|
||||
const importData = new ImportData();
|
||||
importData.setup();
|
||||
import { Initialize } from './Initialize';
|
||||
const initialize = new Initialize();
|
||||
initialize.setup();
|
||||
import { Npc } from './Npc';
|
||||
const npc = new Npc();
|
||||
npc.setup();
|
||||
import { ProficiencyBonus } from './ProficiencyBonus';
|
||||
const proficiencyBonus = new ProficiencyBonus();
|
||||
proficiencyBonus.setup();
|
||||
import { Resistances } from './Resistances';
|
||||
const resistances = new Resistances();
|
||||
resistances.setup();
|
||||
import { SavingThrows } from './SavingThrows';
|
||||
const savingThrows = new SavingThrows();
|
||||
savingThrows.setup();
|
||||
import { Settings } from './Settings';
|
||||
const settings = new Settings();
|
||||
settings.setup();
|
||||
import { Spells } from './Spells';
|
||||
const spells = new Spells();
|
||||
spells.setup();
|
||||
@@ -0,0 +1,380 @@
|
||||
import { TOGGLE_VARS } from './constants';
|
||||
import { fromVOrFinalSetAttrs, getIntValue, getAbilityValue, addArithmeticOperator, getAbilityShortName, hasUpperCase, isUndefined, isUndefinedOrEmpty, exists } from './utilities';
|
||||
|
||||
const parseAttackComponent = (v, repeatingString, finalSetAttrs, options) => {
|
||||
let parsed = v[`${repeatingString}parsed`];
|
||||
|
||||
if (isUndefinedOrEmpty(parsed)) {
|
||||
parsed = finalSetAttrs[`${repeatingString}parsed`];
|
||||
}
|
||||
|
||||
if (isUndefinedOrEmpty(parsed) || parsed.indexOf(options.parseName) === -1) {
|
||||
let aTriggerFieldExists = false;
|
||||
|
||||
if (options.triggerFields) {
|
||||
for (const triggerField of options.triggerFields) {
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}${triggerField}`])) {
|
||||
aTriggerFieldExists = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aTriggerFieldExists && isUndefinedOrEmpty(v[repeatingString + options.toggleField])) {
|
||||
finalSetAttrs[repeatingString + options.toggleField] = options.toggleFieldSetTo;
|
||||
|
||||
if (isUndefinedOrEmpty(finalSetAttrs[`${repeatingString}parsed`])) {
|
||||
finalSetAttrs[`${repeatingString}parsed`] = '';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}parsed`] += ` ${options.parseName}`;
|
||||
}
|
||||
if (options.attackAbility && isUndefined(v[`${repeatingString}attack_ability`])) {
|
||||
finalSetAttrs[`${repeatingString}attack_ability`] = v.default_ability;
|
||||
}
|
||||
|
||||
if (options.addCastingModifier) {
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}damage`]) && isUndefined(v[`${repeatingString}damage_ability`])) {
|
||||
finalSetAttrs[`${repeatingString}damage_ability`] = v.default_ability;
|
||||
}
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}heal`]) && isUndefined(v[`${repeatingString}heal_ability`])) {
|
||||
finalSetAttrs[`${repeatingString}heal_ability`] = v.default_ability;
|
||||
}
|
||||
}
|
||||
if (options.addSecondCastingModifier) {
|
||||
if (!isUndefinedOrEmpty(v[`${repeatingString}second_damage`]) && isUndefined(v[`${repeatingString}second_damage_ability`])) {
|
||||
finalSetAttrs[`${repeatingString}second_damage_ability`] = v.default_ability;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const updateAttackToggle = (v, finalSetAttrs, repeatingString, options) => {
|
||||
parseAttackComponent(v, repeatingString, finalSetAttrs, {
|
||||
attackAbility: options.attackAbility,
|
||||
parseName: 'attack',
|
||||
toggleField: 'roll_toggle',
|
||||
toggleFieldSetTo: TOGGLE_VARS.roll,
|
||||
triggerFields: ['type', 'attack_bonus'],
|
||||
});
|
||||
|
||||
let attackFormula = '';
|
||||
const attackToggle = v[`${repeatingString}roll_toggle`];
|
||||
|
||||
let toHit = 0;
|
||||
if (!attackToggle || attackToggle === TOGGLE_VARS.roll) {
|
||||
const proficiency = v[`${repeatingString}proficiency`];
|
||||
if (!proficiency || proficiency === 'on') {
|
||||
const pb = getIntValue(v.pb);
|
||||
toHit += pb;
|
||||
attackFormula += `${pb}[proficient]`;
|
||||
}
|
||||
|
||||
let attackAbility = v[`${repeatingString}attack_ability`];
|
||||
|
||||
if (isUndefined(attackAbility) && v[`${repeatingString}type`] === 'Melee Weapon') {
|
||||
attackAbility = 'strength';
|
||||
finalSetAttrs[`${repeatingString}attack_ability`] = attackAbility;
|
||||
} else if (isUndefined(attackAbility) && v[`${repeatingString}type`] === 'Ranged Weapon') {
|
||||
attackAbility = 'dexterity';
|
||||
finalSetAttrs[`${repeatingString}attack_ability`] = attackAbility;
|
||||
} else if (finalSetAttrs[`${repeatingString}attack_ability`]) {
|
||||
attackAbility = finalSetAttrs[`${repeatingString}attack_ability`];
|
||||
}
|
||||
attackAbility = getAbilityValue(v, attackAbility);
|
||||
if (exists(attackAbility)) {
|
||||
toHit += attackAbility;
|
||||
attackFormula += `${addArithmeticOperator(attackFormula, attackAbility)}[${getAbilityShortName(v[`${repeatingString}attack_ability`])}]`;
|
||||
}
|
||||
|
||||
const attackBonus = getIntValue(v[`${repeatingString}attack_bonus`]);
|
||||
if (exists(attackBonus)) {
|
||||
toHit += attackBonus;
|
||||
attackFormula += `${addArithmeticOperator(attackFormula, attackBonus)}[bonus]`;
|
||||
}
|
||||
|
||||
if (exists(options.globalAttackBonus)) {
|
||||
if (!isNaN(options.globalAttackBonus)) {
|
||||
toHit += getIntValue(options.globalAttackBonus);
|
||||
}
|
||||
attackFormula += `${addArithmeticOperator(attackFormula, options.globalAttackBonus)}[${options.globalAttackBonusLabel}]`;
|
||||
}
|
||||
|
||||
if (v[`${repeatingString}type`] === 'Melee Weapon') {
|
||||
if (exists(options.globalMeleeAttackBonus)) {
|
||||
if (!isNaN(options.globalMeleeAttackBonus)) {
|
||||
toHit += getIntValue(options.globalMeleeAttackBonus);
|
||||
}
|
||||
attackFormula += `${addArithmeticOperator(attackFormula, options.globalMeleeAttackBonus)}[global melee attack bonus]`;
|
||||
}
|
||||
} else if (v[`${repeatingString}type`] === 'Ranged Weapon') {
|
||||
if (exists(options.globalRangedAttackBonus)) {
|
||||
if (!isNaN(options.globalRangedAttackBonus)) {
|
||||
toHit += getIntValue(options.globalRangedAttackBonus);
|
||||
}
|
||||
attackFormula += `${addArithmeticOperator(attackFormula, options.globalRangedAttackBonus)}[global ranged attack bonus]`;
|
||||
}
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}attack_formula`] = attackFormula;
|
||||
}
|
||||
if (options.type === 'attack') {
|
||||
finalSetAttrs[`${repeatingString}to_hit`] = toHit;
|
||||
}
|
||||
};
|
||||
const updateSavingThrowToggle = (v, finalSetAttrs, repeatingString, options) => {
|
||||
parseAttackComponent(v, repeatingString, finalSetAttrs, {
|
||||
parseName: 'savingThrow',
|
||||
toggleField: 'saving_throw_toggle',
|
||||
toggleFieldSetTo: TOGGLE_VARS.saving_throw,
|
||||
triggerFields: ['saving_throw_ability', 'saving_throw_bonus', 'saving_throw_vs_ability'],
|
||||
});
|
||||
if (fromVOrFinalSetAttrs(v, finalSetAttrs, `${repeatingString}saving_throw_toggle`) === TOGGLE_VARS.saving_throw) {
|
||||
let savingThrowDC = getIntValue(v.base_dc) + getIntValue(v.pb);
|
||||
let savingThrowAbility = v[`${repeatingString}saving_throw_ability`];
|
||||
if (isUndefined(savingThrowAbility) && v.default_ability) {
|
||||
savingThrowAbility = v.default_ability;
|
||||
finalSetAttrs[`${repeatingString}saving_throw_ability`] = v.default_ability;
|
||||
}
|
||||
|
||||
savingThrowDC += getAbilityValue(v, savingThrowAbility);
|
||||
if (options && options.bonusDC) {
|
||||
savingThrowDC += getIntValue(options.bonusDC);
|
||||
}
|
||||
savingThrowDC += getIntValue(v[`${repeatingString}saving_throw_bonus`]);
|
||||
finalSetAttrs[`${repeatingString}saving_throw_dc`] = savingThrowDC;
|
||||
}
|
||||
};
|
||||
const updateDamageToggle = (v, finalSetAttrs, repeatingString, options) => {
|
||||
parseAttackComponent(v, repeatingString, finalSetAttrs, {
|
||||
addCastingModifier: exists(v[`${repeatingString}add_casting_modifier`]),
|
||||
parseName: 'damage',
|
||||
toggleField: 'damage_toggle',
|
||||
toggleFieldSetTo: TOGGLE_VARS.damage,
|
||||
triggerFields: ['damage', 'damage_ability', 'damage_bonus', 'damage_type'],
|
||||
});
|
||||
|
||||
let damageString = '';
|
||||
let damageFormula = '';
|
||||
const damageToggle = v[`${repeatingString}damage_toggle`];
|
||||
let damageAbility = v[`${repeatingString}damage_ability`];
|
||||
let damageType;
|
||||
|
||||
if (!damageToggle || damageToggle === TOGGLE_VARS.damage) {
|
||||
let damageAddition = 0;
|
||||
|
||||
const damage = v[`${repeatingString}damage`];
|
||||
if (exists(damage)) {
|
||||
damageString += damage;
|
||||
damageFormula += `${damage}[damage]`;
|
||||
}
|
||||
|
||||
if (isUndefined(damageAbility) && v[`${repeatingString}type`] === 'Melee Weapon') {
|
||||
damageAbility = 'strength';
|
||||
finalSetAttrs[`${repeatingString}damage_ability`] = damageAbility;
|
||||
} else if (isUndefined(damageAbility) && v[`${repeatingString}type`] === 'Ranged Weapon') {
|
||||
damageAbility = 'dexterity';
|
||||
finalSetAttrs[`${repeatingString}damage_ability`] = damageAbility;
|
||||
}
|
||||
if (exists(damageAbility)) {
|
||||
const damageAbilityValue = getAbilityValue(v, damageAbility);
|
||||
if (exists(damageAbilityValue)) {
|
||||
damageAddition += damageAbilityValue;
|
||||
damageFormula += `${addArithmeticOperator(damageFormula, damageAbilityValue)}[${getAbilityShortName(v[`${repeatingString}damage_ability`])}]`;
|
||||
}
|
||||
}
|
||||
|
||||
const damageBonus = getIntValue(v[`${repeatingString}damage_bonus`]);
|
||||
if (exists(damageBonus)) {
|
||||
damageAddition += damageBonus;
|
||||
damageFormula += `${addArithmeticOperator(damageFormula, damageBonus)}[bonus]`;
|
||||
}
|
||||
|
||||
if (exists(options.globalDamageBonus)) {
|
||||
if (!isNaN(options.globalDamageBonus)) {
|
||||
damageAddition += getIntValue(options.globalDamageBonus);
|
||||
} else {
|
||||
damageString += `${addArithmeticOperator(damageString, options.globalDamageBonus)}`;
|
||||
}
|
||||
damageFormula += `${addArithmeticOperator(damageFormula, options.globalDamageBonus)}[global damage bonus]`;
|
||||
}
|
||||
|
||||
if (options && exists(options.globalMeleeDamageBonus) && (v[`${repeatingString}type`] === 'Melee Weapon')) {
|
||||
if (!isNaN(options.globalMeleeDamageBonus)) {
|
||||
damageAddition += getIntValue(options.globalMeleeDamageBonus);
|
||||
} else {
|
||||
damageString += `${addArithmeticOperator(damageString, options.globalMeleeDamageBonus)}`;
|
||||
}
|
||||
damageFormula += `${addArithmeticOperator(damageFormula, options.globalMeleeDamageBonus)}[global melee damage bonus]`;
|
||||
} else if (options && exists(options.globalRangedDamageBonus) && v[`${repeatingString}type`] === 'Ranged Weapon') {
|
||||
if (!isNaN(options.globalRangedDamageBonus)) {
|
||||
damageAddition += getIntValue(options.globalRangedDamageBonus);
|
||||
} else {
|
||||
damageString += `${addArithmeticOperator(damageString, options.globalRangedDamageBonus)}`;
|
||||
}
|
||||
damageFormula += `${addArithmeticOperator(damageFormula, options.globalRangedDamageBonus)}[global ranged damage bonus]`;
|
||||
}
|
||||
|
||||
if (exists(damageAddition)) {
|
||||
damageString += addArithmeticOperator(damageString, damageAddition);
|
||||
}
|
||||
|
||||
damageType = v[`${repeatingString}damage_type`];
|
||||
if (exists(damageType)) {
|
||||
if (hasUpperCase(damageType)) {
|
||||
damageType = damageType.toLowerCase();
|
||||
finalSetAttrs[`${repeatingString}damage_type`] = damageType;
|
||||
}
|
||||
damageString += ` ${damageType}`;
|
||||
}
|
||||
}
|
||||
if (!exists(damageFormula)) {
|
||||
damageFormula = 0;
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}damage_formula`] = damageFormula;
|
||||
|
||||
parseAttackComponent(v, repeatingString, finalSetAttrs, {
|
||||
addSecondCastingModifier: exists(v[`${repeatingString}add_second_casting_modifier`]),
|
||||
parseName: 'secondDamage',
|
||||
toggleField: 'second_damage_toggle',
|
||||
toggleFieldSetTo: TOGGLE_VARS.second_damage,
|
||||
triggerFields: ['second_damage', 'second_damage_ability', 'second_damage_bonus', 'second_damage_type'],
|
||||
});
|
||||
|
||||
let secondDamageFormula = '';
|
||||
|
||||
const secondDamageToggle = fromVOrFinalSetAttrs(v, finalSetAttrs, `${repeatingString}second_damage_toggle`);
|
||||
if (secondDamageToggle === TOGGLE_VARS.second_damage) {
|
||||
let secondDamageAddition = 0;
|
||||
const secondDamage = v[`${repeatingString}second_damage`];
|
||||
if (exists(secondDamage)) {
|
||||
damageString += ` + ${secondDamage}`;
|
||||
secondDamageFormula += `${secondDamage}[second damage]`;
|
||||
}
|
||||
|
||||
let secondDamageAbility = v[`${repeatingString}second_damage_ability`];
|
||||
if (exists(secondDamageAbility)) {
|
||||
secondDamageAbility = getAbilityValue(v, secondDamageAbility);
|
||||
if (exists(secondDamageAbility)) {
|
||||
secondDamageAddition += secondDamageAbility;
|
||||
secondDamageFormula += `${addArithmeticOperator(secondDamageFormula, secondDamageAbility)}[${getAbilityShortName(v[`${repeatingString}second_damage_ability`])}]`;
|
||||
}
|
||||
}
|
||||
|
||||
const secondDamageBonus = getIntValue(v[`${repeatingString}second_damage_bonus`]);
|
||||
if (exists(secondDamageBonus)) {
|
||||
secondDamageAddition += secondDamageBonus;
|
||||
secondDamageFormula += `${addArithmeticOperator(secondDamageFormula, secondDamageBonus)}[bonus]`;
|
||||
}
|
||||
|
||||
if (exists(secondDamageAddition)) {
|
||||
damageString += addArithmeticOperator(damageString, secondDamageAddition);
|
||||
}
|
||||
|
||||
let secondDamageType = v[`${repeatingString}second_damage_type`];
|
||||
if (exists(secondDamageType)) {
|
||||
if (hasUpperCase(secondDamageType)) {
|
||||
secondDamageType = secondDamageType.toLowerCase();
|
||||
finalSetAttrs[`${repeatingString}second_damage_type`] = secondDamageType;
|
||||
}
|
||||
damageString += ` ${secondDamageType}`;
|
||||
}
|
||||
|
||||
if (isUndefinedOrEmpty(v[`${repeatingString}parsed`]) || v[`${repeatingString}parsed`].indexOf('damageProperties') === -1) {
|
||||
const damageProperties = v[`${repeatingString}properties`];
|
||||
if (exists(damageProperties)) {
|
||||
if (damageProperties.indexOf('Versatile') !== -1) {
|
||||
if (!exists(damageAbility)) {
|
||||
damageAbility = 'strength';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}second_damage_ability`] = damageAbility;
|
||||
finalSetAttrs[`${repeatingString}second_damage_type`] = damageType;
|
||||
}
|
||||
if (!finalSetAttrs[`${repeatingString}parsed`]) {
|
||||
finalSetAttrs[`${repeatingString}parsed`] = '';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}parsed`] += ' damageProperties';
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!exists(secondDamageFormula)) {
|
||||
secondDamageFormula = 0;
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}second_damage_formula`] = secondDamageFormula;
|
||||
if (options.type === 'attack') {
|
||||
finalSetAttrs[`${repeatingString}damage_string`] = damageString;
|
||||
}
|
||||
};
|
||||
const updateHealToggle = (v, finalSetAttrs, repeatingString) => {
|
||||
parseAttackComponent(v, repeatingString, finalSetAttrs, {
|
||||
addCastingModifier: exists(v[`${repeatingString}add_casting_modifier`]),
|
||||
parseName: 'heal',
|
||||
toggleField: 'heal_toggle',
|
||||
toggleFieldSetTo: TOGGLE_VARS.heal,
|
||||
triggerFields: ['heal', 'heal_query_toggle'],
|
||||
});
|
||||
let healFormula = '';
|
||||
const healToggle = v[`${repeatingString}heal_toggle`];
|
||||
if (healToggle === TOGGLE_VARS.heal) {
|
||||
if (!isUndefined(v[`${repeatingString}heal`])) {
|
||||
healFormula = '@{heal}[heal]';
|
||||
}
|
||||
if (!isUndefined(v[`${repeatingString}heal_ability`])) {
|
||||
const healAbility = getAbilityValue(v, v[`${repeatingString}heal_ability`]);
|
||||
healFormula += `${addArithmeticOperator(healFormula, healAbility)}[${getAbilityShortName(v[`${repeatingString}heal_ability`])}]`;
|
||||
}
|
||||
if (!isUndefined(v[`${repeatingString}heal_bonus`])) {
|
||||
const healBonus = getIntValue(v[`${repeatingString}heal_bonus`]);
|
||||
healFormula += `${addArithmeticOperator(healFormula, healBonus)}[bonus]`;
|
||||
}
|
||||
|
||||
if (!isUndefined(v.global_spell_heal_bonus)) {
|
||||
if (healFormula) {
|
||||
healFormula += ' + ';
|
||||
}
|
||||
healFormula += '@{global_spell_heal_bonus}[global spell heal bonus]';
|
||||
}
|
||||
if (v[`${repeatingString}heal_query_toggle`] === TOGGLE_VARS.heal_query) {
|
||||
if (healFormula) {
|
||||
healFormula += ' + ';
|
||||
}
|
||||
healFormula += '@{heal_query_toggle}[query amount]';
|
||||
}
|
||||
|
||||
finalSetAttrs[`${repeatingString}heal_formula`] = healFormula;
|
||||
}
|
||||
};
|
||||
const updateHigherLevelToggle = (v, finalSetAttrs, repeatingString) => {
|
||||
parseAttackComponent(v, repeatingString, finalSetAttrs, {
|
||||
addCastingModifier: exists(v[`${repeatingString}add_casting_modifier`]),
|
||||
parseName: 'higherLevel',
|
||||
toggleField: 'higher_level_toggle',
|
||||
toggleFieldSetTo: TOGGLE_VARS.higher_level,
|
||||
triggerFields: ['higher_level_dice', 'higher_level_die', 'second_higher_level_dice', 'second_higher_level_die', 'higher_level_heal'],
|
||||
});
|
||||
|
||||
const higherLevelToggle = v[`${repeatingString}higher_level_toggle`];
|
||||
if (exists(higherLevelToggle) && higherLevelToggle === TOGGLE_VARS.higher_level) {
|
||||
const spellLevel = getIntValue(v[`${repeatingString}spell_level`]);
|
||||
finalSetAttrs[`${repeatingString}higher_level_query`] = `@{higher_level_query_${spellLevel}}`;
|
||||
|
||||
const damageToggle = v[`${repeatingString}damage_toggle`];
|
||||
if (damageToggle && damageToggle === TOGGLE_VARS.damage) {
|
||||
const higherLevelDamage = `((@{higher_level_query} - ${spellLevel}) * @{higher_level_dice})@{higher_level_die}[higher lvl]`;
|
||||
finalSetAttrs[`${repeatingString}damage_formula`] += addArithmeticOperator(finalSetAttrs[`${repeatingString}damage_formula`], higherLevelDamage);
|
||||
finalSetAttrs[`${repeatingString}damage_crit_formula`] = higherLevelDamage;
|
||||
}
|
||||
|
||||
const secondDamageToggle = v[`${repeatingString}second_damage_toggle`];
|
||||
if (secondDamageToggle && secondDamageToggle === TOGGLE_VARS.second_damage) {
|
||||
const higherLevelSecondDamage = `((@{higher_level_query} - ${spellLevel}) * @{second_higher_level_dice})@{second_higher_level_die}[higher lvl]`;
|
||||
finalSetAttrs[`${repeatingString}second_damage_formula`] += addArithmeticOperator(finalSetAttrs[`${repeatingString}second_damage_formula`], higherLevelSecondDamage);
|
||||
finalSetAttrs[`${repeatingString}second_damage_crit_formula`] = higherLevelSecondDamage;
|
||||
}
|
||||
|
||||
const healToggle = v[`${repeatingString}heal_toggle`];
|
||||
if (healToggle && healToggle === TOGGLE_VARS.heal) {
|
||||
if (finalSetAttrs[`${repeatingString}heal_formula`]) {
|
||||
finalSetAttrs[`${repeatingString}heal_formula`] += ' + ';
|
||||
}
|
||||
finalSetAttrs[`${repeatingString}heal_formula`] += `((@{higher_level_query} - ${spellLevel}) * @{higher_level_dice})@{higher_level_die}[higher lvl] + (@{higher_level_heal} * (@{higher_level_query} - ${spellLevel}))[higher lvl flat amount]`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { updateAttackToggle, updateSavingThrowToggle, updateDamageToggle, updateHealToggle, updateHigherLevelToggle };
|
||||
@@ -0,0 +1,411 @@
|
||||
/* global setAttrs:false, getAttrs:false, getSectionIDs:false */
|
||||
|
||||
const capitalize = (string) => {
|
||||
return string.replace(/\w\S*/g, (txt) => {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
||||
});
|
||||
};
|
||||
const camelize = (str) => {
|
||||
return str.replace(/(?:^\w|[A-Z]|\b\w|\s+)/g, (match, index) => {
|
||||
if (+match === 0) return '';
|
||||
return index === 0 ? match.toLowerCase() : match.toUpperCase();
|
||||
});
|
||||
};
|
||||
const firstThree = (string) => {
|
||||
return string.substring(0, 3);
|
||||
};
|
||||
const round = (value, places) => {
|
||||
return +(`${Math.round(`${value}e+${places}`)}e-${places}`);
|
||||
};
|
||||
const isUndefined = (value) => {
|
||||
if (typeof value === 'undefined') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const isUndefinedOrEmpty = (value) => {
|
||||
if (typeof value === 'undefined' || value === '') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const isEmpty = (obj) => {
|
||||
for (const prop in obj) {
|
||||
if (obj.hasOwnProperty(prop)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const exists = (value) => {
|
||||
if (isUndefinedOrEmpty(value) || value === '' || value === '0' || value === 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const getIntValue = (value, defaultValue) => {
|
||||
if (!defaultValue) {
|
||||
defaultValue = 0;
|
||||
}
|
||||
if (value === 0 || value === '0') {
|
||||
return 0;
|
||||
}
|
||||
return parseInt(value, 10) || defaultValue;
|
||||
};
|
||||
const getFloatValue = (value, defaultValue) => {
|
||||
if (!defaultValue) {
|
||||
defaultValue = 0;
|
||||
}
|
||||
return parseFloat(value) || defaultValue;
|
||||
};
|
||||
const getAbilityMod = (score) => {
|
||||
return Math.floor((getIntValue(score) - 10) / 2);
|
||||
};
|
||||
const getAbilityName = (varName) => {
|
||||
if (!varName) {
|
||||
return 'strength';
|
||||
} else if (typeof varName === 'string') {
|
||||
varName = varName.replace(/\W/g, '');
|
||||
}
|
||||
return varName;
|
||||
};
|
||||
const getAbilityValue = (v, varName) => {
|
||||
if (exists(varName)) {
|
||||
varName = getAbilityName(varName);
|
||||
return getIntValue(v[`${varName}_mod`], 0);
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
const getAbilityShortName = (varName, capital) => {
|
||||
if (!varName) {
|
||||
return 'Str';
|
||||
}
|
||||
varName = varName.replace(/\W/g, '');
|
||||
if (capital) {
|
||||
varName = capitalize(varName);
|
||||
}
|
||||
return firstThree(varName);
|
||||
};
|
||||
const getRepeatingInfo = (leadingString, eventInfo) => {
|
||||
const re = new RegExp(`${leadingString}_(-[a-zA-Z0-9\-]*)_(.*)`);
|
||||
const match = eventInfo.sourceAttribute.match(re);
|
||||
|
||||
let result;
|
||||
if (match && match[1] && match[2]) {
|
||||
result = {
|
||||
rowId: match[1],
|
||||
field: match[2],
|
||||
};
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const setFinalAttrs = (v, finalSetAttrs, name, callback) => {
|
||||
if (!isEmpty(finalSetAttrs)) {
|
||||
for (const key in finalSetAttrs) {
|
||||
if (finalSetAttrs.hasOwnProperty(key)) {
|
||||
if (v[key] === finalSetAttrs[key]) {
|
||||
delete finalSetAttrs[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!isEmpty(finalSetAttrs)) {
|
||||
console.info(name, 'setFinalAttrs', finalSetAttrs);
|
||||
}
|
||||
if (!isEmpty(finalSetAttrs)) {
|
||||
if (callback) {
|
||||
setAttrs(finalSetAttrs, {}, callback);
|
||||
} else {
|
||||
setAttrs(finalSetAttrs);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
const fromVOrFinalSetAttrs = (v, finalSetAttrs, value) => {
|
||||
if (exists(finalSetAttrs[value])) {
|
||||
return finalSetAttrs[value];
|
||||
}
|
||||
return v[value];
|
||||
};
|
||||
const hasUpperCase = (string) => {
|
||||
return (/[A-Z]/.test(string));
|
||||
};
|
||||
const ordinalSpellLevel = (level) => {
|
||||
let spellLevel = '';
|
||||
level = getIntValue(level);
|
||||
if (level === 0) {
|
||||
spellLevel = 'CANTRIP';
|
||||
} else {
|
||||
switch (level % 10) {
|
||||
case 1:
|
||||
spellLevel = `${level}ST_LEVEL`;
|
||||
break;
|
||||
case 2:
|
||||
spellLevel = `${level}ND_LEVEL`;
|
||||
break;
|
||||
case 3:
|
||||
spellLevel = `${level}RD_LEVEL`;
|
||||
break;
|
||||
default:
|
||||
spellLevel = `${level}TH_LEVEL`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return spellLevel;
|
||||
};
|
||||
const addArithmeticOperator = (string, number) => {
|
||||
let value = number;
|
||||
if (string) {
|
||||
if (number < 0) {
|
||||
value = ` - ${Math.abs(number)}`;
|
||||
} else {
|
||||
value = ` + ${number}`;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
};
|
||||
const showSign = (value) => {
|
||||
if (value >= 0) {
|
||||
value = `+${value}`;
|
||||
}
|
||||
return value;
|
||||
};
|
||||
const numberWithCommas = (x) => {
|
||||
const parts = x.toString().split('.');
|
||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
return parts.join('.');
|
||||
};
|
||||
const lowercaseDamageTypes = (string) => {
|
||||
if (!string) {
|
||||
string = '';
|
||||
}
|
||||
return string
|
||||
.replace('Acid', 'acid')
|
||||
.replace('Cold', 'cold')
|
||||
.replace('Fire', 'fire')
|
||||
.replace('Force', 'force')
|
||||
.replace('Lightning', 'lightning')
|
||||
.replace('Necrotic', 'necrotic')
|
||||
.replace('Poison', 'poison')
|
||||
.replace('Psychic', 'psychic')
|
||||
.replace('Radiant', 'radiant')
|
||||
.replace('Thunder', 'thunder')
|
||||
.replace('Bludgeoning', 'bludgeoning')
|
||||
.replace('Piercing', 'piercing')
|
||||
.replace('Slashing', 'slashing')
|
||||
.replace('And', 'and')
|
||||
.replace('From', 'from')
|
||||
.replace('Nonmagical', 'nonmagical')
|
||||
.replace('Weapons', 'weapons')
|
||||
.replace('That', 'that')
|
||||
.replace('Aren\'t', 'aren\'t')
|
||||
.replace('Silvered', 'silvered')
|
||||
.replace('Adamantine', 'adamantine');
|
||||
};
|
||||
const getSetItems = (name, obj) => {
|
||||
const collectionArray = obj.collectionArray || [];
|
||||
const finalSetAttrs = {};
|
||||
|
||||
getAttrs(collectionArray, (v) => {
|
||||
if (obj.callback) {
|
||||
obj.callback(v, finalSetAttrs);
|
||||
}
|
||||
setFinalAttrs(v, finalSetAttrs, name, () => {
|
||||
if (obj.setFinalAttrsCallback) {
|
||||
obj.setFinalAttrsCallback();
|
||||
}
|
||||
});
|
||||
if (obj.returnCallback) {
|
||||
obj.returnCallback();
|
||||
}
|
||||
});
|
||||
};
|
||||
const getSetRepeatingItems = (name, obj) => {
|
||||
const collectionArray = obj.collectionArray || [];
|
||||
const finalSetAttrs = {};
|
||||
|
||||
if (obj.repeatingItems) {
|
||||
for (const repeatingItem of obj.repeatingItems) {
|
||||
getSectionIDs(repeatingItem, (ids) => {
|
||||
if (obj.rowId) {
|
||||
ids = [];
|
||||
ids.push(obj.rowId);
|
||||
}
|
||||
if (ids) {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (obj.collectionArrayAddItems) {
|
||||
for (const addItem of obj.collectionArrayAddItems) {
|
||||
collectionArray.push(`${repeatingString}${addItem}`);
|
||||
}
|
||||
}
|
||||
if (obj.itemsToPush) {
|
||||
for (const itemToPush of obj.itemsToPush) {
|
||||
collectionArray.push(`${repeatingString}${itemToPush}_${obj.itemToPushSuffix}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getAttrs(collectionArray, (v) => {
|
||||
if (obj.callback) {
|
||||
obj.callback(v, finalSetAttrs, ids, repeatingItem);
|
||||
}
|
||||
setFinalAttrs(v, finalSetAttrs, name, () => {
|
||||
if (obj.setFinalAttrsCallback) {
|
||||
obj.setFinalAttrsCallback();
|
||||
}
|
||||
});
|
||||
if (obj.returnCallback) {
|
||||
obj.returnCallback();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
const sumRepeating = (options, sumItems) => {
|
||||
const repeatingItem = `repeating_${options.collection}`;
|
||||
let collectionArray = [];
|
||||
const finalSetAttrs = {};
|
||||
|
||||
getSectionIDs(repeatingItem, (ids) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
collectionArray.push(repeatingString + options.toggle);
|
||||
if (options.qty) {
|
||||
collectionArray.push(repeatingString + options.qty);
|
||||
}
|
||||
|
||||
for (const sumItem of sumItems) {
|
||||
finalSetAttrs[sumItem.totalField] = 0;
|
||||
if (sumItem.totalFieldSecondary) {
|
||||
finalSetAttrs[sumItem.totalFieldSecondary] = 0;
|
||||
}
|
||||
collectionArray.push(repeatingString + sumItem.fieldToAdd);
|
||||
if (sumItem.bonus) {
|
||||
collectionArray.push(repeatingString + sumItem.bonus);
|
||||
}
|
||||
if (sumItem.armorType) {
|
||||
collectionArray.push(repeatingString + sumItem.armorType);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.getExtraFields) {
|
||||
collectionArray = collectionArray.concat(options.getExtraFields);
|
||||
}
|
||||
|
||||
getAttrs(collectionArray, (v) => {
|
||||
let dexMod = 0;
|
||||
if (options.collection === 'armor') {
|
||||
dexMod = getIntValue(v.dexterity_mod);
|
||||
}
|
||||
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
const qty = getIntValue(v[repeatingString + options.qty], 1);
|
||||
|
||||
for (const sumItem of sumItems) {
|
||||
let fieldToAdd = getFloatValue(v[repeatingString + sumItem.fieldToAdd]);
|
||||
if (sumItem.bonus) {
|
||||
fieldToAdd += getFloatValue(v[repeatingString + sumItem.bonus]);
|
||||
}
|
||||
if (sumItem.armorType) {
|
||||
if (!v[repeatingString + sumItem.armorType] || v[repeatingString + sumItem.armorType] === 'Light Armor') {
|
||||
fieldToAdd += dexMod;
|
||||
} else if (v[repeatingString + sumItem.armorType] === 'Medium Armor') {
|
||||
const mediumArmorDexMod = getIntValue(v.medium_armor_max_dex, 2);
|
||||
fieldToAdd += Math.min(mediumArmorDexMod, dexMod);
|
||||
}
|
||||
}
|
||||
|
||||
let itemTotal = round((qty * fieldToAdd), 2);
|
||||
|
||||
itemTotal = round(itemTotal, 2);
|
||||
|
||||
if (sumItem.itemTotal) {
|
||||
finalSetAttrs[repeatingString + sumItem.itemTotal] = itemTotal;
|
||||
}
|
||||
|
||||
const toggle = v[repeatingString + options.toggle];
|
||||
if (toggle !== 0 && toggle !== '0') {
|
||||
let addToPrimary = true;
|
||||
let addToSecondary = false;
|
||||
|
||||
if (sumItem.armorType) {
|
||||
if (v[repeatingString + sumItem.armorType] === 'Shield' || v[repeatingString + sumItem.armorType] === 'AC') {
|
||||
addToSecondary = true;
|
||||
} else if (v[repeatingString + sumItem.armorType] === 'Unarmored') {
|
||||
addToPrimary = false;
|
||||
addToSecondary = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (addToPrimary) {
|
||||
finalSetAttrs[sumItem.totalField] += itemTotal;
|
||||
}
|
||||
if (addToSecondary) {
|
||||
finalSetAttrs[sumItem.totalFieldSecondary] += itemTotal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const sumItem of sumItems) {
|
||||
if (sumItem.totalField && !exists(finalSetAttrs[sumItem.totalField])) {
|
||||
finalSetAttrs[sumItem.totalField] = 0;
|
||||
}
|
||||
if (sumItem.totalFieldSecondary && !exists(finalSetAttrs[sumItem.totalFieldSecondary])) {
|
||||
finalSetAttrs[sumItem.totalFieldSecondary] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (options.collection === 'armor' && !getIntValue(v.is_npc)) {
|
||||
finalSetAttrs.ac_unarmored_calc += 10 + dexMod + getAbilityValue(v, v.ac_unarmored_ability);
|
||||
|
||||
finalSetAttrs.AC = Math.max(finalSetAttrs.ac_armored_calc, finalSetAttrs.ac_unarmored_calc);
|
||||
}
|
||||
setFinalAttrs(v, finalSetAttrs, 'sumRepeating');
|
||||
});
|
||||
});
|
||||
};
|
||||
const getSkillIdByStorageName = (v, repeatingItem, ids, prop) => {
|
||||
for (const id of ids) {
|
||||
const repeatingString = `${repeatingItem}_${id}_`;
|
||||
if (v[`${repeatingString}storage_name`] === prop || v[`${repeatingString}storage_name`] === camelize(prop)) {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
};
|
||||
const setCritDamage = (v, finalSetAttrs, repeatingString) => {
|
||||
if (!v[`${repeatingString}damage_crit`] && v[`${repeatingString}damage`]) {
|
||||
finalSetAttrs[`${repeatingString}damage_crit`] = v[`${repeatingString}damage`];
|
||||
}
|
||||
if (!v[`${repeatingString}second_damage_crit`] && v[`${repeatingString}second_damage`]) {
|
||||
finalSetAttrs[`${repeatingString}second_damage_crit`] = v[`${repeatingString}second_damage`];
|
||||
}
|
||||
};
|
||||
const updateHD = (v, finalSetAttrs, hd) => {
|
||||
for (const key in hd) {
|
||||
if (hd.hasOwnProperty(key)) {
|
||||
if (hd[key] && hd[key] !== 0) {
|
||||
finalSetAttrs[`hd_${key}_max`] = hd[key];
|
||||
finalSetAttrs[`hd_${key}_query`] = '?{HD';
|
||||
for (let x = 1; x <= hd[key]; x++) {
|
||||
finalSetAttrs[`hd_${key}_query`] += `|${x}`;
|
||||
}
|
||||
finalSetAttrs[`hd_${key}_query`] += '}';
|
||||
finalSetAttrs[`hd_${key}_toggle`] = 1;
|
||||
} else {
|
||||
if (!isUndefinedOrEmpty(v[`hd_${key}_max`])) {
|
||||
finalSetAttrs[`hd_${key}_max`] = 0;
|
||||
}
|
||||
if (!isUndefinedOrEmpty(v[`hd_${key}_query`])) {
|
||||
finalSetAttrs[`hd_${key}_query`] = '';
|
||||
}
|
||||
if (exists(v[`hd_${key}_toggle`])) {
|
||||
finalSetAttrs[`hd_${key}_toggle`] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { capitalize, camelize, firstThree, round, isUndefined, isUndefinedOrEmpty, isEmpty, exists, getIntValue, getFloatValue, getAbilityMod, getAbilityName, getAbilityValue, getAbilityShortName, getRepeatingInfo, setFinalAttrs, fromVOrFinalSetAttrs, hasUpperCase, ordinalSpellLevel, addArithmeticOperator, showSign, numberWithCommas, lowercaseDamageTypes, getSetItems, getSetRepeatingItems, sumRepeating, getSkillIdByStorageName, setCritDamage, updateHD };
|
||||
@@ -0,0 +1,3 @@
|
||||
const currentVersion = '6.0.4';
|
||||
|
||||
export { currentVersion };
|
||||
+649
-637
File diff suppressed because it is too large
Load Diff
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
+161
-149
@@ -1,83 +1,82 @@
|
||||
{
|
||||
"10_DAYS":"10 days",
|
||||
"10_MINUTES":"10 minutes",
|
||||
"12_HOURS":"12 hours",
|
||||
"1ST":"1st",
|
||||
"1ST_LEVEL":"1st-level",
|
||||
"1_ACTION":"1 action",
|
||||
"1_BONUS_ACTION":"1 bonus action",
|
||||
"1_HOUR":"1 hour",
|
||||
"1_MINUTE":"1 minutes",
|
||||
"1_REACTION":"1 reaction",
|
||||
"1_ROUND":"1 round",
|
||||
"24_HOURS":"24 hours",
|
||||
"2ND":"2nd",
|
||||
"2ND_LEVEL":"2nd-level",
|
||||
"30_DAYS":"30 days",
|
||||
"3RD":"3rd",
|
||||
"3RD_LEVEL":"3rd-level",
|
||||
"4TH":"4th",
|
||||
"4TH_LEVEL":"4th-level",
|
||||
"5TH":"5th",
|
||||
"5TH_LEVEL":"5th-level",
|
||||
"6TH":"6th",
|
||||
"6TH_LEVEL":"6th-level",
|
||||
"7TH":"7th",
|
||||
"7TH_LEVEL":"7th-level",
|
||||
"7_DAYS":"7 days",
|
||||
"8TH":"8th",
|
||||
"8TH_LEVEL":"8th-level",
|
||||
"8_HOURS":"8 hours",
|
||||
"9TH":"9th",
|
||||
"9TH_LEVEL":"9th-level",
|
||||
"10_DAYS":"10 Tage",
|
||||
"10_MINUTES":"10 Minuten",
|
||||
"12_HOURS":"12 Stunden",
|
||||
"1ST":"1.",
|
||||
"1ST_LEVEL":"Stufe 1",
|
||||
"1_ACTION":"1 Aktion",
|
||||
"1_BONUS_ACTION":"1 Bonusaktion",
|
||||
"1_HOUR":"1 Stunde",
|
||||
"1_MINUTE":"1 Minute",
|
||||
"1_REACTION":"1 Reaktion",
|
||||
"1_ROUND":"1 Runde",
|
||||
"24_HOURS":"24 Stunden",
|
||||
"2ND":"2.",
|
||||
"2ND_LEVEL":"Stufe 2",
|
||||
"30_DAYS":"30 Tage",
|
||||
"3RD":"3.",
|
||||
"3RD_LEVEL":"Stufe 3",
|
||||
"4TH":"4.",
|
||||
"4TH_LEVEL":"Stufe 4",
|
||||
"5TH":"5.",
|
||||
"5TH_LEVEL":"Stufe 5",
|
||||
"6TH":"6.",
|
||||
"6TH_LEVEL":"Stufe 6",
|
||||
"7TH":"7.",
|
||||
"7TH_LEVEL":"Stufe 7",
|
||||
"7_DAYS":"7 Tage",
|
||||
"8TH":"8.",
|
||||
"8TH_LEVEL":"Stufe 8",
|
||||
"8_HOURS":"8 Stunden",
|
||||
"9TH":"9.",
|
||||
"9TH_LEVEL":"Stufe 9",
|
||||
"ABILITY":"Fähigkeit",
|
||||
"ABILITY_CHECK":"Ability check",
|
||||
"ABILITY_CHECKS":"Fähigkeits-Check",
|
||||
"ABILITY_CHECK":"Fähigkeits-Check",
|
||||
"ABILITY_CHECKS":"Fähigkeits-Checks",
|
||||
"ABILITY_CHECKS_QUERY":"Ability checks query",
|
||||
"ABILITY_SCORES":"Ability scores",
|
||||
"ABILITY_SCORES":"Fähigkeitswerte",
|
||||
"ABJURATION":"Bannzauber",
|
||||
"AC":"RK",
|
||||
"ACID":"acid",
|
||||
"ACID":"Säure",
|
||||
"ACROBATICS":"Akrobatik",
|
||||
"ACTION":"Aktion",
|
||||
"ACTIONS":"Aktionen",
|
||||
"AC_ARMORED":"Gepanzerte-RK",
|
||||
"AC_UNARMORED":"Ungepanzerte-RK",
|
||||
"AC_UNARMORED_ABILITY":"Ungepanzerte Fähigkeit",
|
||||
"ADD_HALF_PROFICIENCY_TO_UNPROFICIENT_SAVING_THROWS":"Add half proficiency<br>to unproficient saving throws",
|
||||
"ADD_HALF_PROFICIENCY_TO_UNPROFICIENT_SAVING_THROWS":"Halben Befähigunsbonus zu nicht befähigten Rettungswürfen addieren",
|
||||
"ADVANTAGE":"Vorteil",
|
||||
"AGE":"Alter",
|
||||
"ALIGNMENT":"Gesinnung",
|
||||
"ALL":"Alles",
|
||||
"AMMO":"Munition",
|
||||
"AMMO_AUTO_USE":"Automatically use ammo",
|
||||
"AMMO_AUTO_USE":"Benutze Munition automatisch",
|
||||
"AMMO_WEIGHT":"Munitionsgewicht",
|
||||
"AMPHIBIOUS":"Amphibious",
|
||||
"AMPHIBIOUS":"Amphibisch",
|
||||
"ANIMALHANDLING":"Umgang mit Tieren",
|
||||
"API":"API",
|
||||
"APPEARANCE":"Aussehen",
|
||||
"ARCANA":"Arkanes",
|
||||
"ARMOR":"Rüstung",
|
||||
"ARMORED_AND_UNARMORED":"Panzer und Ungepanzerten",
|
||||
"ARMOR_CLASS":"Rüstungsklasse",
|
||||
"ARROWS":"Arrows",
|
||||
"ARMORED_AND_UNARMORED":"Gepanzert und ungepanzert",
|
||||
"ARMOR_CLASS":"RK",
|
||||
"ARROWS":"Pfeile",
|
||||
"AS":"as",
|
||||
"ATHLETICS":"Athletik",
|
||||
"ATK":"ATT",
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Angriff",
|
||||
"ATTACKS":"Angriffe",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"AVERAGE_OF_ABILITIES":"Average of the highest 1 or 2 abilities",
|
||||
"BACKGROUND":"Hintergrund",
|
||||
"BARBARIAN":"Barbar",
|
||||
"BARD":"Barde",
|
||||
"BASE_DC":"Base DC",
|
||||
"BIG":"Big",
|
||||
"BITE":"Bite",
|
||||
"BASE_DC":"Basis-Schwierigkeitsgrad",
|
||||
"BIG":"Gross",
|
||||
"BITE":"Biss",
|
||||
"BLINDSIGHT":"Blindsicht",
|
||||
"BLIND_BEYOND":"Blind danach",
|
||||
"BLIND_BEYOND":"Blind ausserhalb",
|
||||
"BLUDGEONING":"bludgeoning",
|
||||
"BONDS":"Verpflichtungen",
|
||||
"BONUS":"Bonus",
|
||||
@@ -86,13 +85,13 @@
|
||||
"BONUSES_AND_PENALTIES_TOOLTIP":"Auto add a bonus\/penalty to rolls made using the sheet macros.<br>Usage: you acquire a magic item that gives +1 to your spell save DC, enter 1 in the spell save DC field. You are under the effects of the Bless spell, enter \"d4cs0cf0\" in both attack roll fields, and the saving throw one",
|
||||
"BREAK_TIES":"Break ties",
|
||||
"BURROW":"Graben",
|
||||
"CANCEL":"Cancel",
|
||||
"CANCEL":"Abbrechen",
|
||||
"CANTRIP":"Zaubertrick",
|
||||
"CANTRIPS":"Zaubertricks",
|
||||
"CAN_HAVE":"Kann haben",
|
||||
"CARRIED":"Getragen",
|
||||
"CARRYING_CAPACITY":"Trage-Kapazität",
|
||||
"CARRYING_PUSH_DRAG_LIFT":"Ziehen\/Schieben\/Heben",
|
||||
"CARRYING_PUSH_DRAG_LIFT":"Ziehen\/Schieben\/<br>Heben",
|
||||
"CASTERS_FULL":"Voll (9. ebene: Barde, Kleriker, Druide, Hexenmeister, Zauberer)",
|
||||
"CASTERS_HALF":"Hälfte (5. ebene: Paladin, Waldläufer)",
|
||||
"CASTERS_THIRD":"Dritte (3. ebene: Arcane Urbilder)",
|
||||
@@ -107,7 +106,7 @@
|
||||
"CHECK_BONUS":"Check-Bonus",
|
||||
"CLASS":"Klasse",
|
||||
"CLASS_AND_LEVEL":"Klasse & Stufe",
|
||||
"CLASS_AND_LEVEL_PLACEHOLDER":"Generated after adding a class on the \"Character\" tab",
|
||||
"CLASS_AND_LEVEL_PLACEHOLDER":"Generiert nach Hinzufügen einer Klasse im \"Charakter\"-Tab",
|
||||
"CLASS_FEATURE_ACTION_SURGE":"Action Surge",
|
||||
"CLASS_FEATURE_ACTION_SURGE_TEXT":"On your turn, you can take one additional action on top of your regular action and a possible bonus action.",
|
||||
"CLASS_FEATURE_ARCANE_RECOVERY":"Arcane Recovery",
|
||||
@@ -319,8 +318,8 @@
|
||||
"COIN_CONVERSION_GP_PER_EP":"Elektrum pro Gold (2)",
|
||||
"COIN_CONVERSION_GP_PER_PP":"Gold pro Platinum (10)",
|
||||
"COIN_CONVERSION_GP_PER_SP":"Silber pro Gold (10)",
|
||||
"COLD":"cold",
|
||||
"COLOR":"Color",
|
||||
"COLD":"Kälte",
|
||||
"COLOR":"Farbe",
|
||||
"COMPONENTS":"Komponenten",
|
||||
"COMPONENTS_M":"M",
|
||||
"COMPONENTS_S":"S",
|
||||
@@ -332,25 +331,25 @@
|
||||
"CON":"Kon",
|
||||
"CONC":"Konz.",
|
||||
"CONCENTRATION":"Konzentration",
|
||||
"CONCENTRATION_UP_TO_10_MINUTES":"Concentration, up to 10 minute",
|
||||
"CONCENTRATION_UP_TO_12_HOURS":"Concentration, up to 12 hours",
|
||||
"CONCENTRATION_UP_TO_1_HOUR":"Concentration, up to 1 hour",
|
||||
"CONCENTRATION_UP_TO_1_MINUTE":"Concentration, up to 1 minute",
|
||||
"CONCENTRATION_UP_TO_1_ROUND":"Concentration, up to 1 round",
|
||||
"CONCENTRATION_UP_TO_24_HOURS":"Concentration, up to 24 hours",
|
||||
"CONCENTRATION_UP_TO_2_HOURS":"Concentration, up to 2 hours",
|
||||
"CONCENTRATION_UP_TO_6_ROUNDS":"Concentration, up to 6 rounds",
|
||||
"CONCENTRATION_UP_TO_8_HOURS":"Concentration, up to 8 hours",
|
||||
"CONDENSE":"Condense",
|
||||
"CONDITION_IMMUNITIES":"Konditionen Immunitäten",
|
||||
"CONCENTRATION_UP_TO_10_MINUTES":"Konzentration, bis zu 10 Minuten",
|
||||
"CONCENTRATION_UP_TO_12_HOURS":"Konzentration, bis zu 12 Stunden",
|
||||
"CONCENTRATION_UP_TO_1_HOUR":"Konzentration, bis zu 1 Stunde",
|
||||
"CONCENTRATION_UP_TO_1_MINUTE":"Konzentration, bis zu 1 Minute",
|
||||
"CONCENTRATION_UP_TO_1_ROUND":"Konzentration, bis zu 1 Runde",
|
||||
"CONCENTRATION_UP_TO_24_HOURS":"Konzentration, bis zu 24 Stunden",
|
||||
"CONCENTRATION_UP_TO_2_HOURS":"Konzentration, bis zu 2 Stunden",
|
||||
"CONCENTRATION_UP_TO_6_ROUNDS":"Konzentration, bis zu 6 Runden",
|
||||
"CONCENTRATION_UP_TO_8_HOURS":"Konzentration, bis zu 8 Stunden",
|
||||
"CONDENSE":"Komprimiert",
|
||||
"CONDITION_IMMUNITIES":"Konditions-Immunitäten",
|
||||
"CONJURATION":"Beschwörung",
|
||||
"CONSTITUTION":"Konstitution",
|
||||
"CONTENT":"Inhalt",
|
||||
"COPPER_PIECES":"Copper pieces",
|
||||
"COPPER_PIECES":"Kupfermünzen",
|
||||
"CORE":"Kern",
|
||||
"CRIT":"Krit",
|
||||
"CRIT_ATTACHER_TOOLTIP":"Select one or more other categories and crit to have this message only show when a crit occurs for that category. This will not work for freeform.",
|
||||
"CRIT_DAMAGE_TOOLTIP":"Determines the damage to roll for a crit. Normal weapon damage is not included.",
|
||||
"CRIT_DAMAGE_TOOLTIP":"Bestimmt den Schaden, der für einen Krit zusätzlich gewürfelt wird. Standardmässig ist dies der normale Waffenschaden.",
|
||||
"CRIT_RANGE":"Krit-Ab",
|
||||
"CURRENT":"Aktuell",
|
||||
"CUSTOM":"Benutzerdef.",
|
||||
@@ -362,12 +361,12 @@
|
||||
"DAMAGE_VULNERABILITIES":"Schadens-Verwundbarkeiten",
|
||||
"DARKVISION":"Dunkelsicht",
|
||||
"DC":"SG",
|
||||
"DEATH":"Death",
|
||||
"DEATH":"Tod",
|
||||
"DEATH_SAVES":"Todesrettung",
|
||||
"DEATH_SAVING_THROW":"Todesrettung",
|
||||
"DEATH_SAVING_THROWS":"Todesrettungswürfe",
|
||||
"DECEPTION":"Täuschung",
|
||||
"DEFAULT_ABILITY":"Standardfähigkeit",
|
||||
"DEFAULT_ABILITY":"Standard-<br>fähigkeit",
|
||||
"DEFAULT_ABILITY_TOOLTIP":"This will set the ability for saving throw DCs when importing a Spell or Attack. If \"Add Casting Modifier\" is also set on the importing item it will apply to the damage ability or heal ability as well.",
|
||||
"DEX":"Ges",
|
||||
"DEXTERITY":"Geschick",
|
||||
@@ -377,12 +376,12 @@
|
||||
"DISPLAY_TEXT":"Display text",
|
||||
"DIVINATION":"Erkenntniszauber",
|
||||
"DMG":"DMG",
|
||||
"DONT":"Nacht",
|
||||
"DRAGON":"Dragon",
|
||||
"DONT":"Nicht zum Tracker schicken",
|
||||
"DRAGON":"Drache",
|
||||
"DRUID":"Druide",
|
||||
"DURATION":"Dauer",
|
||||
"EFFECT":"Effekt",
|
||||
"ELECTRUM_PIECES":"Electrum pieces",
|
||||
"ELECTRUM_PIECES":"Elektrummünzen",
|
||||
"EMOTE":"Emote",
|
||||
"ENCHANTMENT":"Verzauberung",
|
||||
"ENCUMBERED":"Beladen",
|
||||
@@ -390,7 +389,7 @@
|
||||
"EQUIPMENT":"Ausrüstung",
|
||||
"EVERY":"every",
|
||||
"EVOCATION":"Hervorrufung",
|
||||
"EXHAUSTION_LEVEL":"Erschöpfungsstufe",
|
||||
"EXHAUSTION_LEVEL":"Erschöpfung",
|
||||
"EXHAUSTION_LEVEL_1":"Nachteil auf Fähigkeitschecks",
|
||||
"EXHAUSTION_LEVEL_2":"Geschwindigkeit halbiert",
|
||||
"EXHAUSTION_LEVEL_3":"Nachteil auf Angriffswürfe & Rettungswürfe",
|
||||
@@ -399,70 +398,71 @@
|
||||
"EXHAUSTION_LEVEL_6":"Tod",
|
||||
"EXPERIENCE_POINTS":"Erfahrungspunkte",
|
||||
"EXPERTISE":"Sachverstand",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Augen",
|
||||
"FAILURES":"Fehlschläge",
|
||||
"FEATURES":"Talente",
|
||||
"FEATURES_AND_TRAITS":"Talente & Fertigkeiten",
|
||||
"FIELD":"Field",
|
||||
"FIELD":"Feld",
|
||||
"FIGHTER":"Kämpfer",
|
||||
"FILTERS":"Filters",
|
||||
"FILTERS":"Filter",
|
||||
"FINESSE":"Finesse",
|
||||
"FIRE":"fire",
|
||||
"FIRE":"Feuer",
|
||||
"FLAT_HEAL":"Einfache Heilung",
|
||||
"FLAWS":"Schwachstellen",
|
||||
"FLY":"Fliegen",
|
||||
"FORCE":"force",
|
||||
"FORT":"Fort",
|
||||
"FORTITUDE":"Fortitude",
|
||||
"FORTITUDE":"Zähigkeit",
|
||||
"FREEFORM":"Freiform",
|
||||
"FREETEXT":"Freitext",
|
||||
"GARGANTUAN":"Gargantuan",
|
||||
"GENDER":"Geschlecht",
|
||||
"GENERATE_SKILLS":"Fertigkeiten erzeugen",
|
||||
"GOLD_PIECES":"Gold pieces",
|
||||
"GOLD_PIECES":"Goldmünzen",
|
||||
"HAIR":"Haar",
|
||||
"HALFLING_LUCK":"Halblings Glück",
|
||||
"HALF_DAMAGE":"half damage",
|
||||
"HALFLING_LUCK":"Halblingsglück",
|
||||
"HALF_DAMAGE":"Schaden halbiert",
|
||||
"HEAL":"Heilung",
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAL_FOR":"Heile um",
|
||||
"HEAVY_ARMOR":"Schwere Rüstung",
|
||||
"HEIGHT":"Höhe",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO":"Information verbergen",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Verberge Fähigkeits-Checks",
|
||||
"HIDE_INFO_ATTACK":"Verberge Angriff",
|
||||
"HIDE_INFO_DAMAGE":"Verberge Schaden",
|
||||
"HIDE_INFO_EFFECT":"Verberge Effekt",
|
||||
"HIDE_INFO_FREETEXT":"Verberge Freitext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
"HIDE_INFO_SAVING_THROW_DC":"Hide saving throw DC",
|
||||
"HIDE_INFO_SAVING_THROW_FAILURE":"Hide saving throw failure",
|
||||
"HIDE_INFO_SAVING_THROW_SUCCESS":"Hide saving throw success",
|
||||
"HIDE_INFO_SPELL_CONTENT":"Hide spell content",
|
||||
"HIDE_INFO_RECHARGE":"Verberge Aufladung",
|
||||
"HIDE_INFO_SAVING_THROWS":"Verberge Rettungswürfe",
|
||||
"HIDE_INFO_SAVING_THROW_DC":"Verberge Rettungswurf-SG",
|
||||
"HIDE_INFO_SAVING_THROW_FAILURE":"Verberge Rettungswurf-Erfolg",
|
||||
"HIDE_INFO_SAVING_THROW_SUCCESS":"Verberge Rettungswurf-Fehlschlag",
|
||||
"HIDE_INFO_SPELL_CONTENT":"Verberge Zauberinhalt",
|
||||
"HIGHER_LEVEL":"Höhere Stufe",
|
||||
"HISTORY":"Geschichte",
|
||||
"HIT_DICE":"Trefferwürfel",
|
||||
"HIT_POINTS":"Trefferpunkte",
|
||||
"HIT_POINTS_ROLLED":"Hit points rolled",
|
||||
"HIT_DICE":"TW",
|
||||
"HIT_POINTS":"TP",
|
||||
"HIT_POINTS_ROLLED":"Gewürfelte TP",
|
||||
"HIT_POINTS_TEMP":"Temp TP",
|
||||
"HIT_POINTS_TEMPORARY":"Temporary hit points",
|
||||
"HOUSERULES":"Houserules",
|
||||
"HIT_POINTS_TEMPORARY":"Temporäre Trefferpunkte",
|
||||
"HOUSERULES":"Hausregeln",
|
||||
"HOVER":"Schweben",
|
||||
"HUGE":"Enorm",
|
||||
"IDEALS":"Ideale",
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"IF_THE_TARGET_IS":"Wenn das Ziel",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"IMPORT":"Importiere",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
"INITIATIVE_BONUS":"Initiativbonus",
|
||||
"INSIGHT":"Einschätzen",
|
||||
"INSPIRATION":"Inspiration",
|
||||
"INSTANTANEOUS":"Instantaneous",
|
||||
"INSTANTANEOUS_OR_1_HOUR":"Instantaneous or 1 hour",
|
||||
"INSTANTANEOUS":"Sofort",
|
||||
"INSTANTANEOUS_OR_1_HOUR":"Sofort oder 1 Stunde",
|
||||
"INT":"Int",
|
||||
"INTELLIGENCE":"Intelligenz",
|
||||
"INTIMIDATION":"Einschüchtern",
|
||||
@@ -471,18 +471,18 @@
|
||||
"LAIR_ACTIONS":"Lair Actions",
|
||||
"LANGUAGES":"Sprachen",
|
||||
"LARGE":"Groß",
|
||||
"LAWFUL_EVIL":"lawful evil",
|
||||
"LBS":"lbs",
|
||||
"LAWFUL_EVIL":"Rechtschaffen böse",
|
||||
"LBS":"Pfund",
|
||||
"LEGENDARY_ACTIONS":"Legendäre Aktionen",
|
||||
"LEGENDARY_ACTIONS_TEXT_1":"The",
|
||||
"LEGENDARY_ACTIONS_TEXT_2":"can take",
|
||||
"LEGENDARY_ACTIONS_TEXT_3":"legendary actions, choosing from the options below. Only one legendary option can be used at a time and only at the end of another creature's turn. The",
|
||||
"LEGENDARY_ACTIONS_TEXT_4":"regains spent legendary actions at the start of its turn.",
|
||||
"LEVEL":"Stufe",
|
||||
"LEVELS":"levels",
|
||||
"LIGHTNING":"lightning",
|
||||
"LEVELS":"Stufen",
|
||||
"LIGHTNING":"Blitz",
|
||||
"LIGHT_ARMOR":"Leichte Rüstung",
|
||||
"LONG_REST":"Long Rest",
|
||||
"LONG_REST":"Lange Rast",
|
||||
"MACROS":"Makros",
|
||||
"MAX":"Max",
|
||||
"MEDICINE":"Medizin",
|
||||
@@ -490,101 +490,110 @@
|
||||
"MEDIUM_ARMOR":"Mittlere Rüstung",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Mittlere Rüstung Max Gesch.",
|
||||
"MELEE":"Nahkampf",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Sonstiges",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS":"Sonstiges",
|
||||
"MISCELLANEOUS_NOTES":"Sonstige Notizen",
|
||||
"MONK":"Mönch",
|
||||
"MOVEMENT":"Bewegung",
|
||||
"MULTIPLIER":"Multiplier",
|
||||
"MULTIPLIER":"Multiplikator",
|
||||
"NAME":"Name",
|
||||
"NATURE":"Natur",
|
||||
"NECROMANCY":"Nekromantie",
|
||||
"NECROTIC":"necrotic",
|
||||
"NECROTIC":"necrotischer",
|
||||
"NO":"Nein",
|
||||
"NORMAL":"Normalerweise",
|
||||
"NPC":"NPC",
|
||||
"ONE_CREATURE":"one creature",
|
||||
"OR":"or",
|
||||
"NPC":"NSC",
|
||||
"ONE_CREATURE":"eine Kreatur",
|
||||
"OR":"oder",
|
||||
"OTHER":"Andere",
|
||||
"OTHER_ARMOR":"Andere Rüstung",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Andere Befähigungen",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Ausgabe",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passiver Fähigkeitscheck",
|
||||
"PC":"SC",
|
||||
"PERCEPTION":"Wahrnehmung",
|
||||
"PERFORMANCE":"Auftreten",
|
||||
"PERSONALITY_TRAITS":"Persönlichkeitsmerkmale",
|
||||
"PERSUASION":"Überzeugen",
|
||||
"PIERCING":"piercing",
|
||||
"PLATINUM_PIECES":"Platinum pieces",
|
||||
"POINTS_OF_ORIGIN":"Points of origin",
|
||||
"POISON":"poison",
|
||||
"PLATINUM_PIECES":"Platinmünzen",
|
||||
"POINTS_OF_ORIGIN":"Ursprungspunkte",
|
||||
"POISON":"Gift",
|
||||
"PREPARED":"Vorbereitet",
|
||||
"PROF":"Befähigt",
|
||||
"PROFICIENCIES":"Befähigungen",
|
||||
"PROFICIENCY_BONUS":"Befähigungsbonus",
|
||||
"PROFICIENT":"Tüchtig",
|
||||
"PSYCHIC":"psychic",
|
||||
"PUBLIC_FOR_ALL":"Öffentliche für alle zu sehen",
|
||||
"PROFICIENT":"Befähigt",
|
||||
"PSYCHIC":"psychischer",
|
||||
"PUBLIC_FOR_ALL":"Öffentlich für alle",
|
||||
"QTY":"Menge",
|
||||
"QUERY":"Query",
|
||||
"QUERY":"Abfrage",
|
||||
"RACE":"Rasse",
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Reichweite",
|
||||
"RANGED":"Fernkampf",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Waldläufer",
|
||||
"REACH":"Bereich",
|
||||
"REACH":"Reichweite",
|
||||
"REACTION":"Reaktion",
|
||||
"REACTIONS":"Reaktionen",
|
||||
"RECHARGE":"Aufladung",
|
||||
"REF":"Ref",
|
||||
"REFLEX":"Reflex",
|
||||
"REGIONAL_EFFECTS":"Regional Effects",
|
||||
"REGIONAL_EFFECTS":"Regionale Effekte",
|
||||
"RELIGION":"Religion",
|
||||
"REMARKABLE_ATHLETE":"Herausragender Athlet",
|
||||
"REQUIRES_API":"This feature requires the API",
|
||||
"REQUIRES_API":"Dieses Feature erfordert die API",
|
||||
"RESISTANCES_AND_IMMUNITIES":"Resistenzen & Immunitäten",
|
||||
"RESOURCES":"Ressourcen",
|
||||
"RESTS":"Rests",
|
||||
"RESTS":"Rast",
|
||||
"RITUAL":"Ritual",
|
||||
"ROGUE":"Schurke",
|
||||
"ROLL_2":"Roll 2",
|
||||
"ROLL_OPTIONS":"Roll options",
|
||||
"ROLL_TEMPLATE":"Roll template",
|
||||
"SAVE":"Save",
|
||||
"SAVE_FAILURE":"Save Failure",
|
||||
"SAVE_SUCCESS":"Save Success",
|
||||
"SAVE":"Rettungswurf",
|
||||
"SAVE_FAILURE":"RW Fehlschlag",
|
||||
"SAVE_SUCCESS":"RW Erfolg",
|
||||
"SAVING_DC":"Rettungs-SG",
|
||||
"SAVING_THROW":"Rettungswurf",
|
||||
"SAVING_THROWS":"Rettungswürfe",
|
||||
"SAVING_THROWS_QUERY":"Saving throws query",
|
||||
"SAVING_THROWS_QUERY":"Rettungswurfabfrage",
|
||||
"SAVING_THROW_DC":"Rettungswurf-SG",
|
||||
"SENSES":"Sinne",
|
||||
"SHEET":"Bogen",
|
||||
"SHEET_OUTPUT":"Bogen Ausgabe",
|
||||
"SHIELD":"Schild",
|
||||
"SHORT_REST":"Short Rest",
|
||||
"SHORT_REST":"Kurze Rast",
|
||||
"SHOW_ALL":"Zeige alles",
|
||||
"SHOW_PASSIVE":"Show passive",
|
||||
"SHOW_RESTS":"Show Rests",
|
||||
"SHOW_SPELL_LEVEL_IF_ALL_SLOTS_ARE_USED":"Show levels if all slots are used",
|
||||
"SHOW_PASSIVE":"Passive zeigen",
|
||||
"SHOW_RESTS":"Rast anzeigen",
|
||||
"SHOW_SPELL_LEVEL_IF_ALL_SLOTS_ARE_USED":"Stufen zeigen, wenn alle Slots aufgebraucht sind",
|
||||
"SHOW_TARGET_AC_ON_ATTACKS":"Zeige Ziel-RK bei Angriffen",
|
||||
"SHOW_TARGET_NAME_ON_ATTACKS":"Zeige Ziel-Name bei Angriffen",
|
||||
"SHOW_TOTALS":"Show totals",
|
||||
"SHOW_UNPREPARED_SPELLS":"Show unprepared spells",
|
||||
"SILVER_PIECES":"Silver pieces",
|
||||
"SHOW_TOTALS":"Gesamtbonus anzeigen",
|
||||
"SHOW_UNPREPARED_SPELLS":"Nicht vorbereitete Zauber zeigen",
|
||||
"SILVER_PIECES":"Silbermünzen",
|
||||
"SIZE":"Größe",
|
||||
"SKILL":"Fertigkeit",
|
||||
"SKILLS":"Fertigkeiten",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Sachverstand",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Befähigt",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Nicht befähigt",
|
||||
"SKIN":"Hautfarbe",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Fingerfertigkeit",
|
||||
"SMALL":"Klein",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Hexenmeister",
|
||||
"SOURCE":"Source",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SOURCE":"Quelle",
|
||||
"SOURCE_TO_TARGET":"Quelle → Ziel",
|
||||
"SPECIAL":"Speziell",
|
||||
"SPECIAL_EFFECTS":"Spezialeffekte",
|
||||
"SPEED":"Geschw.",
|
||||
"SPELL":"Zauber",
|
||||
"SPELLCASTING":"Zaubern",
|
||||
@@ -600,27 +609,30 @@
|
||||
"STEALTH":"Heimlichkeit",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Stärke",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Erfolge",
|
||||
"SURVIVAL":"Überleben",
|
||||
"SWIM":"Schwimmen",
|
||||
"TARGET":"Ziel",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"TARGET_TO_SOURCE":"Ziel → Quelle",
|
||||
"TEXT_SIZE":"Textgröße",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Sehr klein",
|
||||
"TOTAL":"Gesamt",
|
||||
"TOTAL_GOLD_VALUE":"Total gold value",
|
||||
"TO_TRACKER":"Schicken Tracker",
|
||||
"TO_TRACKER":"Zum Tracker schicken",
|
||||
"TRACKER":"Tracker",
|
||||
"TRAITS":"Traits",
|
||||
"TRANSMUTATION":"Verwandlung",
|
||||
"TREMORSENSE":"Erschütterungssinn",
|
||||
"TRUESIGHT":"Wahrsicht",
|
||||
"TURN_OFF_FILTERING":"If you are unable to see recently added spells turn off \"filters\"",
|
||||
"TURN_OFF_FILTERING":"Wenn neu hinzugefügte Zauber nicht sichtbar sind, deaktiviere \"Filter\"",
|
||||
"TYPE":"Typ",
|
||||
"UNARMORED":"Ungepanzerten",
|
||||
"UNPROFICIENT":"Fehlt Tüchtig",
|
||||
"UNTIL_DISPELLED":"Until dispelled",
|
||||
"UNTIL_DISPELLED_OR_TRIGGERED":"Until dispelled or triggered",
|
||||
"UNARMORED":"Ungepanzert",
|
||||
"UNPROFICIENT":"Nicht befähigt",
|
||||
"UNTIL_DISPELLED":"Bis gebannt",
|
||||
"UNTIL_DISPELLED_OR_TRIGGERED":"Bis gebannt oder ausgelöst",
|
||||
"USED":"Used",
|
||||
"USES":"Uses",
|
||||
"USE_CUSTOM_SAVING_THROWS":"Use custom saving throws",
|
||||
@@ -630,8 +642,8 @@
|
||||
"WARLOCK":"Hexer",
|
||||
"WARLOCK_SPELL_SLOTS":"Hexer Zauberslots",
|
||||
"WEIGHT":"Gewicht",
|
||||
"WHISPERED_TO_GM":"Raunte der GM",
|
||||
"WILL":"Will",
|
||||
"WHISPERED_TO_GM":"Geflüstert an den GM",
|
||||
"WILL":"Willen",
|
||||
"WIS":"Wei",
|
||||
"WISDOM":"Weisheit",
|
||||
"WIZARD":"Zauberer",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"AC_ARMORED":"Armored AC",
|
||||
"AC_UNARMORED":"Unarmored AC",
|
||||
"AC_UNARMORED_ABILITY":"Unarmored ability",
|
||||
"ADD_HALF_PROFICIENCY_TO_UNPROFICIENT_SAVING_THROWS":"Add half proficiency<br>to unproficient saving throws",
|
||||
"ADD_HALF_PROFICIENCY_TO_UNPROFICIENT_SAVING_THROWS":"Add half proficiency to unproficient saving throws",
|
||||
"ADVANTAGE":"Advantage",
|
||||
"AGE":"Age",
|
||||
"ALIGNMENT":"Alignment",
|
||||
@@ -67,9 +67,8 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"AVERAGE_OF_ABILITIES":"Average of the highest 1 or 2 abilities",
|
||||
"BACKGROUND":"Background",
|
||||
"BARBARIAN":"Barbarian",
|
||||
"BARD":"Bard",
|
||||
@@ -350,7 +349,7 @@
|
||||
"CORE":"Core",
|
||||
"CRIT":"Crit",
|
||||
"CRIT_ATTACHER_TOOLTIP":"Select one or more other categories and crit to have this message only show when a crit occurs for that category. This will not work for freeform.",
|
||||
"CRIT_DAMAGE_TOOLTIP":"Determines the damage to roll for a crit. Normal weapon damage is not included.",
|
||||
"CRIT_DAMAGE_TOOLTIP":"The damage field is rolled on a crit. This field defaults to the same as damage, but can be edited to another value",
|
||||
"CRIT_RANGE":"Crit range",
|
||||
"CURRENT":"Current",
|
||||
"CUSTOM":"Custom",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,9 +67,8 @@
|
||||
"ATTACHERS":"Attaches",
|
||||
"ATTACK":"Attaque",
|
||||
"ATTACKS":"Attaques",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Enlever le (dés)avantage après chaque jet",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"AVERAGE_OF_ABILITIES":"Average of the highest 1 or 2 abilities",
|
||||
"BACKGROUND":"Biographie",
|
||||
"BARBARIAN":"Barbare",
|
||||
"BARD":"Barde",
|
||||
@@ -332,15 +331,15 @@
|
||||
"CON":"Con",
|
||||
"CONC":"Conc",
|
||||
"CONCENTRATION":"Concentration",
|
||||
"CONCENTRATION_UP_TO_10_MINUTES":"Concentration, up to 10 minute",
|
||||
"CONCENTRATION_UP_TO_12_HOURS":"Concentration, up to 12 hours",
|
||||
"CONCENTRATION_UP_TO_1_HOUR":"Concentration, up to 1 hour",
|
||||
"CONCENTRATION_UP_TO_1_MINUTE":"Concentration, up to 1 minute",
|
||||
"CONCENTRATION_UP_TO_1_ROUND":"Concentration, up to 1 round",
|
||||
"CONCENTRATION_UP_TO_24_HOURS":"Concentration, up to 24 hours",
|
||||
"CONCENTRATION_UP_TO_2_HOURS":"Concentration, up to 2 hours",
|
||||
"CONCENTRATION_UP_TO_6_ROUNDS":"Concentration, up to 6 rounds",
|
||||
"CONCENTRATION_UP_TO_8_HOURS":"Concentration, up to 8 hours",
|
||||
"CONCENTRATION_UP_TO_10_MINUTES":"up to 10 minute",
|
||||
"CONCENTRATION_UP_TO_12_HOURS":"up to 12 hours",
|
||||
"CONCENTRATION_UP_TO_1_HOUR":"up to 1 hour",
|
||||
"CONCENTRATION_UP_TO_1_MINUTE":"up to 1 minute",
|
||||
"CONCENTRATION_UP_TO_1_ROUND":"up to 1 round",
|
||||
"CONCENTRATION_UP_TO_24_HOURS":"up to 24 hours",
|
||||
"CONCENTRATION_UP_TO_2_HOURS":"up to 2 hours",
|
||||
"CONCENTRATION_UP_TO_6_ROUNDS":"up to 6 rounds",
|
||||
"CONCENTRATION_UP_TO_8_HOURS":"up to 8 hours",
|
||||
"CONDENSE":"Condensé",
|
||||
"CONDITION_IMMUNITIES":"Immunité<br>aux conditions",
|
||||
"CONJURATION":"Invocation",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Mort",
|
||||
"EXPERIENCE_POINTS":"Points d'Expérience",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Yeux",
|
||||
"FAILURES":"Échecs",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Soigne",
|
||||
"HEAVY_ARMOR":"Armure Lourde",
|
||||
"HEIGHT":"Taille",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"Si la cible est",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Importer",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Bonus initiative",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Armure Intermédiaire",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Bonus dex max<br>(armure intermédaire)",
|
||||
"MELEE":"Mêlée",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Autre",
|
||||
"MISCELLANEOUS":"Divers",
|
||||
"MISCELLANEOUS_NOTES":"Notes diverses",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Autre",
|
||||
"OTHER_ARMOR":"Autre type d'Armure",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Maîtrises & Langues",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Options d'affichage",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Carac passive",
|
||||
"PC":"PJ",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Portée",
|
||||
"RANGED":"Tir",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Rôdeur",
|
||||
"REACH":"Allonge",
|
||||
"REACTION":"Réaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Catégorie de taille",
|
||||
"SKILL":"Compétence",
|
||||
"SKILLS":"Compétences",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Maîtrise",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Non Maîtrisée",
|
||||
"SKIN":"Peau",
|
||||
"SLASHING":"tranchant",
|
||||
"SLEIGHTOFHAND":"Escamotage",
|
||||
"SMALL":"Petite",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Ensorceleur",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Cible",
|
||||
"SPECIAL":"Spécial",
|
||||
"SPECIAL_EFFECTS":"Effects spéciaux",
|
||||
"SPEED":"Vitesse",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Discrétion",
|
||||
"STR":"For",
|
||||
"STRENGTH":"Force",
|
||||
"STR_13":"For 13",
|
||||
"STR_15":"For 15",
|
||||
"SUCCESSES":"Réussites",
|
||||
"SURVIVAL":"Survie",
|
||||
"SWIM":"Vitesse de nage",
|
||||
"TARGET":"Cible",
|
||||
"TARGET_TO_SOURCE":"Cible → Source",
|
||||
"TEXT_SIZE":"Taille de texte",
|
||||
"THUNDER":"tonnerre",
|
||||
"TINY":"Très Petite",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,9 +67,8 @@
|
||||
"ATTACHERS":"Aggiunte",
|
||||
"ATTACK":"Attacco",
|
||||
"ATTACKS":"Attacchi",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Ripristina (s)vantaggio automaticamente",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"AVERAGE_OF_ABILITIES":"Average of the highest 1 or 2 abilities",
|
||||
"BACKGROUND":"Background",
|
||||
"BARBARIAN":"Barbaro",
|
||||
"BARD":"Bardo",
|
||||
@@ -332,15 +331,15 @@
|
||||
"CON":"Cos",
|
||||
"CONC":"Conc.",
|
||||
"CONCENTRATION":"Concentrazione",
|
||||
"CONCENTRATION_UP_TO_10_MINUTES":"Concentration, up to 10 minute",
|
||||
"CONCENTRATION_UP_TO_12_HOURS":"Concentration, up to 12 hours",
|
||||
"CONCENTRATION_UP_TO_1_HOUR":"Concentration, up to 1 hour",
|
||||
"CONCENTRATION_UP_TO_1_MINUTE":"Concentration, up to 1 minute",
|
||||
"CONCENTRATION_UP_TO_1_ROUND":"Concentration, up to 1 round",
|
||||
"CONCENTRATION_UP_TO_24_HOURS":"Concentration, up to 24 hours",
|
||||
"CONCENTRATION_UP_TO_2_HOURS":"Concentration, up to 2 hours",
|
||||
"CONCENTRATION_UP_TO_6_ROUNDS":"Concentration, up to 6 rounds",
|
||||
"CONCENTRATION_UP_TO_8_HOURS":"Concentration, up to 8 hours",
|
||||
"CONCENTRATION_UP_TO_10_MINUTES":"fino a 10 minuti",
|
||||
"CONCENTRATION_UP_TO_12_HOURS":"fino a 12 ore",
|
||||
"CONCENTRATION_UP_TO_1_HOUR":"fino a 1 ora",
|
||||
"CONCENTRATION_UP_TO_1_MINUTE":"fino a 1 minuto",
|
||||
"CONCENTRATION_UP_TO_1_ROUND":"fino a 1 round",
|
||||
"CONCENTRATION_UP_TO_24_HOURS":"fino a 24 ore",
|
||||
"CONCENTRATION_UP_TO_2_HOURS":"fino a 2 ore",
|
||||
"CONCENTRATION_UP_TO_6_ROUNDS":"fino a 6 round",
|
||||
"CONCENTRATION_UP_TO_8_HOURS":"fino a 8 ore",
|
||||
"CONDENSE":"Riduci",
|
||||
"CONDITION_IMMUNITIES":"Immunità alle condizioni",
|
||||
"CONJURATION":"Invocazione",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Morte",
|
||||
"EXPERIENCE_POINTS":"Punti esperienza",
|
||||
"EXPERTISE":"Perizia",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extra",
|
||||
"EYES":"Occhi",
|
||||
"FAILURES":"Fallimenti",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Cura di",
|
||||
"HEAVY_ARMOR":"Armatura pesante",
|
||||
"HEIGHT":"Altezza",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Nascondi info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Nasc. testo azione",
|
||||
"HIDE_INFO_ATTACK":"Nasc. attacco",
|
||||
"HIDE_INFO_DAMAGE":"Nasc. danni",
|
||||
"HIDE_INFO_EFFECT":"Nasc. effetto",
|
||||
"HIDE_INFO_FREETEXT":"Nasc. testo",
|
||||
"HIDE_INFO_NOTE":"Controllare la documentazione. È necessaria un'estenzione nel browser per cambiare il css per mostrare certe parti",
|
||||
"HIDE_INFO_RECHARGE":"Nasc. ricarica",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"Se il bersaglio è",
|
||||
"ILLUSION":"Illusione",
|
||||
"IMPORT":"Importa",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Iniziativa",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Bonus Iniziativa",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Armatura media",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Armatura media max DES",
|
||||
"MELEE":"Mischia",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Varie",
|
||||
"MISCELLANEOUS":"Varie",
|
||||
"MISCELLANEOUS_NOTES":"Note",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Altro",
|
||||
"OTHER_ARMOR":"Altra armatura",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Altre competenze e lingue",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladino",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Prova passiva di caratteristica",
|
||||
"PC":"PG",
|
||||
"PERCEPTION":"Percezione",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiante",
|
||||
"RANGE":"Portata",
|
||||
"RANGED":"A distanza",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Portata",
|
||||
"REACTION":"Reazione",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Taglia",
|
||||
"SKILL":"Abilità",
|
||||
"SKILLS":"Abilità",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Perizia",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Competente",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Non competente",
|
||||
"SKIN":"Pelle",
|
||||
"SLASHING":"tagliente",
|
||||
"SLEIGHTOFHAND":"Agilità di mano",
|
||||
"SMALL":"Piccola",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Stregone",
|
||||
"SOURCE":"Fonte",
|
||||
"SOURCE_TO_TARGET":"Fonte → Bersaglio",
|
||||
"SPECIAL":"Speciale",
|
||||
"SPECIAL_EFFECTS":"Effetti speciali",
|
||||
"SPEED":"Velocità",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Furtività",
|
||||
"STR":"For",
|
||||
"STRENGTH":"Forza",
|
||||
"STR_13":"For 13",
|
||||
"STR_15":"For 15",
|
||||
"SUCCESSES":"Successi",
|
||||
"SURVIVAL":"Sopravvivenza",
|
||||
"SWIM":"Nuotare",
|
||||
"TARGET":"Bersaglio",
|
||||
"TARGET_TO_SOURCE":"Bersaglio → Fonte",
|
||||
"TEXT_SIZE":"Dimensione testo",
|
||||
"THUNDER":"tuono",
|
||||
"TINY":"Minuscola",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Нападки",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Эксперт",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Глаза",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Рост",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Другое",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Результат",
|
||||
"PALADIN":"Паладин",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Следопыт",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Размер",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Навыки",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Кожа",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Чародей",
|
||||
"SOURCE":"Источник",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Сила",
|
||||
"STRENGTH":"Сила",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -67,7 +67,6 @@
|
||||
"ATTACHERS":"Attachers",
|
||||
"ATTACK":"Attack",
|
||||
"ATTACKS":"Attacks",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"Attacks vs a saving throw",
|
||||
"AUTO_REVERT_ADV":"Automatically revert (dis)advantage",
|
||||
"AVERAGE_OF_ABILITIES":"Average of abilities",
|
||||
"BACKGROUND":"Background",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"Death",
|
||||
"EXPERIENCE_POINTS":"Experience points",
|
||||
"EXPERTISE":"Expertise",
|
||||
"EXPERTISE_AS_ADVANTAGE":"Expertise as Advantage when importing",
|
||||
"EXTRAS":"Extras",
|
||||
"EYES":"Eyes",
|
||||
"FAILURES":"Failures",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"Heal for",
|
||||
"HEAVY_ARMOR":"Heavy Armor",
|
||||
"HEIGHT":"Height",
|
||||
"HIDE_AC":"Hide AC",
|
||||
"HIDE_INFO":"Hide info",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"Hide ability checks",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"Hide action freetext",
|
||||
"HIDE_INFO_ATTACK":"Hide attack",
|
||||
"HIDE_INFO_DAMAGE":"Hide damage",
|
||||
"HIDE_INFO_EFFECT":"Hide effect",
|
||||
"HIDE_INFO_FREETEXT":"Hide freetext",
|
||||
"HIDE_INFO_NOTE":"Please see the documentation. You'll need to use a browser extension to change the css to show certain parts",
|
||||
"HIDE_INFO_RECHARGE":"Hide recharge",
|
||||
"HIDE_INFO_SAVING_THROWS":"Hide saving throws",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"If the target is",
|
||||
"ILLUSION":"Illusion",
|
||||
"IMPORT":"Import",
|
||||
"INFLUENCE":"Influence",
|
||||
"INITIATIVE":"Initiative",
|
||||
"INITIATIVE_ABILITY":"Initiative ability",
|
||||
"INITIATIVE_BONUS":"Initiative bonus",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"Medium Armor",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"Medium armor max dex",
|
||||
"MELEE":"Melee",
|
||||
"MELEE_WEAPON":"Melee weapon (thrown)",
|
||||
"MISC":"Misc",
|
||||
"MISCELLANEOUS":"Miscellaneous",
|
||||
"MISCELLANEOUS_NOTES":"Miscellaneous notes",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"Other",
|
||||
"OTHER_ARMOR":"Other Armor",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"Other Proficiencies & Languages",
|
||||
"OTHER_TYPE":"Other (AoE, Cone, Line)",
|
||||
"OUTPUT":"Output",
|
||||
"PALADIN":"Paladin",
|
||||
"PASSIVE":"Passive",
|
||||
"PASSIVE_ABILITY_CHECK":"Passive ability check",
|
||||
"PC":"PC",
|
||||
"PERCEPTION":"Perception",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"radiant",
|
||||
"RANGE":"Range",
|
||||
"RANGED":"Ranged",
|
||||
"RANGED_WEAPON":"Ranged weapon",
|
||||
"RANGER":"Ranger",
|
||||
"REACH":"Reach",
|
||||
"REACTION":"Reaction",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"Size",
|
||||
"SKILL":"Skill",
|
||||
"SKILLS":"Skills",
|
||||
"SKILL_SELECT_EXPERTISE":"✗ Expertise",
|
||||
"SKILL_SELECT_PROFICIENT":"✓ Proficient",
|
||||
"SKILL_SELECT_UNPROFICIENT":"— Unproficient",
|
||||
"SKIN":"Skin",
|
||||
"SLASHING":"slashing",
|
||||
"SLEIGHTOFHAND":"Sleight of Hand",
|
||||
"SMALL":"Small",
|
||||
"SOCIETY":"Society",
|
||||
"SORCERER":"Sorcerer",
|
||||
"SOURCE":"Source",
|
||||
"SOURCE_TO_TARGET":"Source → Target",
|
||||
"SPECIAL":"Special",
|
||||
"SPECIAL_EFFECTS":"Special effects",
|
||||
"SPEED":"Speed",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"Stealth",
|
||||
"STR":"Str",
|
||||
"STRENGTH":"Strength",
|
||||
"STR_13":"Str 13",
|
||||
"STR_15":"Str 15",
|
||||
"SUCCESSES":"Successes",
|
||||
"SURVIVAL":"Survival",
|
||||
"SWIM":"Swim",
|
||||
"TARGET":"Target",
|
||||
"TARGET_TO_SOURCE":"Target → Source",
|
||||
"TEXT_SIZE":"Text size",
|
||||
"THUNDER":"thunder",
|
||||
"TINY":"Tiny",
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
"AC_ARMORED":"crwdns6862:0crwdne6862:0",
|
||||
"AC_UNARMORED":"crwdns6863:0crwdne6863:0",
|
||||
"AC_UNARMORED_ABILITY":"crwdns6864:0crwdne6864:0",
|
||||
"ADD_HALF_PROFICIENCY_TO_UNPROFICIENT_SAVING_THROWS":"crwdns6865:0crwdne6865:0",
|
||||
"ADD_HALF_PROFICIENCY_TO_UNPROFICIENT_SAVING_THROWS":"crwdns8213:0crwdne8213:0",
|
||||
"ADVANTAGE":"crwdns6866:0crwdne6866:0",
|
||||
"AGE":"crwdns6867:0crwdne6867:0",
|
||||
"ALIGNMENT":"crwdns6868:0crwdne6868:0",
|
||||
@@ -67,9 +67,8 @@
|
||||
"ATTACHERS":"crwdns6881:0crwdne6881:0",
|
||||
"ATTACK":"crwdns6882:0crwdne6882:0",
|
||||
"ATTACKS":"crwdns6883:0crwdne6883:0",
|
||||
"ATTACKS_VS_A_SAVING_THROW":"crwdns7781:0crwdne7781:0",
|
||||
"AUTO_REVERT_ADV":"crwdns6884:0crwdne6884:0",
|
||||
"AVERAGE_OF_ABILITIES":"crwdns8197:0crwdne8197:0",
|
||||
"AVERAGE_OF_ABILITIES":"crwdns8214:0crwdne8214:0",
|
||||
"BACKGROUND":"crwdns6885:0crwdne6885:0",
|
||||
"BARBARIAN":"crwdns6886:0crwdne6886:0",
|
||||
"BARD":"crwdns6887:0crwdne6887:0",
|
||||
@@ -350,7 +349,7 @@
|
||||
"CORE":"crwdns7143:0crwdne7143:0",
|
||||
"CRIT":"crwdns7144:0crwdne7144:0",
|
||||
"CRIT_ATTACHER_TOOLTIP":"crwdns7145:0crwdne7145:0",
|
||||
"CRIT_DAMAGE_TOOLTIP":"crwdns7146:0crwdne7146:0",
|
||||
"CRIT_DAMAGE_TOOLTIP":"crwdns8215:0crwdne8215:0",
|
||||
"CRIT_RANGE":"crwdns7147:0crwdne7147:0",
|
||||
"CURRENT":"crwdns7148:0crwdne7148:0",
|
||||
"CUSTOM":"crwdns7149:0crwdne7149:0",
|
||||
@@ -399,6 +398,7 @@
|
||||
"EXHAUSTION_LEVEL_6":"crwdns7189:0crwdne7189:0",
|
||||
"EXPERIENCE_POINTS":"crwdns7190:0crwdne7190:0",
|
||||
"EXPERTISE":"crwdns7191:0crwdne7191:0",
|
||||
"EXPERTISE_AS_ADVANTAGE":"crwdns8216:0crwdne8216:0",
|
||||
"EXTRAS":"crwdns7192:0crwdne7192:0",
|
||||
"EYES":"crwdns7193:0crwdne7193:0",
|
||||
"FAILURES":"crwdns7194:0crwdne7194:0",
|
||||
@@ -428,13 +428,12 @@
|
||||
"HEAL_FOR":"crwdns7214:0crwdne7214:0",
|
||||
"HEAVY_ARMOR":"crwdns7215:0crwdne7215:0",
|
||||
"HEIGHT":"crwdns7216:0crwdne7216:0",
|
||||
"HIDE_AC":"crwdns7805:0crwdne7805:0",
|
||||
"HIDE_INFO":"crwdns7806:0crwdne7806:0",
|
||||
"HIDE_INFO_ABILITY_CHECKS":"crwdns7807:0crwdne7807:0",
|
||||
"HIDE_INFO_ACTION_FREETEXT":"crwdns7808:0crwdne7808:0",
|
||||
"HIDE_INFO_ATTACK":"crwdns7809:0crwdne7809:0",
|
||||
"HIDE_INFO_DAMAGE":"crwdns7810:0crwdne7810:0",
|
||||
"HIDE_INFO_EFFECT":"crwdns7811:0crwdne7811:0",
|
||||
"HIDE_INFO_FREETEXT":"crwdns8217:0crwdne8217:0",
|
||||
"HIDE_INFO_NOTE":"crwdns7812:0crwdne7812:0",
|
||||
"HIDE_INFO_RECHARGE":"crwdns7813:0crwdne7813:0",
|
||||
"HIDE_INFO_SAVING_THROWS":"crwdns7814:0crwdne7814:0",
|
||||
@@ -456,6 +455,7 @@
|
||||
"IF_THE_TARGET_IS":"crwdns7433:0crwdne7433:0",
|
||||
"ILLUSION":"crwdns7238:0crwdne7238:0",
|
||||
"IMPORT":"crwdns7239:0crwdne7239:0",
|
||||
"INFLUENCE":"crwdns8218:0crwdne8218:0",
|
||||
"INITIATIVE":"crwdns7240:0crwdne7240:0",
|
||||
"INITIATIVE_ABILITY":"crwdns8207:0crwdne8207:0",
|
||||
"INITIATIVE_BONUS":"crwdns7241:0crwdne7241:0",
|
||||
@@ -490,6 +490,7 @@
|
||||
"MEDIUM_ARMOR":"crwdns7268:0crwdne7268:0",
|
||||
"MEDIUM_ARMOR_MAX_DEX":"crwdns7269:0crwdne7269:0",
|
||||
"MELEE":"crwdns7270:0crwdne7270:0",
|
||||
"MELEE_WEAPON":"crwdns8219:0crwdne8219:0",
|
||||
"MISC":"crwdns7271:0crwdne7271:0",
|
||||
"MISCELLANEOUS":"crwdns7272:0crwdne7272:0",
|
||||
"MISCELLANEOUS_NOTES":"crwdns7273:0crwdne7273:0",
|
||||
@@ -508,8 +509,10 @@
|
||||
"OTHER":"crwdns7284:0crwdne7284:0",
|
||||
"OTHER_ARMOR":"crwdns7285:0crwdne7285:0",
|
||||
"OTHER_PROFICIENCIES_AND_LANGUAGES":"crwdns7286:0crwdne7286:0",
|
||||
"OTHER_TYPE":"crwdns8220:0crwdne8220:0",
|
||||
"OUTPUT":"crwdns7287:0crwdne7287:0",
|
||||
"PALADIN":"crwdns7289:0crwdne7289:0",
|
||||
"PASSIVE":"crwdns8221:0crwdne8221:0",
|
||||
"PASSIVE_ABILITY_CHECK":"crwdns7441:0crwdne7441:0",
|
||||
"PC":"crwdns7290:0crwdne7290:0",
|
||||
"PERCEPTION":"crwdns7291:0crwdne7291:0",
|
||||
@@ -533,6 +536,7 @@
|
||||
"RADIANT":"crwdns7308:0crwdne7308:0",
|
||||
"RANGE":"crwdns7309:0crwdne7309:0",
|
||||
"RANGED":"crwdns7310:0crwdne7310:0",
|
||||
"RANGED_WEAPON":"crwdns8222:0crwdne8222:0",
|
||||
"RANGER":"crwdns7311:0crwdne7311:0",
|
||||
"REACH":"crwdns7312:0crwdne7312:0",
|
||||
"REACTION":"crwdns7313:0crwdne7313:0",
|
||||
@@ -577,12 +581,17 @@
|
||||
"SIZE":"crwdns7346:0crwdne7346:0",
|
||||
"SKILL":"crwdns7347:0crwdne7347:0",
|
||||
"SKILLS":"crwdns7348:0crwdne7348:0",
|
||||
"SKILL_SELECT_EXPERTISE":"crwdns8223:0crwdne8223:0",
|
||||
"SKILL_SELECT_PROFICIENT":"crwdns8224:0crwdne8224:0",
|
||||
"SKILL_SELECT_UNPROFICIENT":"crwdns8225:0crwdne8225:0",
|
||||
"SKIN":"crwdns7349:0crwdne7349:0",
|
||||
"SLASHING":"crwdns7350:0crwdne7350:0",
|
||||
"SLEIGHTOFHAND":"crwdns7351:0crwdne7351:0",
|
||||
"SMALL":"crwdns7352:0crwdne7352:0",
|
||||
"SOCIETY":"crwdns8226:0crwdne8226:0",
|
||||
"SORCERER":"crwdns7354:0crwdne7354:0",
|
||||
"SOURCE":"crwdns7355:0crwdne7355:0",
|
||||
"SOURCE_TO_TARGET":"crwdns8227:0crwdne8227:0",
|
||||
"SPECIAL":"crwdns7430:0crwdne7430:0",
|
||||
"SPECIAL_EFFECTS":"crwdns7356:0crwdne7356:0",
|
||||
"SPEED":"crwdns7357:0crwdne7357:0",
|
||||
@@ -600,10 +609,13 @@
|
||||
"STEALTH":"crwdns7369:0crwdne7369:0",
|
||||
"STR":"crwdns7370:0crwdne7370:0",
|
||||
"STRENGTH":"crwdns7371:0crwdne7371:0",
|
||||
"STR_13":"crwdns8228:0crwdne8228:0",
|
||||
"STR_15":"crwdns8229:0crwdne8229:0",
|
||||
"SUCCESSES":"crwdns7372:0crwdne7372:0",
|
||||
"SURVIVAL":"crwdns7373:0crwdne7373:0",
|
||||
"SWIM":"crwdns7374:0crwdne7374:0",
|
||||
"TARGET":"crwdns7375:0crwdne7375:0",
|
||||
"TARGET_TO_SOURCE":"crwdns8230:0crwdne8230:0",
|
||||
"TEXT_SIZE":"crwdns7376:0crwdne7376:0",
|
||||
"THUNDER":"crwdns7377:0crwdne7377:0",
|
||||
"TINY":"crwdns7378:0crwdne7378:0",
|
||||
|
||||
@@ -0,0 +1,577 @@
|
||||
/*----------- Repeating Blocks -------------*/
|
||||
.charsheet .repcontrol_add {
|
||||
display: block;
|
||||
background:#7F2108;
|
||||
color:white;
|
||||
text-shadow:0px 0px 2px #000,0px 0px 2px #000,0px 0px 2px #000;
|
||||
box-shadow:none;
|
||||
float:left!important;
|
||||
margin-bottom:0px;
|
||||
font-size:0.9em;
|
||||
height:2.2em;
|
||||
font-family: Copperplate, 'Copperplate Gothic Light', fantasy;
|
||||
}
|
||||
.charsheet .repcontrol_edit
|
||||
{
|
||||
display: inline-block;
|
||||
background:#7F2108;
|
||||
color:white;
|
||||
text-shadow:0px 0px 2px #000,0px 0px 2px #000,0px 0px 2px #000;
|
||||
box-shadow:none;
|
||||
float:none!important;
|
||||
margin-bottom:5px;
|
||||
font-size:0.9em;
|
||||
height:2.2em;
|
||||
font-family: Copperplate, 'Copperplate Gothic Light', fantasy;
|
||||
}
|
||||
.charsheet .repcontrol_del {
|
||||
background:red;
|
||||
color:white;
|
||||
text-shadow:0px 0px 2px #000,0px 0px 2px #000,0px 0px 2px #000;
|
||||
box-shadow:none;
|
||||
float:none!important;
|
||||
margin-bottom:5px;
|
||||
font-size:0.9em;
|
||||
height:2.2em;
|
||||
}
|
||||
.charsheet .repcontrol_move {
|
||||
display: inline-block;
|
||||
background:#08667f;
|
||||
color:white;
|
||||
text-shadow:0px 0px 2px #000,0px 0px 2px #000,0px 0px 2px #000;
|
||||
box-shadow:none;
|
||||
float:none!important;
|
||||
margin-bottom:5px;
|
||||
font-size:0.9em;
|
||||
height:1.4em;
|
||||
padding-top:3px;
|
||||
padding-bottom:3px;
|
||||
}
|
||||
/*----------- End of Repeating Blocks -------------*//*=======================Tabs=======================*/
|
||||
|
||||
div.sheet-tab-content {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input.sheet-tab1:checked ~ div.sheet-tab1,
|
||||
input.sheet-tab2:checked ~ div.sheet-tab2,
|
||||
input.sheet-tab3:checked ~ div.sheet-tab3,
|
||||
input.sheet-tab4:checked ~ div.sheet-tab4,
|
||||
input.sheet-tab5:checked ~ div.sheet-tab5,
|
||||
input.sheet-tab6:checked ~ div.sheet-tab6,
|
||||
input.sheet-tab7:checked ~ div.sheet-tab7 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input.sheet-tab {
|
||||
width: 130px;
|
||||
height: 20px;
|
||||
position: relative;
|
||||
left: 6px;
|
||||
margin: 0px ;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
border-radius: 5px 5px 5px 5px;
|
||||
}
|
||||
|
||||
input.sheet-tab::before
|
||||
{
|
||||
content: attr(title);
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
color:white;
|
||||
text-shadow:0px 0px 0.5em black;
|
||||
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
|
||||
background: #fff;
|
||||
background: -moz-linear-gradient(to top, #fff, #B35439, #fff);
|
||||
background: -webkit-linear-gradient(to top, #fff, #B35439, #fff);
|
||||
background: -ms-linear-gradient(to top, #fff, #B35439, #fff);
|
||||
background: -o-linear-gradient(to top, #fff, #B35439, #fff);
|
||||
background: linear-gradient(to top, #fff, #B35439, #fff);
|
||||
|
||||
width: 130px;
|
||||
height: 20px;
|
||||
font-size: 16px;
|
||||
font-weight:700;
|
||||
border-radius: 15px 15px 15px 15px;
|
||||
|
||||
border:1px solid black;
|
||||
|
||||
}
|
||||
|
||||
input.sheet-tab:checked::before
|
||||
{
|
||||
background: #dcdcdc;
|
||||
background: -moz-linear-gradient(to top, #B35439, #000, #B35439);
|
||||
background: -webkit-linear-gradient(to top, #B35439, #000, #B35439);
|
||||
background: -ms-linear-gradient(to top, #B35439, #000, #B35439);
|
||||
background: -o-linear-gradient(to top, #B35439, #000, #B35439);
|
||||
background: linear-gradient(to top, #B35439, #000, #B35439);
|
||||
/* border-bottom-color: #fff; */
|
||||
text-shadow:0px 0px 0.5em black,0px 0px 0.5em black;
|
||||
}
|
||||
|
||||
input.sheet-tab:not(:first-child)::before
|
||||
{
|
||||
border-left: none;
|
||||
}
|
||||
|
||||
div.sheet-tab-content {
|
||||
width: 835px;
|
||||
background:white;
|
||||
box-shadow: inset 0px 0px 10px #B35439, inset 0px 0px 8px #B35439,inset 0px 0px 4px #B35439;
|
||||
padding: 5px;
|
||||
border-radius:15px;
|
||||
margin-right:auto;
|
||||
margin-left:auto;
|
||||
}
|
||||
div.sheet-top_bar {
|
||||
width: 835px;
|
||||
background:white;
|
||||
box-shadow: inset 0px 0px 10px #B35439, inset 0px 0px 8px #B35439,inset 0px 0px 4px #B35439;
|
||||
padding: 5px;
|
||||
border-radius:15px;
|
||||
margin-right:auto;
|
||||
margin-left:auto;
|
||||
}
|
||||
/*=======================End of tabs=======================*/
|
||||
/*----------- Font Face -------------*/
|
||||
@font-face {
|
||||
font-family: 'GreatVibesRegular';
|
||||
src: url('http://openfontlibrary.org/assets/fonts/rebecca/d32a4d9e4887fccf9ce200538290cd10/53e7427de4aaa693950c7a9c35de80e2/GreatVibesRegular.otf');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
/*----------- End of Font Face -------------*/
|
||||
/*----------- Banner -------------*/
|
||||
.sheet-banner {
|
||||
background: url('http://www.atlas-games.com/images/ArM5LogoColor.jpg');
|
||||
background-size: 100%;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right bottom;
|
||||
}
|
||||
|
||||
.sheet-banner-content {
|
||||
margin: 0;
|
||||
height: 100px;
|
||||
width: 200px;
|
||||
}
|
||||
/*----------- End of Banner -------------*/
|
||||
/*----------- background -------------*/
|
||||
.charsheet {
|
||||
background:black;
|
||||
width:850px;
|
||||
}
|
||||
/*----------- End of background -------------*/
|
||||
/*----------- Text -------------*/
|
||||
.sheet-heading {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
font-weight:bold;
|
||||
font-size:1.3em;
|
||||
}
|
||||
|
||||
.sheet-heading_1 {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
font-size:1.3em;
|
||||
line-height:1.4em;
|
||||
border-top: none;
|
||||
border-bottom: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
width:200px;
|
||||
}
|
||||
|
||||
textarea.sheet-textarea_3:hover,textarea.sheet-textarea_3:focus,
|
||||
textarea.sheet-textarea_2:hover,textarea.sheet-textarea_2:focus,
|
||||
textarea.sheet-textarea_1:hover,textarea.sheet-textarea_1:focus,
|
||||
.sheet-number_1:hover, .sheet-number_1:focus,
|
||||
.sheet-heading_2:hover, .sheet-heading_2:focus,
|
||||
.sheet-heading_3:hover, .sheet-heading_3:focus,
|
||||
.sheet-heading_1:hover, .sheet-heading_1:focus {
|
||||
box-shadow: inset -9px -8px 18px -4px #B35439;
|
||||
text-shadow: 0px 0px 5px white, 0px 0px 5px white, 0px 0px 5px white;
|
||||
}
|
||||
.sheet-heading_2 {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
font-size:1.1em;
|
||||
line-height:1.2em;
|
||||
|
||||
border: none;
|
||||
|
||||
width:160px;
|
||||
}
|
||||
.sheet-heading_3 {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
font-size:1.1em;
|
||||
line-height:1.2em;
|
||||
|
||||
border: none;
|
||||
|
||||
width:200px;
|
||||
}
|
||||
.sheet-heading_4 {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
font-size:1.1em;
|
||||
line-height:1.2em;
|
||||
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid black;
|
||||
|
||||
width:120px;
|
||||
}
|
||||
.sheet-number_1 {
|
||||
width:60px;
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
font-size:1.3em;
|
||||
line-height:1.4em;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid black;
|
||||
box-shadow: none;
|
||||
background:transparent;
|
||||
}
|
||||
.sheet-number_2 {
|
||||
width:40px;
|
||||
font-family: Copperplate, 'Copperplate Gothic Light', fantasy;
|
||||
font-size:1.1em;
|
||||
line-height:1.2em;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid black;
|
||||
box-shadow: none;
|
||||
background:transparent;
|
||||
}
|
||||
|
||||
.sheet-number_2:disabled {
|
||||
background: black;
|
||||
color:white;
|
||||
}
|
||||
.sheet-counter {
|
||||
width:90px;
|
||||
font-family: Copperplate, 'Copperplate Gothic Light', fantasy;
|
||||
font-size:1.1em;
|
||||
line-height:1.2em;
|
||||
border-top: none;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
border-bottom: 1px solid black;
|
||||
box-shadow: none;
|
||||
background:transparent;
|
||||
text-shadow: 0px 0px 10px white;
|
||||
color:black;
|
||||
font-weight:700;
|
||||
}
|
||||
|
||||
input.sheet-counter[type=number]::-webkit-inner-spin-button,
|
||||
input.sheet-counter[type=number]::-webkit-outer-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
.sheet-heading_label {
|
||||
margin-left:0px;
|
||||
margin-bottom:-6px;
|
||||
padding-left: 10px;
|
||||
border: 1px solid #B35439;
|
||||
border-radius: 15px 15px 0px 0px;
|
||||
background:#B35439;
|
||||
text-shadow: 0px 0px 5px white, 0px 0px 5px white, 0px 0px 5px white;
|
||||
width:155px;
|
||||
}
|
||||
/*----------- End of Text -------------*/
|
||||
/*----------- Tables -------------*/
|
||||
.sheet-table_1 th {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
}
|
||||
.sheet-table_2 {
|
||||
border: 1px solid black;
|
||||
margin-top:5px;
|
||||
margin-bottom:5px;
|
||||
|
||||
}
|
||||
.sheet-table_2 th {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
/*----------- End of Tables -------------*/
|
||||
/*----------- textarea -------------*/
|
||||
textarea.sheet-textarea_1 {
|
||||
width: 200px;
|
||||
resize:vertical;
|
||||
height:90px;
|
||||
border:1px dotted #d3d3d3;
|
||||
border-radius:15px;
|
||||
}
|
||||
textarea.sheet-textarea_2 {
|
||||
width: 400px;
|
||||
resize:vertical;
|
||||
height:45px;
|
||||
border:1px dotted #d3d3d3;
|
||||
border-radius:15px;
|
||||
}
|
||||
textarea.sheet-textarea_3 {
|
||||
width: 180px;
|
||||
resize:vertical;
|
||||
height:30px;
|
||||
border:1px dotted #d3d3d3;
|
||||
border-radius:15px;
|
||||
}
|
||||
/*----------- End of textarea -------------*/
|
||||
/*----------- Select -------------*/
|
||||
select.sheet-select_1 {
|
||||
-webkit-appearance: none;
|
||||
padding-top:0px;
|
||||
padding-right:0px;
|
||||
appearance: none;
|
||||
margin-bottom: 0;
|
||||
width:110px;
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
}
|
||||
|
||||
select {
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
select *.sheet-italic {
|
||||
font-style:italic;
|
||||
}
|
||||
/*----------- End of Select -------------*/
|
||||
/*----------- Hide Things -------------*/
|
||||
.sheet-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
input.sheet-hider:checked ~ div.sheet-hide {
|
||||
display: none;
|
||||
}
|
||||
/*----------- End of Hide Things -------------*/
|
||||
/*----------- Checkbox -------------*/
|
||||
/* Hide actual checkbox */
|
||||
|
||||
input.sheet-checkbox_3[type="checkbox"],
|
||||
input.sheet-checkbox_2[type="checkbox"],
|
||||
input.sheet-checkbox_1[type="checkbox"] {
|
||||
opacity: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: 8px;
|
||||
margin:0px;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Fake checkbox */
|
||||
input.sheet-checkbox_2[type="checkbox"] + span::before,
|
||||
input.sheet-checkbox_1[type="checkbox"] + span::before {
|
||||
margin-right: 4px;
|
||||
border: solid 1px #a8a8a8;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
-moz-box-shadow: 0 0 2px #ccc;
|
||||
-webkit-box-shadow: 0 0 2px #ccc;
|
||||
box-shadow: 0 0 2px #ccc;
|
||||
|
||||
background: #f6f6f6;
|
||||
background: -moz-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: -webkit-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: -ms-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: -o-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: radial-gradient(#f6f6f6, #dfdfdf);
|
||||
}
|
||||
|
||||
/* Fake checkbox */
|
||||
input.sheet-checkbox_2[type="checkbox"] + span::before,
|
||||
input.sheet-checkbox_1[type="checkbox"] + span::before {
|
||||
content: "";
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
font-size: 12px;
|
||||
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
input.sheet-checkbox_1[type="checkbox"] + span::before {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
margin:-10px;
|
||||
}
|
||||
|
||||
input.sheet-checkbox_2[type="checkbox"] + span::before {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
margin:-10px;
|
||||
}
|
||||
input.sheet-checkbox_1[type="checkbox"]:checked + span::before {
|
||||
content: "✓";
|
||||
}
|
||||
input.sheet-checkbox_2[type="checkbox"]:checked + span::before {
|
||||
content: "x";
|
||||
color:red;
|
||||
|
||||
} /* Fake checkbox */
|
||||
input.sheet-checkbox_3[type="checkbox"] + span::before {
|
||||
margin-right: 4px;
|
||||
border: solid 1px #a8a8a8;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
-moz-box-shadow: 0 0 2px #ccc;
|
||||
-webkit-box-shadow: 0 0 2px #ccc;
|
||||
box-shadow: 0 0 2px #ccc;
|
||||
|
||||
background: #f6f6f6;
|
||||
}
|
||||
|
||||
/* Fake checkbox */
|
||||
input.sheet-checkbox_3[type="checkbox"] + span::before {
|
||||
content: "";
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
font-size: 12px;
|
||||
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
/*----------- Radio -------------*/
|
||||
|
||||
/* Hide actual radio */
|
||||
input.sheet-radio_2[type="radio"],
|
||||
input.sheet-radio_1[type="radio"] {
|
||||
opacity: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: 8px;
|
||||
margin:0px;
|
||||
cursor: pointer;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* Fake checkbox */
|
||||
input.sheet-radio_2[type="radio"] + span::before,
|
||||
input.sheet-radio_1[type="radio"] + span::before {
|
||||
margin-right: 4px;
|
||||
border: solid 1px #a8a8a8;
|
||||
line-height: 14px;
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
margin:-8px;
|
||||
|
||||
-moz-box-shadow: 0 0 2px #ccc;
|
||||
-webkit-box-shadow: 0 0 2px #ccc;
|
||||
box-shadow: 0 0 2px #ccc;
|
||||
|
||||
background: #f6f6f6;
|
||||
background: -moz-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: -webkit-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: -ms-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: -o-radial-gradient(#f6f6f6, #dfdfdf);
|
||||
background: radial-gradient(#f6f6f6, #dfdfdf);
|
||||
}
|
||||
|
||||
input.sheet-radio_1[type="radio"] + span::before {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: -8px;
|
||||
margin:0px;
|
||||
}
|
||||
|
||||
input.sheet-radio_2[type="radio"] + span::before {
|
||||
position: relative;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
margin:-10px;
|
||||
}
|
||||
|
||||
/* Fake checkbox */
|
||||
input.sheet-radio_2[type="radio"] + span::before,
|
||||
input.sheet-radio_1[type="radio"] + span::before {
|
||||
content: "";
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
font-size: 12px;
|
||||
|
||||
-moz-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
input.sheet-radio_2[type="radio"]:checked + span::before,
|
||||
input.sheet-radio_1[type="radio"]:checked + span::before {
|
||||
content: "x";
|
||||
}
|
||||
|
||||
/*----------- End of Checkbox -------------*/
|
||||
/*----------- Buttons -------------*/
|
||||
button.sheet-button_1:before {
|
||||
content: "" !important;
|
||||
}
|
||||
button.sheet-botch:before{
|
||||
content: "" !important;
|
||||
display: none;
|
||||
}
|
||||
|
||||
button.sheet-botch {
|
||||
font-family: 'GreatVibesRegular', "Shadows Into Light", cursive;
|
||||
color:white;
|
||||
text-shadow:0px 0px 0.5em black;
|
||||
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
|
||||
background: #fff;
|
||||
background: -moz-linear-gradient(to top, #fff, #08667f, #fff);
|
||||
background: -webkit-linear-gradient(to top, #fff, #08667f, #fff);
|
||||
background: -ms-linear-gradient(to top, #fff, #08667f, #fff);
|
||||
background: -o-linear-gradient(to top, #fff, #08667f, #fff);
|
||||
background: linear-gradient(to top, #fff, #08667f, #fff);
|
||||
|
||||
width: 130px;
|
||||
height: 24px;
|
||||
font-size: 16px;
|
||||
line-height:18px;
|
||||
font-weight:700;
|
||||
border-radius: 15px 15px 15px 15px;
|
||||
|
||||
border:1px solid black;
|
||||
}
|
||||
button.sheet-botch:hover {
|
||||
background: #fff;
|
||||
background: -moz-linear-gradient(to top, #08667f, #fff, #08667f);
|
||||
background: -webkit-linear-gradient(to top, #08667f, #fff, #08667f);
|
||||
background: -ms-linear-gradient(to top, #08667f, #fff, #08667f);
|
||||
background: -o-linear-gradient(to top, #08667f, #fff, #08667f);
|
||||
background: linear-gradient(to top, #08667f, #fff, #08667f);
|
||||
}
|
||||
button.sheet-botch:active {
|
||||
background: #fff;
|
||||
background: -moz-linear-gradient(to left, #08667f, #fff, #08667f);
|
||||
background: -webkit-linear-gradient(to left, #08667f, #fff, #08667f);
|
||||
background: -ms-linear-gradient(to left, #08667f, #fff, #08667f);
|
||||
background: -o-linear-gradient(to left, #08667f, #fff, #08667f);
|
||||
background: linear-gradient(to left, #08667f, #fff, #08667f);
|
||||
}
|
||||
|
||||
|
||||
/*----------- End of Buttons -------------*/
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 118 KiB |
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"html": "Ars_Magica_5th.html",
|
||||
"css": "Ars_Magica_5th.css",
|
||||
"authors": "Coal Powered Puppet.",
|
||||
"roll20userid": "492849",
|
||||
"preview": "Ars_Magica_5th.png",
|
||||
"instructions": "#Ars Magica 5th \r \r **For use with Ars Magica 5th edition** \r \r Chrome Users must load unsafe scripts to see ultra-cool Font. \r\r If there's something you want added, or you'd like to report a bug, please contact the author of this sheet. "
|
||||
}
|
||||
@@ -0,0 +1,461 @@
|
||||
.sheet-characteristic-roll{
|
||||
font-size: 0.8em !important;
|
||||
margin-left: 3px;
|
||||
margin-right: 3px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0px;
|
||||
|
||||
}
|
||||
.sheet-skills-header{
|
||||
margin-bottom: 8px;
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.charsheet{
|
||||
background-color: lightgray;
|
||||
}
|
||||
|
||||
/*Hide stuff*/
|
||||
|
||||
|
||||
.charsheet div.sheet-skills-magic1{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-toggle-magic1:checked ~ div.sheet-skills-magic1 {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.charsheet div.sheet-strike-rank{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-showstrike-rank:checked ~ div.sheet-strike-rank {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.charsheet span.sheet-strike-rank{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-showstrike-rank:checked ~ span.sheet-strike-rank {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
input.sheet-showstrike-rank:checked ~ .repcontainer[data-groupname="repeating_Hand-to-Hand"] sheet-strike-rank {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div[data-groupname="repeating_Hand-to-Hand"] .sheet-strike-rank
|
||||
{
|
||||
display: inline-block;
|
||||
border: 5px solid green;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
.sheet-melee-toggle { display: none; }
|
||||
.sheet-check-melee-toggle:checked ~ [data-groupname=repeating_melee] > .repitem .sheet-melee-toggle { display: inline; }
|
||||
|
||||
|
||||
.sheet-example-toggle { display: none; }
|
||||
.sheet-check-toggle:checked ~ [data-groupname=repeating_example] > .repitem .sheet-example-toggle { display: inline; }
|
||||
|
||||
|
||||
.sheet-repeat-strike-rank{ display: none; border: 5px soild pink; }
|
||||
.sheet-showstrike-rank:checked ~ [data-groupname=repeating_Hand-to-Hand] > .repitem .sheet-repeat-strike-rank { display: inline; }
|
||||
|
||||
|
||||
/*
|
||||
input.sheet-collapse-example::checked ~ .repcontainer[data-groupname=repeating_example] .repeating-content {
|
||||
display: none;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
.charsheet div.sheet-skills-alphabetical{
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-toggle-alphabetical:not(:checked) ~ div.sheet-skills-alphabetical {
|
||||
display: none;
|
||||
*/
|
||||
|
||||
.charsheet div.sheet-skills-alphabetical{
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
.charsheet input.sheet-toggle-alphabetical:checked ~ div.sheet-skills-alphabetical {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.charsheet div.sheet-skills-by-category{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-toggle-categories:checked ~ div.sheet-skills-by-category {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.charsheet div.sheet-strike-rank{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-showstrike-rank:checked ~ div.sheet-strike-rank {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.charsheet div.sheet-hpbl {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-showhbpl:checked ~ div.sheet-hpbl {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
.charsheet div.sheet-hitloc{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-showhitloc:checked ~ div.sheet-hitloc {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
|
||||
.charsheet div.sheet-edufld{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-showedufld:checked ~ div.sheet-edufld {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.charsheet div.sheet-mjrwnd{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-showmjrwnd:checked ~ div.sheet-mjrwnd {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* Configuration Window*/
|
||||
.charsheet .sheet-cdiv {
|
||||
width:810px;
|
||||
/*border: 1px dotted;*/
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
}
|
||||
|
||||
.sheet-HideConfig:checked ~ *.sheet-config {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.charsheet span.sheet-is-config::after { /*Close Config: grayish background with black text*/
|
||||
content: "^";
|
||||
}
|
||||
|
||||
.charsheet .sheet-HideConfig:checked + span.sheet-is-config::after { /*Show Configuration: Black background with grayish text*/
|
||||
content: "v";
|
||||
}
|
||||
|
||||
.charsheet span.sheet-is-config {
|
||||
text-align: center;
|
||||
display: inline-block;
|
||||
width: 5%;
|
||||
height: 16px;
|
||||
font-size: 9px;
|
||||
/*font-family: "Pictos";*/
|
||||
/*background: #65763c;*/
|
||||
background: black; /*#93537c;*/
|
||||
color: white; /*white;*/
|
||||
font-weight: bold;
|
||||
border-radius: 4px;
|
||||
margin-left: -5%;
|
||||
}
|
||||
|
||||
.charsheet input.sheet-HideConfig {
|
||||
width: 5%;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
margin-left: auto;
|
||||
margin-top: auto;
|
||||
/*position: absolute;
|
||||
right: 20%;*/
|
||||
opacity: 0;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.charsheet .sheet-HideConfig:checked + span.sheet-is-config {
|
||||
background: black;
|
||||
border-radius: 4px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.charsheet label.sheet-configitem {
|
||||
margin-left: 10px;
|
||||
width: 50px;
|
||||
font-size: .9em;
|
||||
font-weight: normal
|
||||
}
|
||||
|
||||
/*End Configuration Window*/
|
||||
|
||||
.sheet-section-header{
|
||||
text-align: center;
|
||||
color: #FFF;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.sheet-col h3{
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
.repcontrol{
|
||||
margin-right: 7px;
|
||||
}
|
||||
|
||||
div.repcontrol button
|
||||
{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
color: transparent;
|
||||
text-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
div.repcontrol button.repcontrol_add::before,
|
||||
div.repcontrol button.repcontrol_edit::before
|
||||
{
|
||||
font-family: Pictos;
|
||||
position: relative;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* +Add */
|
||||
div.repcontrol button.repcontrol_add::before
|
||||
{
|
||||
|
||||
content: "&"; /* & in Pictos is a + sign, while + is a plus inside a circle */
|
||||
left: -5px;
|
||||
top: -4px;
|
||||
}
|
||||
|
||||
/* Modify */
|
||||
div.repcontrol button.repcontrol_edit::before
|
||||
{
|
||||
text-shadow: 0px 0px 0px rgba(0, 0, 0, 0);
|
||||
content: "x"; /* x in Pictos is a crossed hammer and wrench */
|
||||
left: -5px;
|
||||
top: -4px;
|
||||
}
|
||||
/* Done */
|
||||
div.repcontrol.editmode button.repcontrol_edit::before
|
||||
{
|
||||
content: "3"; /* 3 in Pictos is a check mark */
|
||||
|
||||
}
|
||||
|
||||
.sheet-big-col{
|
||||
width: calc(60% - 20px) !important;
|
||||
}
|
||||
.sheet-small-col{
|
||||
width: calc(40% - 20px) !important;
|
||||
}
|
||||
|
||||
|
||||
.sheet-characteristics
|
||||
{
|
||||
border: 3px solid black;
|
||||
width: 100%
|
||||
}
|
||||
|
||||
.sheet-characteristics p
|
||||
{
|
||||
margin-left: 3px;
|
||||
margin-right: 7px;
|
||||
font-weight: bold;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
button[type="roll"].sheet-plain
|
||||
{
|
||||
width:100%;
|
||||
}
|
||||
button[type="roll"].sheet-plain-major-wound
|
||||
{
|
||||
background: #000;
|
||||
background: -webkit-linear-gradient(#000, #000);
|
||||
background: linear-gradient(#000, #000);
|
||||
border-radius: 5px;
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px 0 #000;
|
||||
font-size: 1.0em;
|
||||
|
||||
}
|
||||
|
||||
button[type="roll"].sheet-plain-major-wound::before
|
||||
{
|
||||
content: "";
|
||||
width: 117px;
|
||||
color: #fff ;
|
||||
background-color: #000
|
||||
|
||||
}
|
||||
|
||||
|
||||
button[type="roll"].sheet-plain::before
|
||||
{
|
||||
content: "";
|
||||
|
||||
}
|
||||
|
||||
|
||||
.sheet-hit-location-selection {
|
||||
color: #ffffff;
|
||||
background-color: #000000;
|
||||
width:100%
|
||||
}
|
||||
|
||||
|
||||
.sheet-hit-location-selection td{
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.sheet-hit-location-selection select{
|
||||
color: #ffffff;
|
||||
background-color: #000000;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
.sheet-loc-text{
|
||||
text-align:left;
|
||||
|
||||
}
|
||||
|
||||
|
||||
.sheet-header-text{
|
||||
font-size: 10px;
|
||||
}
|
||||
.sheet-armor-name{
|
||||
width:100px;
|
||||
}
|
||||
|
||||
|
||||
.sheet-template_value{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.sheet-rolltemplate-HL-Missle th {
|
||||
text-align: centre;
|
||||
color: #ffffff;
|
||||
background-color: #000000;
|
||||
}
|
||||
.sheet-rolltemplate-HL-Missle table {
|
||||
width: 230px;
|
||||
padding: 2px;
|
||||
border: 1px solid;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.sheet-rolltemplate-HL-Melee th {
|
||||
text-align: centre;
|
||||
color: #ffffff;
|
||||
background-color: #000000;
|
||||
}
|
||||
.sheet-rolltemplate-HL-Melee table {
|
||||
width: 230px;
|
||||
padding: 2px;
|
||||
border: 1px solid;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.sheet-rolltemplate-skillRoll th {
|
||||
text-align: centre;
|
||||
color: #ffffff;
|
||||
background-color: #000000;
|
||||
}
|
||||
.sheet-rolltemplate-skillRoll table {
|
||||
width: 230px;
|
||||
padding: 2px;
|
||||
border: 1px solid;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.sheet-rolltemplate-melee-roll th {
|
||||
text-align: centre;
|
||||
color: #ffffff;
|
||||
background-color: #000000;
|
||||
}
|
||||
.sheet-rolltemplate-melee-roll table {
|
||||
width: 230px;
|
||||
padding: 2px;
|
||||
border: 1px solid;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.sheet-rolltemplate-melee-roll .template_value{
|
||||
text-align: right;
|
||||
}
|
||||
.charsheet .sheet-cat_header{
|
||||
font-size:1.3em;
|
||||
}
|
||||
|
||||
.charsheet .sheet-chkfiller{
|
||||
width:12px;
|
||||
}
|
||||
|
||||
.charsheet .sheet-skillname{
|
||||
width:154px;
|
||||
}
|
||||
|
||||
.charsheet .sheet-repeat-skillname{
|
||||
width:151px;
|
||||
}
|
||||
|
||||
.charsheet button[type=roll].sheet-textButton {
|
||||
background-color: transparent;
|
||||
color: black;
|
||||
border: none;
|
||||
font-size: 1.25em;
|
||||
font-weight: bold;
|
||||
text-align: right;
|
||||
background-image: none;
|
||||
text-shadow: none;
|
||||
box-shadow: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
/*margin-top: -5px;*/
|
||||
/*width: 70%;*/
|
||||
}
|
||||
|
||||
.charsheet span.sheet-diceroll {
|
||||
font-family: "dicefontd20";
|
||||
}
|
||||
|
||||
.charsheet button[type=roll].sheet-textButton::before,
|
||||
.charsheet button[type=roll].sheet-powerButton::before {
|
||||
content: "" !important;
|
||||
}
|
||||
|
||||
.charsheet input[type=text].sheet-standard {
|
||||
border-top: none;
|
||||
border-right: none;
|
||||
border-left: none;
|
||||
border-bottom: dotted 1px black;
|
||||
color: black;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 158 KiB |
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user