-
+
-
-
+
@@ -2006,21 +2005,21 @@
- FOR
+ FOR
- DEX
+ DEX
- CON
+ CON
@@ -2029,21 +2028,21 @@
- INT
+ INT
- SAG
+ SAG
- CHA
+ CHA
@@ -2117,7 +2116,7 @@
- Attaques
+ Attaques
Toucher
Crit.
DM
@@ -2143,9 +2142,9 @@
-
-
-
+
+
+
+
@@ -2181,7 +2180,7 @@
-
+
Naturel
Arme 1 main
Arme 2 mains
@@ -2190,7 +2189,7 @@
Arme de jet
-
+
@@ -2462,12 +2461,12 @@
scha = "@{JETNORMAL}";
}
setAttrs({
- FOR_SUP: sfor,
- DEX_SUP: sdex,
- CON_SUP: scon,
- INT_SUP: sint,
- SAG_SUP: ssag,
- CHA_SUP: scha,
+ for_sup: sfor,
+ dex_sup: sdex,
+ con_sup: scon,
+ int_sup: sint,
+ sag_sup: ssag,
+ cha_sup: scha,
});
});
}
@@ -2496,21 +2495,21 @@
}
}
});
- getAttrs(["FOR_SUP", "DEX_SUP", "CON_SUP", "INT_SUP", "SAG_SUP", "CHA_SUP"], function(jets) {
+ getAttrs(["for_sup", "dex_sup", "con_sup", "int_sup", "sag_sup", "cha_sup"], function(jets) {
var sfor, sdex, scon, sint, ssag, scha = "";
- if (jets.FOR_SUP) sfor = jets.FOR_SUP.toLowerCase();
- if (jets.DEX_SUP) sdex = jets.DEX_SUP.toLowerCase();
- if (jets.CON_SUP) scon = jets.CON_SUP.toLowerCase();
- if (jets.INT_SUP) sint = jets.INT_SUP.toLowerCase();
- if (jets.SAG_SUP) ssag = jets.SAG_SUP.toLowerCase();
- if (jets.CHA_SUP) scha = jets.CHA_SUP.toLowerCase();
+ if (jets.for_sup) sfor = jets.for_sup.toLowerCase();
+ if (jets.dex_sup) sdex = jets.dex_sup.toLowerCase();
+ if (jets.con_sup) scon = jets.con_sup.toLowerCase();
+ if (jets.int_sup) sint = jets.int_sup.toLowerCase();
+ if (jets.sag_sup) ssag = jets.sag_sup.toLowerCase();
+ if (jets.cha_sup) scha = jets.cha_sup.toLowerCase();
setAttrs({
- FOR_SUP: sfor,
- DEX_SUP: sdex,
- CON_SUP: scon,
- INT_SUP: sint,
- SAG_SUP: ssag,
- CHA_SUP: scha,
+ for_sup: sfor,
+ dex_sup: sdex,
+ con_sup: scon,
+ int_sup: sint,
+ sag_sup: ssag,
+ cha_sup: scha,
});
});
}
@@ -2954,8 +2953,8 @@
["force", "FOR_BONUS", "dexterite", "DEX_BONUS", "constitution",
"CON_BONUS", "intelligence", "INT_BONUS", "sagesse", "SAG_BONUS",
"charisme", "CHA_BONUS", "INIT_DIV", "DEFARMURE", "DEFARMUREON",
- "DEFBOUCLIER", "DEFBOUCLIERON", "DEFDIV", "PV_max", "FOR_SUP",
- "DEX_SUP", "CON_SUP", "INT_SUP", "SAG_SUP", "CHA_SUP", "PV", "RDS",
+ "DEFBOUCLIER", "DEFBOUCLIERON", "DEFDIV", "PV_max", "for_sup",
+ "dex_sup", "con_sup", "int_sup", "sag_sup", "cha_sup", "PV", "RDS",
"jets_caches", "pnj_default_jets_caches",
],
function(values) {
@@ -2996,12 +2995,12 @@
if (!isNaN(bonus)) attrs.pnj_def += bonus;
bonus = parseInt(values.INIT_DIV);
if (!isNaN(bonus)) attrs.pnj_init += bonus;
- attrs.pnj_for_sup = car_sup_from_pj_to_pnj(values.FOR_SUP);
- attrs.pnj_dex_sup = car_sup_from_pj_to_pnj(values.DEX_SUP);
- attrs.pnj_con_sup = car_sup_from_pj_to_pnj(values.CON_SUP);
- attrs.pnj_int_sup = car_sup_from_pj_to_pnj(values.INT_SUP);
- attrs.pnj_sag_sup = car_sup_from_pj_to_pnj(values.SAG_SUP);
- attrs.pnj_cha_sup = car_sup_from_pj_to_pnj(values.CHA_SUP);
+ attrs.pnj_for_sup = car_sup_from_pj_to_pnj(values.for_sup);
+ attrs.pnj_dex_sup = car_sup_from_pj_to_pnj(values.dex_sup);
+ attrs.pnj_con_sup = car_sup_from_pj_to_pnj(values.con_sup);
+ attrs.pnj_int_sup = car_sup_from_pj_to_pnj(values.int_sup);
+ attrs.pnj_sag_sup = car_sup_from_pj_to_pnj(values.sag_sup);
+ attrs.pnj_cha_sup = car_sup_from_pj_to_pnj(values.cha_sup);
if (values.pnj_default_jets_caches == "true") {
attrs.pnj_jets_caches = '/w gm ';
attrs.jets_caches = '/w gm ';
@@ -3273,85 +3272,85 @@
});
on('change:pnj_for_sup', function(eventinfo) {
if (eventinfo.newValue == 'on') {
- getAttrs(["FOR_SUP"], function(values) {
- if (values.FOR_SUP && values.FOR_SUP.startsWith('@{jetsup')) return;
+ getAttrs(["for_sup"], function(values) {
+ if (values.for_sup && values.for_sup.startsWith('@{jetsup')) return;
setAttrs({
- FOR_SUP: '@{jetsup}'
+ for_sup: '@{jetsup}'
});
});
} else {
setAttrs({
- FOR_SUP: '@{jetnormal}'
+ for_sup: '@{jetnormal}'
});
}
});
on('change:pnj_dex_sup', function(eventinfo) {
if (eventinfo.newValue == 'on') {
- getAttrs(["DEX_SUP"], function(values) {
- if (values.DEX_SUP && values.DEX_SUP.startsWith('@{jetsup')) return;
+ getAttrs(["dex_sup"], function(values) {
+ if (values.dex_sup && values.dex_sup.startsWith('@{jetsup')) return;
setAttrs({
- DEX_SUP: '@{jetsup}'
+ dex_sup: '@{jetsup}'
});
});
} else {
setAttrs({
- DEX_SUP: '@{jetnormal}'
+ dex_sup: '@{jetnormal}'
});
}
});
on('change:pnj_con_sup', function(eventinfo) {
if (eventinfo.newValue == 'on') {
- getAttrs(["CON_SUP"], function(values) {
- if (values.CON_SUP && values.CON_SUP.startsWith('@{jetsup')) return;
+ getAttrs(["con_sup"], function(values) {
+ if (values.con_sup && values.con_sup.startsWith('@{jetsup')) return;
setAttrs({
- CON_SUP: '@{jetsup}'
+ con_sup: '@{jetsup}'
});
});
} else {
setAttrs({
- CON_SUP: '@{jetnormal}'
+ con_sup: '@{jetnormal}'
});
}
});
on('change:pnj_int_sup', function(eventinfo) {
if (eventinfo.newValue == 'on') {
- getAttrs(["INT_SUP"], function(values) {
- if (values.INT_SUP && values.INT_SUP.startsWith('@{jetsup')) return;
+ getAttrs(["int_sup"], function(values) {
+ if (values.int_sup && values.int_sup.startsWith('@{jetsup')) return;
setAttrs({
- INT_SUP: '@{jetsup}'
+ int_sup: '@{jetsup}'
});
});
} else {
setAttrs({
- INT_SUP: '@{jetnormal}'
+ int_sup: '@{jetnormal}'
});
}
});
on('change:pnj_sag_sup', function(eventinfo) {
if (eventinfo.newValue == 'on') {
- getAttrs(["SAG_SUP"], function(values) {
- if (values.SAG_SUP && values.SAG_SUP.startsWith('@{jetsup')) return;
+ getAttrs(["sag_sup"], function(values) {
+ if (values.sag_sup && values.sag_sup.startsWith('@{jetsup')) return;
setAttrs({
- SAG_SUP: '@{jetsup}'
+ sag_sup: '@{jetsup}'
});
});
} else {
setAttrs({
- SAG_SUP: '@{jetnormal}'
+ sag_sup: '@{jetnormal}'
});
}
});
on('change:pnj_cha_sup', function(eventinfo) {
if (eventinfo.newValue == 'on') {
- getAttrs(["CHA_SUP"], function(values) {
- if (values.CHA_SUP && values.CHA_SUP.startsWith('@{jetsup')) return;
+ getAttrs(["cha_sup"], function(values) {
+ if (values.cha_sup && values.cha_sup.startsWith('@{jetsup')) return;
setAttrs({
- CHA_SUP: '@{jetsup}'
+ cha_sup: '@{jetsup}'
});
});
} else {
setAttrs({
- CHA_SUP: '@{jetnormal}'
+ cha_sup: '@{jetnormal}'
});
}
});
@@ -4448,7 +4447,74 @@
});
});
+ function keyOfName(nom) {
+ nom = nom + '';
+ nom = nom.trim().toLowerCase();
+ nom = nom.replace(/é/g, 'e');
+ nom = nom.replace(/ç/g, 'c');
+ return nom;
+ }
+
//Les compétences
+
+ var competences = {
+ desamorcage: {
+ nom: 'Désamorçage',
+ main: 'DEX',
+ caracs: {
+ DEX: {},
+ INT: {},
+ }
+ },
+ discretion: {
+ nom: 'Discrétion',
+ main: 'DEX',
+ caracs: {
+ DEX: {
+ malus: 'armure'
+ },
+ }
+ },
+ mecanique: {
+ nom: 'Mécanique',
+ main: 'INT',
+ caracs: {
+ DEX: {},
+ INT: {},
+ }
+ },
+ perception: {
+ nom: 'Perception',
+ main: 'SAG',
+ caracs: {
+ SAG: {
+ malus: 'casque'
+ },
+ }
+ },
+ survie: {
+ nom: 'Survie',
+ main: 'SAG',
+ caracs: {
+ SAG: {
+ malus: 'casque'
+ },
+ CON: {
+ malus: 'armure'
+ }
+ }
+ },
+ vigilance: {
+ nom: 'Vigilance',
+ main: 'SAG',
+ caracs: {
+ SAG: {
+ malus: 'casque'
+ },
+ }
+ },
+ };
+
on('change:repeating_competences:comp_carac', function(eventinfo) {
var carac = eventinfo.newValue;
setAttrs({
@@ -4505,4 +4571,69 @@
});
});
});
+
+ on('change:repeating_competences:comp_nom change:repeating_competences:comp_nomCapa', function(eventinfo) {
+ getAttrs(['repeating_competences_comp_nom', 'repeating_competences_comp_nomCapa', 'repeating_competences_comp_carac', 'repeating_competences_comp_malus'], function(values) {
+ var nom = values.repeating_competences_comp_nom;
+ //Le nom doit être égal à nomCapa si il existe
+ var nomCapa = values.repeating_competences_comp_nomCapa;
+ if (nomCapa !== '' && nom != nomCapa) {
+ setAttrs({
+ repeating_competences_comp_nom: nomCapa
+ });
+ return;
+ }
+ var n = keyOfName(nom);
+ var c = competences[n];
+ if (c === undefined) return;
+ var carac = values.repeating_competences_comp_carac;
+ var sa = {};
+ var modif;
+ if (carac == 'FOR' && c.main != 'FOR') {
+ sa.repeating_competences_comp_carac = c.main;
+ carac = c.main;
+ modif = true;
+ }
+ carac = c.caracs[carac];
+ if (carac.malus && carac.malus != values.repeating_competences_comp_malus) {
+ sa.repeating_competences_comp_malus = carac.malus;
+ modif = true;
+ }
+ if (modif) setAttrs(sa);
+ });
+ });
+
+ on('change:repeating_competences:comp_carac', function(eventinfo) {
+ getAttrs(['repeating_competences_comp_nom', 'repeating_competences_comp_malus'], function(values) {
+ var nom = values.repeating_competences_comp_nom;
+ var n = keyOfName(nom);
+ var c = competences[n];
+ if (c === undefined) return;
+ var carac = c.caracs[eventinfo.newValue];
+ if (carac.malus && carac.malus != values.repeating_competences_comp_malus) {
+ setAttrs({
+ repeating_competences_comp_malus: carac.malus
+ });
+ }
+ });
+ });
+
+ //Les capacités
+
+ var capacites = {
+ mecanismes: {
+ voie: "voie de l'artilleur",
+ rang: 1,
+ texte: "l’arquebusier obtient un bonus de +1 par Rang dans cette voie à tous les tests visant à réparer ou à comprendre des mécanismes (cela inclut le fait de désamorcer des pièges mécaniques et de manipuler des armes de siège). Il peut appliquer ce bonus à tous les tests d’attaque avec des armes de siège (baliste, couleuvrine, canon, trébuchet, catapulte, etc.).",
+ bonus: [{
+ type: 'competence',
+ nom: 'Mécanique',
+ valeur: 'rang'
+ }, {
+ type: 'competence',
+ nom: 'Désamorçage',
+ valeur: 'rang'
+ }, ]
+ },
+ };
diff --git a/ChroniquesOubliees/sheet.json b/ChroniquesOubliees/sheet.json
index 0fd24ca116..889cbe8286 100644
--- a/ChroniquesOubliees/sheet.json
+++ b/ChroniquesOubliees/sheet.json
@@ -16,11 +16,11 @@
},
{
"attribute": "option_pr",
- "displayname": "Points de récupération",
+ "displayname": "Points de récupération",
"type": "checkbox",
"value": "1",
"checked": "checked",
- "description": "Utilisation de l'option des points de récupération (page 77 et 78 du livre de base)"
+ "description": "Utilisation de l'option des points de récupération (page 77 et 78 du livre de base)"
},
{
"attribute": "option_pm",
@@ -32,10 +32,10 @@
},
{
"attribute": "option_epuisement",
- "displayname": "Ãpuisement magique",
+ "displayname": "Épuisement magique",
"type": "checkbox",
"value": "1",
- "description": "Utilisation de l'option d'épuisement magique (page 180 du livre de base)"
+ "description": "Utilisation de l'option d'épuisement magique (page 180 du livre de base)"
},
{
"attribute": "option_ba_niveau",
@@ -43,7 +43,7 @@
"type": "checkbox",
"value": "1",
"checked": "checked",
- "description": "Le bonus d'attaque de base est égal au niveau"
+ "description": "Le bonus d'attaque de base est égal au niveau"
},
{
"attribute": "pnj_default_jets_caches",
@@ -51,22 +51,22 @@
"type": "select",
"options": [
"visibles|false",
- "cachés|true"
+ "cachés|true"
],
"default": "false",
- "description": "Valeurs des jets par défaut quand on channge de PJ à PNJ"
+ "description": "Valeurs des jets par défaut quand on channge de PJ à PNJ"
},
{
"attribute": "option_setting",
"displayname": "Setting",
"type": "select",
"options": [
- "Générique|generique",
+ "Générique|generique",
"Terre d'Arran|arran"
],
"default": "generique",
- "description": "Ensemble de règles utilisé"
+ "description": "Ensemble de règles utilisé"
}
],
"legacy": true
-}
\ No newline at end of file
+}
diff --git a/ChroniquesOublieesContemporain/README.md b/ChroniquesOublieesContemporain/README.md
index b8e037e385..8e39e8e837 100644
--- a/ChroniquesOublieesContemporain/README.md
+++ b/ChroniquesOublieesContemporain/README.md
@@ -10,10 +10,14 @@ Le jeu complet est disponible sur le site de l'éditeur [Black Book Editions](ht
# Version courante
-3.8 [Screenshot](coc_v2.png)
+3.8.1 [Screenshot](coc_v2.png)
# Notes de version
+## v3.8.1 (2021-03-01)
+
+Suppression du code de remise en forme des textes de capacités par élimination des retours à la ligne
+
## v3.8 (2021-02-22)
_Fiche de PJ_
diff --git a/ChroniquesOublieesContemporain/coc.css b/ChroniquesOublieesContemporain/coc.css
index e1d787b860..55571b1ad1 100644
--- a/ChroniquesOublieesContemporain/coc.css
+++ b/ChroniquesOublieesContemporain/coc.css
@@ -135,6 +135,7 @@ table.sheet-tabsep {
textarea.sheet-boxability {
width: 92%;
+ overflow-x: hidden;
}
span.sheet-boxability,
diff --git a/ChroniquesOublieesContemporain/coc.html b/ChroniquesOublieesContemporain/coc.html
index 2ace5df334..604fe1c8d5 100644
--- a/ChroniquesOublieesContemporain/coc.html
+++ b/ChroniquesOublieesContemporain/coc.html
@@ -1,8 +1,8 @@
-
-
+
+
@@ -82,13 +82,13 @@
-
-
@@ -4890,78 +4890,6 @@ on('change:type_personnage', function (eventInfo) {
);
});
-/**
- * On changing an ability description :
- * - Reformat text
- */
-on(
- [
- 'change:voie1-1',
- 'change:voie1-2',
- 'change:voie1-3',
- 'change:voie1-4',
- 'change:voie1-5',
- 'change:voie2-1',
- 'change:voie2-2',
- 'change:voie2-3',
- 'change:voie2-4',
- 'change:voie2-5',
- 'change:voie3-1',
- 'change:voie3-2',
- 'change:voie3-3',
- 'change:voie3-4',
- 'change:voie3-5',
- 'change:voie3-1',
- 'change:voie3-2',
- 'change:voie3-3',
- 'change:voie3-4',
- 'change:voie3-5',
- 'change:voie4-1',
- 'change:voie4-2',
- 'change:voie4-3',
- 'change:voie4-4',
- 'change:voie4-5',
- 'change:voie5-1',
- 'change:voie5-2',
- 'change:voie5-3',
- 'change:voie5-4',
- 'change:voie5-5',
- 'change:voie6-1',
- 'change:voie6-2',
- 'change:voie6-3',
- 'change:voie6-4',
- 'change:voie6-5',
- 'change:voie7-1',
- 'change:voie7-2',
- 'change:voie7-3',
- 'change:voie7-4',
- 'change:voie7-5',
- 'change:voie8-1',
- 'change:voie8-2',
- 'change:voie8-3',
- 'change:voie8-4',
- 'change:voie8-5',
- 'change:voie9-1',
- 'change:voie9-2',
- 'change:voie9-3',
- 'change:voie9-4',
- 'change:voie9-5',
- ].join(' '),
- function (eventInfo) {
- if (eventInfo.sourceType === 'sheetworker') return;
- const attrName = eventInfo.sourceAttribute;
- getAttrs([`${attrName}`], function (v) {
- let text = v[Object.keys(v)[0]].replace(/\n/g, '~').replace(/~~/g, '§');
- let lines = text.split('~');
- const title = lines.shift();
- text = title + '\n' + lines.join(' ').replace(/§/g, '\n');
- let attrValue = {};
- attrValue[Object.keys(v)[0]] = text;
- setAttrs(attrValue);
- });
- }
-);
-
/**
* Initialize an array of abilities
* @param {string} voie path #
diff --git a/ChroniquesOublieesContemporain/sheet.json b/ChroniquesOublieesContemporain/sheet.json
index 7bd1421bde..6c27e7d5ae 100644
--- a/ChroniquesOublieesContemporain/sheet.json
+++ b/ChroniquesOublieesContemporain/sheet.json
@@ -1,10 +1,10 @@
{
"html": "coc.html",
"css": "coc.css",
- "authors": "Ulti, Stéphane D, and Natha",
- "roll20userid": ["1794854", "75857", "84776"],
+ "authors": "StéphaneD",
+ "roll20userid": "84776",
"preview": "coc_v2.png",
- "instructions": "Feuille de Personnage pour [Chroniques Oubliées Contemporain](http://www.black-book-editions.fr/produit.php?id=4349). Chroniques Oubliées Contemporain est le dérivé de Chroniques Oubliées Fantasy adapté pour jouer dans la période 1900-2100. Il permet de jouer des aventures du genre espionnage, commando militaire, enquêtes policières occultes, vampires contre garous, mutants, super-héros, épouvante, pulp, apocalypse zombie, cyberpunk, et plus. Version 3.8 (22/02/2021). [Lisez-moi](https://github.com/Roll20/roll20-character-sheets/blob/master/ChroniquesOublieesContemporain/README.md).",
+ "instructions": "Feuille de Personnage pour [Chroniques Oubliées Contemporain](http://www.black-book-editions.fr/produit.php?id=4349). Chroniques Oubliées Contemporain est le dérivé de Chroniques Oubliées Fantasy adapté pour jouer dans la période 1900-2100. Il permet de jouer des aventures du genre espionnage, commando militaire, enquêtes policières occultes, vampires contre garous, mutants, super-héros, épouvante, pulp, apocalypse zombie, cyberpunk, et plus. Version 3.8.1 (01/03/2021). [Lisez-moi](https://github.com/Roll20/roll20-character-sheets/blob/master/ChroniquesOublieesContemporain/README.md).",
"useroptions": [
{
"attribute": "coc_setting",
diff --git a/City Of Mist Official/city-of-mist.html b/City Of Mist Official/city-of-mist.html
index 2f3baea1d0..50e1457ec1 100644
--- a/City Of Mist Official/city-of-mist.html
+++ b/City Of Mist Official/city-of-mist.html
@@ -8001,11 +8001,13 @@ setAttrs(settings);
Bastion
Conjuration
Destiny
-
Divination
+
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
-
Subversion
+
Subversion
@@ -8269,7 +8271,9 @@ setAttrs(settings);
Conjuration
Destiny
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
Subversion
@@ -8728,7 +8732,9 @@ setAttrs(settings);
Conjuration
Destiny
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
Subversion
@@ -8995,7 +9001,9 @@ setAttrs(settings);
Conjuration
Destiny
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
Subversion
@@ -9454,7 +9462,9 @@ setAttrs(settings);
Conjuration
Destiny
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
Subversion
@@ -9721,7 +9731,9 @@ setAttrs(settings);
Conjuration
Destiny
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
Subversion
@@ -10177,7 +10189,9 @@ setAttrs(settings);
Conjuration
Destiny
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
Subversion
@@ -10444,7 +10458,9 @@ setAttrs(settings);
Conjuration
Destiny
Divination
+
Enclave
Expression
+
Familiar
Mobility
Relic
Subversion
diff --git a/City Of Mist Official/translation.json b/City Of Mist Official/translation.json
index 718862ed07..42b7a2df96 100644
--- a/City Of Mist Official/translation.json
+++ b/City Of Mist Official/translation.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Whenever your character has some downtime-button , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "
Whenever your character has some downtime , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave":"Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "
If your Identity ever becomes resolved , rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "
When you find answers to your Mystery , choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/af.json b/City Of Mist Official/translations/af.json
index e907323c6c..8e897a4af1 100644
--- a/City Of Mist Official/translations/af.json
+++ b/City Of Mist Official/translations/af.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/ca.json b/City Of Mist Official/translations/ca.json
index 718862ed07..2ff79ac4bb 100644
--- a/City Of Mist Official/translations/ca.json
+++ b/City Of Mist Official/translations/ca.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Whenever your character has some downtime-button , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "
Whenever your character has some downtime , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "
If your Identity ever becomes resolved , rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "
When you find answers to your Mystery , choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/cs.json b/City Of Mist Official/translations/cs.json
index 5d174f4a1c..171f36a951 100644
--- a/City Of Mist Official/translations/cs.json
+++ b/City Of Mist Official/translations/cs.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/da.json b/City Of Mist Official/translations/da.json
index e907323c6c..8e897a4af1 100644
--- a/City Of Mist Official/translations/da.json
+++ b/City Of Mist Official/translations/da.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/de.json b/City Of Mist Official/translations/de.json
index d14d29f3c5..2c23a642a9 100644
--- a/City Of Mist Official/translations/de.json
+++ b/City Of Mist Official/translations/de.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/el.json b/City Of Mist Official/translations/el.json
index e907323c6c..8e897a4af1 100644
--- a/City Of Mist Official/translations/el.json
+++ b/City Of Mist Official/translations/el.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/en.json b/City Of Mist Official/translations/en.json
index 718862ed07..2ff79ac4bb 100644
--- a/City Of Mist Official/translations/en.json
+++ b/City Of Mist Official/translations/en.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Whenever your character has some downtime-button , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "
Whenever your character has some downtime , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "
If your Identity ever becomes resolved , rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "
When you find answers to your Mystery , choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/es.json b/City Of Mist Official/translations/es.json
index 3e4f5ffbfa..7b4bd7faec 100644
--- a/City Of Mist Official/translations/es.json
+++ b/City Of Mist Official/translations/es.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expresión",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/fr.json b/City Of Mist Official/translations/fr.json
index 6faec6f56f..93a1e38bcc 100644
--- a/City Of Mist Official/translations/fr.json
+++ b/City Of Mist Official/translations/fr.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "Fin De La Route",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Enfin, Quelques Réponses",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/he.json b/City Of Mist Official/translations/he.json
index e907323c6c..8e897a4af1 100644
--- a/City Of Mist Official/translations/he.json
+++ b/City Of Mist Official/translations/he.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/hu.json b/City Of Mist Official/translations/hu.json
index 718862ed07..2ff79ac4bb 100644
--- a/City Of Mist Official/translations/hu.json
+++ b/City Of Mist Official/translations/hu.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Whenever your character has some downtime-button , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "
Whenever your character has some downtime , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "
If your Identity ever becomes resolved , rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "
When you find answers to your Mystery , choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/it.json b/City Of Mist Official/translations/it.json
index 19781dd5e8..bb278b5118 100644
--- a/City Of Mist Official/translations/it.json
+++ b/City Of Mist Official/translations/it.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Ogni volta che un personaggio ha un momento di tempo libero , può spenderlo in vari modi:
Dedicare tempo a un Tema Logos o extra. Il gioca-tore deve dichiarare in che modo dedichi attenzio-ne a questo Tema e segnare un Punto Attenzione su quel Tema. Lavorare al caso. Il giocatore deve dichiarare in che modo stia portando avanti le indagini, e guadagna 3 Indizi. Affrontare un Mistero. Il giocatore deve dichiarare a quale Mistero stia dedicando il suo tempo, e in che modo. Riceve un Indizio ed un Punto Attenzione per il Tema a cui appartiene il Mistero. Prepararsi per la prossima azione. Il giocatore deve dichiarare come si stia preparando e scegliere una delle opzioni seguenti: recuperare tutti gli Attributi consumati o guadagnare 3 Punti Carica con un metodo che rifletta la preparazione. I Punti Carica possono essere spesi per attivare i migliora-menti descritti nella Mossa Ottenere Un Vantaggio .Liberarsi dagli effetti negativi. Il MC determina se e come tu possa ridurre (o eliminare) gli Stati continui. In alternativa, il MC può decidere di ri-durre uno o più Stati negativi di un livello per ogni Attributo pertinente. Il MC può decidere di trasformare un Intermezzo in una scena.",
"downtime-desc": "
Ogni volta che un personaggio ha un momento di tempo libero , può spenderlo in vari modi:
Dedicare tempo a un Tema Logos o extra. Il gioca-tore deve dichiarare in che modo dedichi attenzio-ne a questo Tema e segnare un Punto Attenzione su quel Tema. Lavorare al caso. Il giocatore deve dichiarare in che modo stia portando avanti le indagini, e guadagna 3 Indizi. Affrontare un Mistero. Il giocatore deve dichiarare a quale Mistero stia dedicando il suo tempo, e in che modo. Riceve un Indizio ed un Punto Attenzione per il Tema a cui appartiene il Mistero. Prepararsi per la prossima azione. Il giocatore deve dichiarare come si stia preparando e scegliere una delle opzioni seguenti: recuperare tutti gli Attributi consumati o guadagnare 3 Punti Carica con un metodo che rifletta la preparazione. I Punti Carica possono essere spesi per attivare i migliora-menti descritti nella Mossa Ottenere Un Vantaggio .Liberarsi dagli effetti negativi. Il MC determina se e come tu possa ridurre (o eliminare) gli Stati continui. In alternativa, il MC può decidere di ri-durre uno o più Stati negativi di un livello per ogni Attributo pertinente. Il MC può decidere di trasformare un Intermezzo in una scena.",
"eliminate-nemeses": "Liberati delle tue nemesi",
+ "enclave": "Enclave",
"end-of-road": "Fine corsa",
"end-road-desc": "
Quando un’Identità viene risolta , riformula l’Identità e rendila funzionale a un nuovo obiettivo, a uno scopo più grande o visto da una prospettiva nuova, e così via. In alcuni casi, se un determinato aspetto della vita del personaggio si è concluso per sempre, il Tema può essere sostituito.",
"expression": "Dominio",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "Sei protetto e non ricevi lo Stato da cui ti stai difendendo. ",
"face-danger-min-succ": "Subisci lo Stato, ma con livello ridotto di 1.",
"fade": "SCOMPARSA:",
+ "familiar": "Familiar",
"find-answers-button": "Trovare la risposta",
"find-mistery-desc": "
Quando un personaggio trova risposta al suo Mistero , scegli una o più di queste opzioni:
Il personaggio arriva a comprendere meglio il suo Mythos, il suo Mistero o il legame fra essi: segna un Punto Attenzione sul Tema a cui appartiene il Mistero risolto.
Il personaggio è sconvolto dalla scoperta a tal punto da rifiutare il suo Mythos o un aspetto della sua vita ordinaria; segna un Punto Scomparsa o Frattura su uno dei Temi.
Il personaggio ha trovato la risposta che cercava: scegli un nuovo Mistero per questo Tema.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/ja.json b/City Of Mist Official/translations/ja.json
index d37e9dd447..446ec8f452 100644
--- a/City Of Mist Official/translations/ja.json
+++ b/City Of Mist Official/translations/ja.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/ko.json b/City Of Mist Official/translations/ko.json
index 40e600d40b..ccbe644eca 100644
--- a/City Of Mist Official/translations/ko.json
+++ b/City Of Mist Official/translations/ko.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "인과응보",
+ "enclave": "Enclave",
"end-of-road": "여정의 끝",
"end-road-desc": "
당신의 정체성이 변했다면 , 새로운 목표, 더 넓은 범위, 새로운 관점 등을 고려해 다시 써라. 그렇지 않고 당신의 삶의 관점이 완전히 끝이 났다면, 이 정체성 테마를 교체할 수 있다.",
"expression": "표출",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "당신은 -1 티어의 스테이터스를 받는다",
"fade": "쇠락:",
+ "familiar": "Familiar",
"find-answers-button": "드디어, 답이 좀 나왔군",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "플래시 백",
diff --git a/City Of Mist Official/translations/nl.json b/City Of Mist Official/translations/nl.json
index e907323c6c..8e897a4af1 100644
--- a/City Of Mist Official/translations/nl.json
+++ b/City Of Mist Official/translations/nl.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/pl.json b/City Of Mist Official/translations/pl.json
index 2901cf22f4..d17d242fb6 100644
--- a/City Of Mist Official/translations/pl.json
+++ b/City Of Mist Official/translations/pl.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/pt.json b/City Of Mist Official/translations/pt.json
index 805b5b9675..b9d0b6418e 100644
--- a/City Of Mist Official/translations/pt.json
+++ b/City Of Mist Official/translations/pt.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Quando quer que seu personagem tenha algum downtime , escolha uma forma para usá-lo:
Dê atenção para um de seus temas Logos (ou extra). Diga a todos na mesa como você fez isso e marque Atenção nesse tema. Trabalho no caso. Diga a todos na mesa como você fez isso, ganhe 3 pistas com o método e a fonte baseada na sua descrição. Explore seu Mythos. Diga à todos na mesa qual Mistério você explora e como faz isso. Você ganha 1 Cola com o método e a fonte baseada em sua descrição. Marque Atenção no tema do Mistério. Prepare-se para sua próxima atividade. Diga à todos na mesa como você se preparou e escolha um: recupere todas as suas tags de poder queimadas OU ganhe 3 Juice com o método baseado em sua descrição. Você pode escolher um dos efeitos a seguir Mude o Jogo. Recupere de sua última atividade. Para cada em andamento ainda afetando você, o MC vai te dizer se e como isto apode ser reduzido durante seu botão-downtime e por quantos ranques. Alternativamente, o MC pode permitir que você reduza uma ou mais de seus status por um ranque para cada tag relevante que você tenha. O MC pode ter uma deixa dentro de qualquer evento da montagem e continuar, então, as cenas.\"",
"downtime-desc": "
Quando quer que seu personagem tenha algum downtime , escolha uma forma para usá-lo:
Dê atenção para um de seus temas Logos (ou extra). Diga a todos na mesa como você fez isso e marque Atenção nesse tema. Trabalho no caso. Diga a todos na mesa como você fez isso, ganhe 3 pistas com o método e a fonte baseada na sua descrição. Explore seu Mythos. Diga à todos na mesa qual Mistério você explora e como faz isso. Você ganha 1 Cola com o método e a fonte baseada em sua descrição. Marque Atenção no tema do Mistério. Prepare-se para sua próxima atividade. Diga à todos na mesa como você se preparou e escolha um: recupere todas as suas tags de poder queimadas OU ganhe 3 Juice com o método baseado em sua descrição. Você pode escolher um dos efeitos a seguir Mude o Jogo. Recupere de sua última atividade. Para cada em andamento ainda afetando você, o MC vai te dizer se e como isto apode ser reduzido durante seu botão-downtime e por quantos tiers. Alternativamente, o MC pode permitir que você reduza uma ou mais de seus status por um tier para cada tag relevante que você tenha. O MC pode ter uma deixa dentro de qualquer evento da montagem e continuar, então, as cenas.",
"eliminate-nemeses": "Obtenha o encerramento de seu Nemeses",
+ "enclave": "Enclave",
"end-of-road": "Fim da Estrada",
"end-road-desc": "
Se sua Identidade for resolvida em algum momento , reformule-o com o mesmo espírito para descrever um novo objetivo, um escopo maior, um novo ângulo, etc. Alternativamente, se este aspecto da sua vida realmente acabar, você pode substituir o tema desta Identidade.",
"expression": "Expressão",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "Você escapa do efeito e não assume nenhum status. ",
"face-danger-min-succ": "Você recebe o status, mas com tier -1.",
"fade": "DESVANESCER:",
+ "familiar": "Familiar",
"find-answers-button": "Enfim, Algumas Respostas",
"find-mistery-desc": "
Quando você encontrar respostas para o seu mistério , escolha um, dois, ou todos três:
Você adquire uma compreensão mais profunda do seu Mythos, do assunto do seu Mistério ou da ligação entre o seu Mistério e o seu Mythos. Marque Atenção no tema que pertence este Mistério.
Você está chocado com a descoberta a ponto de rejeitar seu Mythos ou um aspecto comum de sua vida. Marque Desvanescer ou Crack em qualquer tema.
Suas perguntas foram respondidas. Escolha um novo mistério para este tema.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/ru.json b/City Of Mist Official/translations/ru.json
index 192223912d..41a937cd26 100644
--- a/City Of Mist Official/translations/ru.json
+++ b/City Of Mist Official/translations/ru.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Когда у твоего персонажа есть время на отдых , выбери один способ, чтобы потратить его:
Уделить внимание одной из своих тем Logos (или extra). Расскажи всем за столом как ты делаешь это и отметь Attention на этой теме. Работать над делом. Расскажи всем за столом как ты это делаешь и получи 3 Clues, основанные на методе и источнике из твоего описания. Исследовать Mythos. Расскажи всем за столом какую Mystery ты исследуешь и как. Получи 1 Clue, основанную на методе и источнике из твоего описания. Отметь Attention на теме этой Mystery. Prepare for your next activity. Расскажи всем за столом как ты готовишься и выбери одно: восстановить все сожженные power tags ИЛИ получить 3 Juice, основанные на методе из твоего описания. Ты можешь выбрать варианты улучшений из хода Change the Game. Recover from you last activity. Для каждого текущего статуса, влияющего на тебя, MC расскажет как (и можно ли) понизить его в течении твоего отдыха и на сколько рангов. В качестве альтернативы, MC может позволить тебе понизить любые (или некоторые) из твоих статусов на один уровень за каждый твой подходящий тег. MC может подключаться к любому событию монтажа и продолжать их как сцены.",
"downtime-desc": "
Когда у твоего персонажа есть время на отдых , выбери один способ, чтобы потратить его:
Уделить внимание одной из своих тем Logos (или extra). Расскажи всем за столом как ты делаешь это и отметь Attention на этой теме. Работать над делом. Расскажи всем за столом как ты это делаешь и получи 3 Clues, основанные на методе и источнике из твоего описания. Исследовать Mythos. Расскажи всем за столом какую Mystery ты исследуешь и как. Получи 1 Clue, основанную на методе и источнике из твоего описания. Отметь Attention на теме этой Mystery. Подготовиться к будущим событиям. Расскажи всем за столом как ты готовишься и выбери одно: восстановить все сожженные power tags ИЛИ получить 3 Juice, основанные на методе из твоего описания. Ты можешь выбрать варианты улучшений из хода Change the Game. Восстановиться после недавних событий Для каждого текущего статуса, влияющего на тебя, MC расскажет как (и можно ли) понизить его в течении твоего отдыха и на сколько рангов. В качестве альтернативы, MC может позволить тебе понизить любые (или некоторые) из твоих статусов на один уровень за каждый твой подходящий тег. MC может подключаться к любому событию монтажа и продолжать их как сцены.",
"eliminate-nemeses": "Средство против Заклятых Врагов",
+ "enclave": "Enclave",
"end-of-road": "Конец Дороги",
"end-road-desc": "
Если твоя Identity стала решенной , перефразируй ее в том же духе, чтобы описать новую цель, больший объем, новый угол, и т.д. В качестве альтернативы, если этот аспект твоей жизни действительно закончился, ты можешь заменить эту тему Identity.",
"expression": "Выражение (Expression)",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "Ты отражаешь эффект и не получаешь статуса.",
"face-danger-min-succ": "Ты получаешь статус, но с уровнем на 1 меньше.",
"fade": "УГСН:",
+ "familiar": "Familiar",
"find-answers-button": "Наконец-то, Ответы",
"find-mistery-desc": "
Когда ты находишь ответы на свою Mystery , выбери одно, два, или все три:
Ты получаешь более глубокое понимание своего Mythos, предмета своей Mystery, или связи между ними. Отметь Attention на теме, к которой принадлежит эта Mystery. Ты шокирован открытием вплоть до отрицания своего Mythos или аспекта своей обычной жизни. Отметь Fade или Crack на любой теме. Ты нашел ответы на свои вопросы. Выбери новую Mystery для этой темы. ",
"flashback-button": "Флэшбэк",
diff --git a/City Of Mist Official/translations/sl.json b/City Of Mist Official/translations/sl.json
index 718862ed07..2ff79ac4bb 100644
--- a/City Of Mist Official/translations/sl.json
+++ b/City Of Mist Official/translations/sl.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Whenever your character has some downtime-button , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "
Whenever your character has some downtime , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "
If your Identity ever becomes resolved , rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "
When you find answers to your Mystery , choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/sv.json b/City Of Mist Official/translations/sv.json
index 33d8422171..366875a9d3 100644
--- a/City Of Mist Official/translations/sv.json
+++ b/City Of Mist Official/translations/sv.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/tr.json b/City Of Mist Official/translations/tr.json
index e907323c6c..8e897a4af1 100644
--- a/City Of Mist Official/translations/tr.json
+++ b/City Of Mist Official/translations/tr.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/uk.json b/City Of Mist Official/translations/uk.json
index 718862ed07..2ff79ac4bb 100644
--- a/City Of Mist Official/translations/uk.json
+++ b/City Of Mist Official/translations/uk.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "
Whenever your character has some downtime-button , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "
Whenever your character has some downtime , choose one way to spend it:
Give attention to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. Work the case. Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. Explore your Mythos. Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. Prepare for your next activity. Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under Change the Game. Recover from you last activity. For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "
If your Identity ever becomes resolved , rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "
When you find answers to your Mystery , choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/City Of Mist Official/translations/zh.json b/City Of Mist Official/translations/zh.json
index ed981ee44c..3fb41db9e6 100644
--- a/City Of Mist Official/translations/zh.json
+++ b/City Of Mist Official/translations/zh.json
@@ -51,6 +51,7 @@
"downtime-button-desc": "**Whenever your character has some downtime-button**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime-button and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"downtime-desc": "**Whenever your character has some downtime**, choose one way to spend it:
**Give attention** to one of your Logos (or extra) themes. Tell everyone at the table how you do it and mark Attention on that theme. **Work the case.** Tell everyone at the table how you do it, and gain 3 Clues with a method and a source based on your description. **Explore your Mythos.** Tell everyone at the table which Mystery you explore and how you do it. You gain 1 Clue with a method and a source based on your description. Mark Attention on that Mystery’s theme. **Prepare for your next activity.** Tell everyone at the table how you prepare and choose one: recover all your burnt power tags OR gain 3 Juice with a method based on your description. You can choose from the effect improvements under **Change the Game.** **Recover from you last activity.** For each ongoing status still affecting you, the MC will tell you if and how it can be reduced during your downtime and by how many tiers. Alternatively, the MC can allow you to reduce any or some of your statuses by one tier for each relevant tag you have. The MC can cue into any of the montage events and continue them as scenes.",
"eliminate-nemeses": "Get closure from your Nemeses",
+ "enclave": "Enclave",
"end-of-road": "End Of The Road",
"end-road-desc": "**If your Identity ever becomes resolved**, rephrase it in the same spirit to describe a new goal, a greater scope, a new angle, etc. Alternatively, if this aspect of your life truly ended, you may replace this Identity’s theme.",
"expression": "Expression",
@@ -62,6 +63,7 @@
"face-danger-max-succ": "You fend off the effect and take no status at all. ",
"face-danger-min-succ": "You take the status, but with -1 tier.",
"fade": "FADE:",
+ "familiar": "Familiar",
"find-answers-button": "Finally, Some Answers",
"find-mistery-desc": "**When you find answers to your Mystery**, choose one, two, or all three:
You gain a deeper understanding of your Mythos, of the subject of your Mystery, or of the link between your Mystery and your Mythos. Mark Attention on the theme to which this Mystery belongs.
You are shocked by the discovery to the point of rejecting your Mythos or an aspect of your ordinary life. Mark Fade or Crack on any theme.
Your questions are answered. Choose a new Mystery for this theme.",
"flashback-button": "Flashback",
diff --git a/CortexPrime-Hammerheads/CortexPrime-Hammerhead.css b/CortexPrime-Hammerheads/CortexPrime-Hammerhead.css
new file mode 100644
index 0000000000..cae36aa690
--- /dev/null
+++ b/CortexPrime-Hammerheads/CortexPrime-Hammerhead.css
@@ -0,0 +1,567 @@
+
+ .charsheet * {
+ font-family: monospace;
+ padding: 0;
+ margin: 0;
+ border-collapse: collapse;
+ font-size: 1em;
+ font-weight: 200;
+ color: #ffffff;
+ grid-gap: 1rem;
+ box-sizing: border-box;
+ }
+
+/* Layout */
+
+ sheet-template-container,
+ .charsheet {
+ background-image: url(https://raw.githubusercontent.com/Roll20/roll20-character-sheets/master/CortexPrime-Hammerheads/assets/background.png);
+ background-size: 8%;
+ background-clip: content-box;
+ background-color: #1b1a1a
+ }
+
+ .sheet-wrapper {
+ min-width: 750px;
+ padding: 25px;
+ display: grid;
+ grid-template-columns: repeat(1, 1fr );
+ align-items: start;
+ }
+
+
+/* Trait Blocks */
+
+ .sheet-traits4 {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr );
+ align-items: start;
+ }
+
+ .sheet-traits3 {
+ display: grid;
+ grid-template-columns: repeat(3, 1fr );
+ align-items: start;
+ }
+
+ .sheet-traits2 {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr );
+ align-items: start;
+ }
+
+ .sheet-traits1 {
+ display: grid;
+ grid-template-columns: repeat(1, 1fr );
+ align-items: start;
+ }
+
+
+/* Trait Types */
+
+ .sheet-info {
+ border-top: 4px solid #ffcb2b;
+ border-left: 1px dashed #ffcb2b;
+ padding: 12.5px;
+ }
+
+ .sheet-action {
+ border: 1px dashed #ffcb2b;
+ border-top: 6px solid #ffcb2b;
+ padding: 5px;
+ }
+
+ .sheet-training {
+ text-align: center;
+ min-height: 92px;
+ border: 1px dashed #ffcb2b;
+ border-top: 6px solid #ffcb2b;
+ padding: 5px;
+ }
+
+ .sheet-distinction {
+ border: 1px dashed #ffcb2b;
+ border-top: 6px solid #ffcb2b;
+ padding: 5px;
+ }
+
+ .sheet-distinctionType {
+ min-width: 70px;
+ display: inline-block;
+ }
+
+ .sheet-distinctionType input {
+ max-width: 300px;
+ }
+
+ .sheet-sfx {
+ border-top: 1px dashed #9999ee;
+ }
+
+ .sheet-relationship {
+ border: 1px dashed #3da069;
+ border-top: 6px solid #3da069;
+ padding: 5px;
+ }
+
+ .sheet-stress {
+ border: 1px dashed #bb3030;
+ border-top: 6px solid #bb3030;
+ padding: 5px;
+ }
+
+ .sheet-trauma {
+ border: 1px dashed #bb3030;
+ border-top: 6px solid #bb3030;
+ padding: 5px;
+ text-align: left;
+ background-color: rgba(255, 0, 0, 0.25);
+ }
+
+ .sheet-stress, .sheet-trauma {
+ min-height: 45px;
+ }
+
+ .sheet-hide {
+ visibility: hidden;
+ display: none;
+ }
+
+/* copy */
+
+ .charsheet h1 {
+ font-size: 1.6em;
+ color: #ffffff;
+ text-shadow: .2em .2em .2em rgba(255, 255, 255, 0.3)
+ }
+
+ .charsheet h2 {
+ font-size: 1.4em;
+ color: #ffffff;
+ text-shadow: .2em .2em .1em rgba(255, 255, 255, 0.2)
+ }
+
+ .charsheet h3 {
+ font-size: 1.2em;
+ line-height: 1.3em;
+ color: #ffffff;
+ text-shadow: .1em .2em .2em rgba(255, 255, 255, 0.2)
+ }
+
+ .charsheet h4 {
+ font-size: 1.1em;
+ color: #ffffff;
+ font-style: italic;
+ text-shadow: .1em .1em .2em rgba(255, 255, 255, 0.1)
+ }
+
+ input[name="attr_Portrait"] + div img.sheet-portrait {
+ display: none;
+ }
+
+ .sheet-legal,
+ .sheet-legal a {
+ font-size: 0.8em;
+ color:rgba(255, 255, 255, 0.69);
+ }
+
+/* Portraits */
+
+ input[name="attr_Portrait"][value="PC01"] + div img[alt="PC01"],
+ input[name="attr_Portrait"][value="PC02"] + div img[alt="PC02"],
+ input[name="attr_Portrait"][value="PC03"] + div img[alt="PC03"],
+ input[name="attr_Portrait"][value="PC04"] + div img[alt="PC04"],
+ input[name="attr_Portrait"][value="PC05"] + div img[alt="PC05"],
+ input[name="attr_Portrait"][value="PC06"] + div img[alt="PC06"],
+ input[name="attr_Portrait"][value="PC07"] + div img[alt="PC07"],
+ input[name="attr_Portrait"][value="PC08"] + div img[alt="PC08"],
+ input[name="attr_Portrait"][value="PC09"] + div img[alt="PC09"],
+ input[name="attr_Portrait"][value="PC10"] + div img[alt="PC10"],
+ input[name="attr_Portrait"][value="PC11"] + div img[alt="PC11"],
+ input[name="attr_Portrait"][value="PC12"] + div img[alt="PC12"],
+ input[name="attr_Portrait"][value="PC13"] + div img[alt="PC13"],
+ input[name="attr_Portrait"][value="PC14"] + div img[alt="PC14"],
+ input[name="attr_Portrait"][value="PC15"] + div img[alt="PC15"],
+ input[name="attr_Portrait"][value="PC16"] + div img[alt="PC16"],
+ input[name="attr_Portrait"][value="PC17"] + div img[alt="PC17"],
+ input[name="attr_Portrait"][value="PC18"] + div img[alt="PC18"],
+ input[name="attr_Portrait"][value="PC19"] + div img[alt="PC19"],
+ input[name="attr_Portrait"][value="PC20"] + div img[alt="PC20"] {
+ display: block;
+ width: 250px;
+ height: auto;
+ }
+
+ input[name="attr_Portrait"][value="PC0"] + img[alt="Hammerheads"] {
+ width: auto !important;
+ height: 200px !important;
+ padding-left: 60px;
+ padding-bottom: 12px;
+ }
+
+/* Dice */
+
+ img[alt="d0"],
+ img[alt="d4"],
+ img[alt="d6"],
+ img[alt="d8"],
+ img[alt="d10"],
+ img[alt="d12"],
+ img[alt="stressed"] {
+ display: none;
+ }
+
+ .sheet-stress .sheet-locked + span,
+ .sheet-trauma .sheet-locked + span,
+ .sheet-action .sheet-locked + span {
+ display: block;
+ float: left;
+ padding-right:10px;
+ }
+
+ .sheet-training .sheet-locked + span {
+ display: inline-block;
+ }
+
+ .sheet-relationship .sheet-locked + span {
+ display: inline-block;
+ float: left;
+ }
+
+ .sheet-locked[value="0"] + span img[alt="d0"],
+ .sheet-locked[value="4"] + span img[alt="d4"],
+ .sheet-locked[value="6"] + span img[alt="d6"],
+ .sheet-locked[value="8"] + span img[alt="d8"],
+ .sheet-locked[value="10"] + span img[alt="d10"],
+ .sheet-locked[value="12"] + span img[alt="d12"],
+ .sheet-locked[value="14"] + span img[alt="stressed"] {
+ display: block !important;
+ }
+
+ .charsheet button[type="roll"].sheet-blank-roll-button::before {
+ content: '';
+ }
+
+ .charsheet button[type="roll"].sheet-blank-roll-button + span {
+ visibility: hidden;
+ display: none;
+ }
+
+ .charsheet button[type="roll"].sheet-blank-roll-button {
+ color: #444444 !important;
+ border: 2px solid #444444 !important;
+ background-color: rgba(255, 255, 255, 0.6) !important;
+ width: 215px;
+ background-image: none !important;
+ padding: 8px 8px 8px 8px;
+ }
+
+/* halo layout */
+
+
+ input[name="attr_Portrait"][value="PC0"] {
+ border: 1px solid #cccc00;
+ text-align: center;
+ background-color: rgba(255, 128, 0, 0.05);
+ }
+
+ input[name="attr_Portrait"][value="PC0"] + h1.sheet-hide {
+ visibility: visible !important;
+ display: block;
+ }
+
+ input[name="attr_Portrait"]:not([value="PC0"]) ~ .sheet-physical {
+ position: absolute;
+ top: 190px;
+ left: 280px;
+ line-height: 25px;
+ z-index: 10;
+ }
+
+ input[name="attr_Portrait"]:not([value="PC0"]) ~ .sheet-mental {
+ position: absolute;
+ top: 243px;
+ left: 290px;
+ line-height: 25px;
+ z-index: 10;
+ }
+
+ input[name="attr_Portrait"]:not([value="PC0"]) ~ .sheet-social {
+ position: absolute;
+ top: 295px;
+ left: 280px;
+ line-height: 25px;
+ z-index: 10;
+ }
+
+
+ input[name="attr_Portrait"]:not([value="PC0"]) + .sheet-action {
+ border: none;
+ border-top: none;
+ padding: 0;
+ }
+
+/* Field style */
+
+ input[type="text"][name^="attr"] {
+ border: 1px dashed rgba(0, 0, 0, 0);
+ background-color: rgba(255, 255, 255, 0) !important;
+ padding: 0 5px;
+ color: #ffffff !important;
+ font-size: 1em;
+ line-height: 1.2em;
+ }
+
+ textarea[name^="attr"] {
+ border: 1px dashed rgba(0, 0, 0, 0.06);
+ background-color: rgba(255, 255, 255, 0) !important;
+ padding: 0 5px;
+ color: #ffffff !important;
+ font-size: 1em;
+ line-height: 1.2em;
+ width: 95%;
+ height: 4em;
+ }
+ textarea.sfx {
+ width: 80%;
+ margin-left: 15px;
+ }
+
+/* Tool Tip */
+/* Tooltip container */
+
+.sheet-tooltip {
+ position: relative;
+ display: inline-block;
+ width: 100%;
+}
+
+/* Tooltip text */
+.sheet-tooltip .sheet-tooltiptext {
+ visibility: hidden;
+ width: 22ch;
+ background-color: rgba(255, 255, 255, 0.86);
+ color: #000;
+ text-align: left;
+ padding: 5px 5px;
+ border: 1px dashed black;
+ min-height: 60px;
+ max-height: 70px;
+ width: 100%;
+ line-height: 0.9em;
+ font-size: 0.8em;
+
+ /* Position the tooltip text - see examples below! */
+ position: absolute;
+ left: 0px;
+ top: -64px;
+ z-index: 3;
+}
+
+.sheet-tooltiptext {
+ font-size: 0.7em;
+}
+
+/* Show the tooltip text when you mouse over the tooltip container */
+
+
+input.sheet-tooltipSwitch[value="off"] {
+
+}
+
+input[name="attr_tooltipSwitch"][value="on"] ~ div h3.sheet-tooltip:hover .sheet-tooltiptext {
+ visibility: visible;
+}
+
+/* Edit */
+
+.sheet-editPane {
+ border: 1px dashed #cccccc;
+ background-color: #0d0d0d;
+ width: 670px;
+ z-index: 45;
+ position: absolute;
+ top: 15px;left: 10vh;
+ padding: 14px;
+ display: none;
+}
+
+.sheet-editPane .sheet-traits2 h3 select {
+ float: right;
+}
+
+input[name="attr_Edit"]:checked + div {
+ display: block !important;
+}
+
+.sheet-editDice {
+ width: 60px;
+ color: #ffffff;
+ background-color: #1b1a1a;
+}
+
+/* Preloader */
+
+ .sheet-preload img {
+ width: 40px;
+ display: none;
+ }
+
+/* Roll Template */
+
+ .sheet-rolltemplate-Hammerheads * {
+ font-family: monospace;
+ font-size: 1em;
+ font-weight: 600;
+ color: #ffffff;
+ }
+
+ .sheet-rolltemplate-Hammerheads {
+ background-color: #2a364e;
+ margin-left: -50px;
+ }
+
+ .sheet-rolltemplate-container {
+ display: grid;
+ grid-template-columns: 35px 1fr;
+ align-items: start;
+ grid-gap: 1rem;
+ padding: 2ch;
+ }
+
+
+
+ .sheet-rolltemplate-container div {
+ border-bottom: 1px solid #b6b473;
+ height: 45px;
+ }
+
+ .sheet-rolltemplate-dice {
+ display: grid;
+ grid-template-columns: repeat(7, 35px);
+ align-items: start;
+ grid-gap: 1rem;
+ padding: 2ch;
+ }
+
+ .sheet-rolltemplate-name {
+ }
+
+ .sheet-rolltemplate-result {
+ background-clip: padding-box;
+ background-size: contain;
+ background-repeat: no-repeat;
+ height: 2em;
+ font-size: 1.2em;
+ }
+
+ .sheet-rolltemplate-Hammerheads .inlinerollresult {
+ display: inline-block;
+ min-width: 1.5em;
+ text-align: center;
+ border: none !important;
+ background-color: transparent !important;
+ color: #ffffff !important;
+ padding-top: 7px;
+ }
+
+ .sheet-rolltemplate-Hammerheads .inlinerollresult.fullcrit {
+
+ }
+
+ .sheet-rolltemplate-Hammerheads .inlinerollresult.fullfail {
+
+ }
+
+ .sheet-rolltemplate-Hammerheads .inlinerollresult.importantroll {
+
+ }
+
+
+ @media only screen and (max-width: 480px) {
+
+ .sheet-wrapper {
+ min-width: 320px;
+ }
+
+ .sheet-traits4 {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr );
+ align-items: start;
+ }
+
+ .sheet-traits3 {
+ display: grid;
+ grid-template-columns: repeat(1, 1fr );
+ align-items: start;
+ }
+
+ .sheet-traits2 {
+ display: grid;
+ grid-template-columns: repeat(1, 1fr );
+ align-items: start;
+ }
+
+ .sheet-traits2 .sheet-traits2 {
+ display: grid;
+ grid-template-columns: repeat(2, 1fr );
+ align-items: start;
+ }
+
+ .sheet-traits1 {
+ display: grid;
+ grid-template-columns: repeat(1, 1fr );
+ align-items: start;
+ }
+
+
+/* halo layout */
+
+ .sheet-editPane {
+ width: 80%;
+ }
+
+ input[name="attr_Portrait"][value="PC0"] {
+ border: 1px solid #cccc00;
+ text-align: center;
+ background-color: rgba(255, 128, 0, 0.05);
+ }
+
+ h1.sheet-hide {
+ visibility: visible !important;
+ display: block;
+ }
+
+ input[name="attr_Portrait"]:not([value="PC0"]) ~ .sheet-physical {
+ position: static;
+ border: 1px dashed #ffcb2b;
+ border-top: 6px solid #ffcb2b;
+ padding: 5px;
+ }
+
+ input[name="attr_Portrait"]:not([value="PC0"]) ~ .sheet-mental {
+ position: static;
+ border: 1px dashed #ffcb2b;
+ border-top: 6px solid #ffcb2b;
+ padding: 5px;
+ }
+
+ input[name="attr_Portrait"]:not([value="PC0"]) ~ .sheet-social {
+ position: static;
+ border: 1px dashed #ffcb2b;
+ border-top: 6px solid #ffcb2b;
+ padding: 5px;
+ }
+
+
+ input[name="attr_Portrait"]:not([value="PC0"]) + .sheet-action {
+ display: block;
+ visibility: visible;
+ }
+
+ .charsheet button[type="roll"].sheet-blank-roll-button + span {
+ display: block !important;
+ visibility: visible !important;
+ }
+
+ }
\ No newline at end of file
diff --git a/CortexPrime-Hammerheads/CortexPrime-Hammerhead.html b/CortexPrime-Hammerheads/CortexPrime-Hammerhead.html
new file mode 100644
index 0000000000..685c02d41c
--- /dev/null
+++ b/CortexPrime-Hammerheads/CortexPrime-Hammerhead.html
@@ -0,0 +1,1282 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Edit
+
+
+
+
+
Portrait
+ Hammerhead logo
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Attributes
+
+ [
+
+
+
+ ]
+
+
+
+ Physical
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Mental
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Social
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+
+
+
Training Packages
+ [
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ]
+
+
Training Package Hints
+
on
+
off
+
+
+ Crowd Control
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Emergency Medical
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Firefighting
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Hammerhead Pilot
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Hazmat
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ High-Altitude Recovery
+
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Legal Specialist
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Logistics
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Marine Recovery
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Network Specialist
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Mechanic
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Tactical Response
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Technical Analyst
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+ Urban Recovery
+
+ Select
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+
+
+
Relationships
+ [
+
+
+ The rest are ]
+
+
saved my life.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
owes me big.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
is a trouble maker.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
knows their stuff.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
is a liability.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
is dependable.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
is good for a laugh.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
is a source of inspiration.
+
+ NA
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Name:
+
Callsign:
+
Description:
+
+
+ Dice Pool Builder
+ This may not work on the Roll20 Beta Mobile app.
+
+
+
+
+
+
+
+
+
Training Packages
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Distinctions
+
+
Your life before:
+
+
+ Spend a
to step up an attribute when you connect to your old life.
+
+ Add a
to the
Crisis Pool to double your attribute dice when you connect to your old life.
+
+
+
+
+
Approach/Attitude:
+
+
+ Spend a
to reroll your dice when you align with your true nature.
+
+ Add a
to the
Crisis Pool to step up your training package die when you align with your true nature.
+
+
+
+
Quirk/Quality
+
+
+ Spend a
to double your relationship die when your assistance embraces your quirk or quality.
+
+ Add a
to the
Crisis Pool to step up a relationship die you include in your pool when you embrace your quirk or quality.
+
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
+
+
Relationships
+
+
+
saved my life.
+
+
+
+
+
+
+
+
+
+
+
owes me big.
+
+
+
+
+
+
+
+
+
+
+
is a trouble maker.
+
+
+
+
+
+
+
+
+
+
+
knows their stuff.
+
+
+
+
+
+
+
+
+
+
+
is a liability.
+
+
+
+
+
+
+
+
+
+
+
is dependable.
+
+
+
+
+
+
+
+
+
is good for a laugh.
+
+
+
+
+
+
+
+
+
+
+
is a source of inspiration.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Hammerheads is a part of the Cortex Prime Game Handbook published by Fandom Inc, and was written, designed, and developed by Cam Banks.
+
Hammerheads uses the Cortex system. The Cortex system and the Fandom logos are © 2020 Fandom Inc. All rights reserved. Reference to other copyrighted material in no way constitutes a challenge to the respective copyright holders of that material.
+
Artwork and graphics © and ™ Fandom Inc, illustrated by Ten Ten Studios Malaysia. All rights reserved.
+
Character Portraits sourced from https://thispersondoesnotexist.com/
+
+
+
+
+
+
+ {{#rollTotal() trait_name 1}}
+
+ {{physical}}
+
+
+ Physical
+ d{{physical_dice_size}} • Attribute
+
+ {{/rollTotal() trait_name 1}}
+ {{#rollTotal() trait_name 2}}
+
+ {{mental}}
+
+
+ Mental
+ d{{mental_dice_size}} • Attribute
+
+ {{/rollTotal() trait_name 2}}
+ {{#rollTotal() trait_name 3}}
+
+ {{social}}
+
+
+ Social
+ d{{social_dice_size}} • Attribute
+
+ {{/rollTotal() trait_name 3}}
+
+ {{#rollTotal() TrainingPackage 1}}
+
+ {{CrowdControl}}
+
+
+ Crowd Control
+ d{{CrowdControl_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 1}}
+ {{#rollTotal() TrainingPackage 2}}
+
+ {{EmergencyMedical}}
+
+
+ Emergency Medical
+ d{{EmergencyMedical_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 2}}
+ {{#rollTotal() TrainingPackage 3}}
+
+ {{Firefighting}}
+
+
+ Firefighting
+ d{{Firefighting_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 3}}
+ {{#rollTotal() TrainingPackage 4}}
+
+ {{HammerheadPilot}}
+
+
+ Hammerhead Pilot
+ d{{HammerheadPilot_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 4}}
+ {{#rollTotal() TrainingPackage 5}}
+
+ {{Hazmat}}
+
+
+ Hazmat
+ d{{Hazmat_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 5}}
+ {{#rollTotal() TrainingPackage 6}}
+
+ {{HighAltitudeRecovery}}
+
+
+ High Altitude Recovery
+ d{{HighAltitudeRecovery_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 6}}
+ {{#rollTotal() TrainingPackage 7}}
+
+ {{LegalSpecialist}}
+
+
+ Legal Specialist
+ d{{LegalSpecialist_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 7}}
+ {{#rollTotal() TrainingPackage 8}}
+
+ {{Logistics}}
+
+
+ Logistics
+ d{{Logistics_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 8}}
+ {{#rollTotal() TrainingPackage 9}}
+
+ {{MarineRecovery}}
+
+
+ Marine Recovery
+ d{{MarineRecovery_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 9}}
+ {{#rollTotal() TrainingPackage 10}}
+
+ {{NetworkSpecialist}}
+
+
+ Network Specialist
+ d{{NetworkSpecialist_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 10}}
+ {{#rollTotal() TrainingPackage 11}}
+
+ {{Mechanic}}
+
+
+ Mechanic
+ d{{Mechanic_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 11}}
+ {{#rollTotal() TrainingPackage 12}}
+
+ {{TacticalResponse}}
+
+
+ Tactical Response
+ d{{TacticalResponse_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 12}}
+ {{#rollTotal() TrainingPackage 13}}
+
+ {{TechnicalAnalyst}}
+
+
+ Technical Analyst
+ d{{TechnicalAnalyst_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 13}}
+ {{#rollTotal() TrainingPackage 14}}
+
+ {{UrbanRecovery}}
+
+
+ Urban Recovery
+ d{{UrbanRecovery_dice_size}} • Training Package
+
+ {{/rollTotal() TrainingPackage 14}}
+
+ {{#rollTotal() Distinction_Hinder 1}}
+
+ {{Distinction}}
+
+
+ {{Distinction_Name}}
+ d8 • Distinction
+
+ {{/rollTotal() Distinction_Hinder 1}}
+ {{#rollTotal() Distinction_Hinder 2}}
+
+ {{Hinder}}
+
+
+ {{Distinction_Name}}
+ d4 • Distinction
+
+ {{/rollTotal() Distinction_Hinder 2}}
+
+ {{#rollTotal() MyStress 4}}
+
+ {{Stress4}}
+
+
+ Remove stress, gain a
+
d4 • Your Stress
+
+ {{/rollTotal() MyStress 4}}
+ {{#rollTotal() TargetStress 6}}
+
+ {{Stress6}}
+
+
+ Target's Stress
+ d6 • Target Stress
+
+ {{/rollTotal() TargetStress 6}}
+ {{#rollTotal() TargetStress 8}}
+
+ {{Stress8}}
+
+
+ Target's Stress
+ d8 • Target Stress
+
+ {{/rollTotal() TargetStress 8}}
+ {{#rollTotal() TargetStress 10}}
+
+ {{Stress10}}
+
+
+ Target's Stress
+ d10 • Target Stress
+
+ {{/rollTotal() TargetStress 10}}
+ {{#rollTotal() TargetStress 12}}
+
+ {{Stress12}}
+
+
+ Target's Stress
+ d12 • Target Stress
+
+ {{/rollTotal() TargetStress 12}}
+
+ {{#rollTotal() friendship 6}}
+
+ {{friend6}}
+
+
+ A little help
+ d6 • Help
+
+ {{/rollTotal() friendship 6}}
+ {{#rollTotal() friendship 8}}
+
+ {{friend8}}
+
+
+ Some help
+ d8 • Help
+
+ {{/rollTotal() friendship 8}}
+ {{#rollTotal() friendship 10}}
+
+ {{friend10}}
+
+
+ Real help
+ d10 • Help
+
+ {{/rollTotal() friendship 10}}
+ {{#rollTotal() friendship 12}}
+
+ {{friend12}}
+
+
+ Incredible help
+ d12 • Help
+
+ {{/rollTotal() friendship 12}}
+
+
+
+ {{#rollLess() shaken 1}}
+ {{name}} can keep two dice in their result. And may spend a
to include another.
+ {{/rollLess() shaken 1}}
+
+ {{#rollTotal() shaken 1}}
+ {{name}} is
shaken .
They can only keep one die in their result. But may spend a
to include another.
+ {{/rollTotal() shaken 1}}
+
+
+ {{#rollGreater() shaken 1}}
+ {{name}} is stricken and they should not have acted, they have been taken out of the scene.
+ {{/rollGreater() shaken 1}}
+
+
+
+ {{#rollTotal() trait_name 1}}
+
+ {{physical}}
+
+ {{/rollTotal() trait_name 1}}
+ {{#rollTotal() trait_name 2}}
+
+ {{mental}}
+
+ {{/rollTotal() trait_name 2}}
+ {{#rollTotal() trait_name 3}}
+
+ {{social}}
+
+ {{/rollTotal() trait_name 3}}
+
+ {{#rollTotal() TrainingPackage 1}}
+
+ {{CrowdControl}}
+
+ {{/rollTotal() TrainingPackage 1}}
+ {{#rollTotal() TrainingPackage 2}}
+
+ {{EmergencyMedical}}
+
+ {{/rollTotal() TrainingPackage 2}}
+ {{#rollTotal() TrainingPackage 3}}
+
+ {{Firefighting}}
+
+ {{/rollTotal() TrainingPackage 3}}
+ {{#rollTotal() TrainingPackage 4}}
+
+ {{HammerheadPilot}}
+
+ {{/rollTotal() TrainingPackage 4}}
+ {{#rollTotal() TrainingPackage 5}}
+
+ {{Hazmat}}
+
+ {{/rollTotal() TrainingPackage 5}}
+ {{#rollTotal() TrainingPackage 6}}
+
+ {{HighAltitudeRecovery}}
+
+ {{/rollTotal() TrainingPackage 6}}
+ {{#rollTotal() TrainingPackage 7}}
+
+ {{LegalSpecialist}}
+
+ {{/rollTotal() TrainingPackage 7}}
+ {{#rollTotal() TrainingPackage 8}}
+
+ {{Logistics}}
+
+ {{/rollTotal() TrainingPackage 8}}
+ {{#rollTotal() TrainingPackage 9}}
+
+ {{MarineRecovery}}
+
+ {{/rollTotal() TrainingPackage 9}}
+ {{#rollTotal() TrainingPackage 10}}
+
+ {{NetworkSpecialist}}
+
+ {{/rollTotal() TrainingPackage 10}}
+ {{#rollTotal() TrainingPackage 11}}
+
+ {{Mechanic}}
+
+ {{/rollTotal() TrainingPackage 11}}
+ {{#rollTotal() TrainingPackage 12}}
+
+ {{TacticalResponse}}
+
+ {{/rollTotal() TrainingPackage 12}}
+ {{#rollTotal() TrainingPackage 13}}
+
+ {{TechnicalAnalyst}}
+
+ {{/rollTotal() TrainingPackage 13}}
+ {{#rollTotal() TrainingPackage 14}}
+
+ {{UrbanRecovery}}
+
+ {{/rollTotal() TrainingPackage 14}}
+
+ {{#rollTotal() Distinction_Hinder 1}}
+
+ {{Distinction}}
+
+ {{/rollTotal() Distinction_Hinder 1}}
+ {{#rollTotal() Distinction_Hinder 2}}
+
+ {{Hinder}}
+
+ {{/rollTotal() Distinction_Hinder 2}}
+
+
+ {{#rollTotal() MyStress 4}}
+
+ {{Stress4}}
+
+ {{/rollTotal() MyStress 4}}
+ {{#rollTotal() TargetStress 6}}
+
+ {{Stress6}}
+
+ {{/rollTotal() TargetStress 6}}
+ {{#rollTotal() TargetStress 8}}
+
+ {{Stress8}}
+
+ {{/rollTotal() TargetStress 8}}
+ {{#rollTotal() TargetStress 10}}
+
+ {{Stress10}}
+
+ {{/rollTotal() TargetStress 10}}
+ {{#rollTotal() TargetStress 12}}
+
+ {{Stress12}}
+
+ {{/rollTotal() TargetStress 12}}
+
+ {{#rollTotal() friendship 6}}
+
+ {{friend6}}
+
+ {{/rollTotal() friendship 6}}
+ {{#rollTotal() friendship 8}}
+
+ {{friend8}}
+
+ {{/rollTotal() friendship 8}}
+ {{#rollTotal() friendship 10}}
+
+ {{friend10}}
+
+ {{/rollTotal() friendship 10}}
+ {{#rollTotal() friendship 12}}
+
+ {{friend12}}
+
+ {{/rollTotal() friendship 12}}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CortexPrime-Hammerheads/CortexPrime-Hammerhead.png b/CortexPrime-Hammerheads/CortexPrime-Hammerhead.png
new file mode 100644
index 0000000000..a6eef0b994
Binary files /dev/null and b/CortexPrime-Hammerheads/CortexPrime-Hammerhead.png differ
diff --git a/CortexPrime-Hammerheads/assets/background.png b/CortexPrime-Hammerheads/assets/background.png
new file mode 100644
index 0000000000..6da5e5db44
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/background.png differ
diff --git a/CortexPrime-Hammerheads/assets/d10-280x280.png b/CortexPrime-Hammerheads/assets/d10-280x280.png
new file mode 100644
index 0000000000..2dc95ecbcc
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d10-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d10-blank-280x280-hitch.png b/CortexPrime-Hammerheads/assets/d10-blank-280x280-hitch.png
new file mode 100644
index 0000000000..0703dda596
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d10-blank-280x280-hitch.png differ
diff --git a/CortexPrime-Hammerheads/assets/d10-blank-280x280.png b/CortexPrime-Hammerheads/assets/d10-blank-280x280.png
new file mode 100644
index 0000000000..24f294abd8
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d10-blank-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d12-280x280.png b/CortexPrime-Hammerheads/assets/d12-280x280.png
new file mode 100644
index 0000000000..b51e8f6a7f
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d12-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d12-blank-280x280-hitch.png b/CortexPrime-Hammerheads/assets/d12-blank-280x280-hitch.png
new file mode 100644
index 0000000000..5e8f8bb4f8
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d12-blank-280x280-hitch.png differ
diff --git a/CortexPrime-Hammerheads/assets/d12-blank-280x280.png b/CortexPrime-Hammerheads/assets/d12-blank-280x280.png
new file mode 100644
index 0000000000..be8ebc2bc2
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d12-blank-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d14-280x280.png b/CortexPrime-Hammerheads/assets/d14-280x280.png
new file mode 100644
index 0000000000..cb0cb37b88
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d14-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d4-280x280.png b/CortexPrime-Hammerheads/assets/d4-280x280.png
new file mode 100644
index 0000000000..64950c165e
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d4-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d4-blank-280x280-hitch.png b/CortexPrime-Hammerheads/assets/d4-blank-280x280-hitch.png
new file mode 100644
index 0000000000..918346d7d2
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d4-blank-280x280-hitch.png differ
diff --git a/CortexPrime-Hammerheads/assets/d4-blank-280x280.png b/CortexPrime-Hammerheads/assets/d4-blank-280x280.png
new file mode 100644
index 0000000000..7f49136bc8
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d4-blank-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d6-280x280.png b/CortexPrime-Hammerheads/assets/d6-280x280.png
new file mode 100644
index 0000000000..09838b2045
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d6-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d6-blank-280x280-hitch.png b/CortexPrime-Hammerheads/assets/d6-blank-280x280-hitch.png
new file mode 100644
index 0000000000..ca7379b437
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d6-blank-280x280-hitch.png differ
diff --git a/CortexPrime-Hammerheads/assets/d6-blank-280x280.png b/CortexPrime-Hammerheads/assets/d6-blank-280x280.png
new file mode 100644
index 0000000000..329e77335a
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d6-blank-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d8-280x280.png b/CortexPrime-Hammerheads/assets/d8-280x280.png
new file mode 100644
index 0000000000..7f45f44eda
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d8-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/d8-blank-280x280-hitch.png b/CortexPrime-Hammerheads/assets/d8-blank-280x280-hitch.png
new file mode 100644
index 0000000000..266b155512
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d8-blank-280x280-hitch.png differ
diff --git a/CortexPrime-Hammerheads/assets/d8-blank-280x280.png b/CortexPrime-Hammerheads/assets/d8-blank-280x280.png
new file mode 100644
index 0000000000..0510befa8d
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/d8-blank-280x280.png differ
diff --git a/CortexPrime-Hammerheads/assets/original.png b/CortexPrime-Hammerheads/assets/original.png
new file mode 100644
index 0000000000..a9741f297f
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/original.png differ
diff --git a/CortexPrime-Hammerheads/assets/plotpoint.png b/CortexPrime-Hammerheads/assets/plotpoint.png
new file mode 100644
index 0000000000..0de78bb520
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/plotpoint.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-1-510x510.png b/CortexPrime-Hammerheads/assets/portrait-1-510x510.png
new file mode 100644
index 0000000000..c4185d9643
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-1-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-10-510x510.png b/CortexPrime-Hammerheads/assets/portrait-10-510x510.png
new file mode 100644
index 0000000000..c9b2e6a02b
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-10-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-11-510x510.png b/CortexPrime-Hammerheads/assets/portrait-11-510x510.png
new file mode 100644
index 0000000000..a978262497
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-11-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-12-510x510.png b/CortexPrime-Hammerheads/assets/portrait-12-510x510.png
new file mode 100644
index 0000000000..9dae03a171
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-12-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-13-510x510.png b/CortexPrime-Hammerheads/assets/portrait-13-510x510.png
new file mode 100644
index 0000000000..44d56622a2
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-13-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-14-510x510.png b/CortexPrime-Hammerheads/assets/portrait-14-510x510.png
new file mode 100644
index 0000000000..fe7b7ea025
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-14-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-15-510x510.png b/CortexPrime-Hammerheads/assets/portrait-15-510x510.png
new file mode 100644
index 0000000000..567cbc2e8f
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-15-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-16-510x510.png b/CortexPrime-Hammerheads/assets/portrait-16-510x510.png
new file mode 100644
index 0000000000..41cbfc68a0
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-16-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-17-510x510.png b/CortexPrime-Hammerheads/assets/portrait-17-510x510.png
new file mode 100644
index 0000000000..b62697dca1
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-17-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-18-510x510.png b/CortexPrime-Hammerheads/assets/portrait-18-510x510.png
new file mode 100644
index 0000000000..7c29ad505e
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-18-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-19-510x510.png b/CortexPrime-Hammerheads/assets/portrait-19-510x510.png
new file mode 100644
index 0000000000..a880ddbafa
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-19-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-2-510x510.png b/CortexPrime-Hammerheads/assets/portrait-2-510x510.png
new file mode 100644
index 0000000000..9c19c3dca5
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-2-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-20-510x510.png b/CortexPrime-Hammerheads/assets/portrait-20-510x510.png
new file mode 100644
index 0000000000..779bb63445
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-20-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-3-510x510.png b/CortexPrime-Hammerheads/assets/portrait-3-510x510.png
new file mode 100644
index 0000000000..94b9c565cc
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-3-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-4-510x510.png b/CortexPrime-Hammerheads/assets/portrait-4-510x510.png
new file mode 100644
index 0000000000..35bd60fd35
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-4-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-5-510x510.png b/CortexPrime-Hammerheads/assets/portrait-5-510x510.png
new file mode 100644
index 0000000000..340f418336
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-5-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-6-510x510.png b/CortexPrime-Hammerheads/assets/portrait-6-510x510.png
new file mode 100644
index 0000000000..b037dd08ed
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-6-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-7-510x510.png b/CortexPrime-Hammerheads/assets/portrait-7-510x510.png
new file mode 100644
index 0000000000..8bea708c3e
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-7-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-8-510x510.png b/CortexPrime-Hammerheads/assets/portrait-8-510x510.png
new file mode 100644
index 0000000000..2c49bf734f
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-8-510x510.png differ
diff --git a/CortexPrime-Hammerheads/assets/portrait-9-510x510.png b/CortexPrime-Hammerheads/assets/portrait-9-510x510.png
new file mode 100644
index 0000000000..043acfd118
Binary files /dev/null and b/CortexPrime-Hammerheads/assets/portrait-9-510x510.png differ
diff --git a/CortexPrime-Hammerheads/readme.md b/CortexPrime-Hammerheads/readme.md
new file mode 100644
index 0000000000..8383e932fd
--- /dev/null
+++ b/CortexPrime-Hammerheads/readme.md
@@ -0,0 +1,56 @@
+Cortex Prime: Hammerhead Character Sheet
+
+##Set up
+
+- Open the Journal tab, and add a new Character.
+- Click on save changes.
+- Open the Character Sheet Tab
+- Tick the Edit Checkbox.
+- Select One of the Portraits, or select the dot next to the word Portrait to set no portrait.
+- Set the dice values for the Attributes, Training Packages, and Relationships using the drop downs.
+- Untick the Edit check box to hide the editor
+- Enter the remaining details - Name, Description, Value statements, Relationship names, Distinctions title and description in the editable text fields.
+
+##Stress
+
+I have been using API macro's to adjust Stress values. But these are simply Attributes (PhysicalStress, MentalStress, SocialStress).
+
+You can add these to the Attributes and Abilities tab manually, and assign values ranging from 2 to show the character has no stress - 4,6,8,10 or 12 corresponding to the dice value, or a value of 14 indicates the character has been stressed out.
+
+###Diceroller
+
+Using the 'Dice Pool Builder' button will ask the player which traits to include and roll in a dice pool. The output to the chat panel will also indicate if the character is shaken or stricken.
+
+Any feedback, or requests - I'm happy to hear.
+
+---
+
+Hammerheads is a part of the Cortex Prime Game Handbook published by Fandom Inc, and was written, designed, and developed by Cam Banks.
+Hammerheads uses the Cortex system. The Cortex system and the Fandom logos are © 2020 Fandom Inc. All rights reserved. Reference to other copyrighted material in no way constitutes a challenge to the respective copyright holders of that material.
+Artwork and graphics © and ™ Fandom Inc, illustrated by Ten Ten Studios Malaysia. All rights reserved.
+Character Portraits sourced from https://thispersondoesnotexist.com/
+
+
+##Changelog
+
+### V1.2 2021-03-22
+
+Added mobile layout support - which includes support for the beta release of the mobile app.
+Currently the beta release of the mobile app does not support the dice pool builder macros.
+Roll Template includes prompts when the character is shaken or stricken.
+Stress can now go higher than 12, if set a value of 14 the icon shows as 12+ to indicate being stressed out.
+
+
+### V1.2 2021-03-19
+
+Added a Roll Template, to better display the roll results.
+Added black dice icons and dark dice icons to use in roll template
+
+### V1.1 2021-03-17
+
+Fixed broken images
+Removed Trauma
+Added d10 and d12 settings to relationships
+Minor adjustments
+
+### v.1.0 2021-03-13"
\ No newline at end of file
diff --git a/CortexPrime-Hammerheads/sheet.json b/CortexPrime-Hammerheads/sheet.json
new file mode 100644
index 0000000000..f51304ede6
--- /dev/null
+++ b/CortexPrime-Hammerheads/sheet.json
@@ -0,0 +1,9 @@
+{
+ "html": "CortexPrime-Hammerhead.html",
+ "css": "CortexPrime-Hammerhead.css",
+ "authors": "Tapiochre",
+ "roll20userid": "73532",
+ "preview": "CortexPrime-Hammerhead.png",
+ "legacy": true,
+ "instructions": "Cortex Prime: Hammerhead Character Sheet\n\n##Set up\n\n- Open the Journal tab, and add a new Character.\n- Click on save changes.\n- Open the Character Sheet Tab\n- Tick the Edit Checkbox.\n- Select One of the Portraits, or select the dot next to the word Portrait to set no portrait.\n- Set the dice values for the Attributes, Training Packages, and Relationships using the drop downs.\n- Untick the Edit check box to hide the editor\n- Enter the remaining details - Name, Description, Value statements, Relationship names, Distinctions title and description in the editable text fields.\n\n##Stress\n\nI have been using API macros to adjust Stress values. But these are simply Attributes (PhysicalStress, MentalStress, SocialStress).\nYou can add these to the Attributes and Abilities tab manually, and assign values ranging from 2 to show the character has no stress - 4,6,8,10 or 12 corresponding to the dice value, or a value of 14 indicates the character has been stressed out.\n\n###Diceroller\n\nUsing the Dice-Pool-Builder button will ask the player which traits to include and roll in a dice pool. The output to the chat panel will also indicate if the character is shaken or stricken. \n\nIf you have added a stress and its not showing check the spelling, Capitalisation, and dice value to be sure you got those all correct.\n\nAny feedback, or requests - Im happy to hear.\n\n---\n\nHammerheads is a part of the Cortex Prime Game Handbook published by Fandom Inc, and was written, designed, and developed by Cam Banks.\nHammerheads uses the Cortex system. The Cortex system and the Fandom logos are © 2020 Fandom Inc. All rights reserved. Reference to other copyrighted material in no way constitutes a challenge to the respective copyright holders of that material.\nArtwork and graphics © and ™ Fandom Inc, illustrated by Ten Ten Studios Malaysia. All rights reserved.\nCharacter Portraits sourced from https://thispersondoesnotexist.com/\n"
+}
\ No newline at end of file
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.css b/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.css
new file mode 100644
index 0000000000..9c0129a305
--- /dev/null
+++ b/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.css
@@ -0,0 +1,296 @@
+ * {
+ font-family: cursive;
+ color: #444444;
+ border-collapse: collapse;
+ }
+
+ .sheet-legal {
+ font-size: 10px;
+ line-height: 14px;
+ padding: 5px 0 5px 12px;
+ margin: 0px;
+ color: rgba(55, 55, 25, 0.6);
+ font-family: sans-serif;
+ }
+
+ .sheet-preload{opacity:0;position:absolute}
+ .sheet-preload img{width:1px;height:1px}
+ select {
+ position: absolute;
+ right: 20px;
+ width: 90px !important;
+ }
+ input[type="text"],
+ textarea.sheet-value {
+ border: none;
+ background-color: rgba(255, 255, 255, 0.6) !important;
+ padding: 5px;
+ color: #000000 !important;
+ font-size: 14px;
+ line-height: 19px;
+ font-weight: 300;
+ }
+
+ textarea.sheet-value {
+ resize: vertical;
+ max-height: 70px;
+ }
+
+ .sheet-traitname {
+ font-size: 16px !important;
+ font-weight: 700 !important;
+ }
+
+ .sheet-inlineTrait {
+ padding: 0px 5px 5px 0 !important;
+ color: #444444 !important;
+ text-transform: none !important;
+ font-size: 13px !important;
+ font-weight: 400 !important;
+ }
+
+ .sheet-wrapper {
+ max-width: 900px;
+ min-width: 760px;
+ display: grid;
+ grid-gap: 10px;
+ grid-template-columns: repeat(2, 1fr ) ;
+ background-image: url(https://raw.githubusercontent.com/tapiochre/roll20-character-sheets/master/CortexPrime-Tales-of-Xadia-Playtest/assets/parchment.jpg);
+ background-clip: content-box
+ }
+ .sheet-fiveCol {
+ padding: 5px;
+ display: grid;
+ grid-gap: 5px;
+ grid-template-columns: repeat(5, 1fr);
+ }
+ .sheet-threeCol {
+ padding: 5px;
+ display: grid;
+ grid-gap: 5px;
+ grid-template-columns: repeat(3, 1fr);
+ }
+ .sheet-twoCol {
+ padding: 5px;
+ display: grid;
+ grid-gap: 5px;
+ grid-template-columns: repeat(2, 1fr);
+ }
+ .sheet-skills {
+ grid-column: auto;
+ display: grid;
+ grid-gap: 6px;
+ grid-template-columns: 1fr 1fr;
+ }
+ .sheet-title {
+ grid-row: 1;
+ font-weight: 800;
+ }
+
+ .sheet-box {
+ padding: 6px;
+ font-size: 11px;
+ }
+
+ .sheet-box .sheet-box {
+ background-color: rgba(255, 255, 255, 0.3)
+ border: 1px solid rgba(55, 55, 55, 0.3);
+ }
+ .sheet-skill {
+ font-size: small;
+ font-weight: 800;
+ text-align: center;
+ grid-column: auto;
+ border: 1px solid black;
+ }
+ .sheet-skill strong {
+ min-height: 35px;
+ display: block;
+ }
+ .sheet-distinctions {
+ display: grid;
+ grid-gap: 6px;
+ }
+ .sheet-distinction {
+ font-size: 13px;
+ font-weight: 300;
+ text-align: left;
+ margin-bottom: 5px;
+ }
+ .sheet-center img {
+ margin: 0 auto;
+ }
+ .sheet-trigger {
+ font-size: small;
+ }
+
+ .sheet-trauma {
+ background-color: rgba(172, 23, 37, 0.25);
+ font-weight: 800 !important;
+ color: #ffffff !important;
+ }
+
+ h1 {
+ font-size: 18px;
+ line-height: 26px;
+ padding: 0;
+ margin: 0;
+ color: #444444 !important;
+ }
+ h2 {
+ font-size: 16px;
+ line-height: 22px;
+ padding: 10px 0 10px 0;
+ margin: 0;
+ color: #444444 !important;
+ }
+ h3 {
+ font-size: 16px;
+ line-height: 20px;
+ padding: 0 0 5px 0;
+ margin: 0;
+ color: #444444 !important;
+ }
+ h4 {
+ font-size: 14px;
+ line-height: 16px;
+ padding: 9px 12px 10px 19px;
+ margin: 0;
+ color: #444444 !important;
+ }
+ /***
+ Interactive styles
+ input[type*="radio"]:not(:checked) + label{
+ display: none;
+ }
+ input[type*="radio"]:checked {
+ display: block;
+ }
+ ***/
+ input[name="attr_Edit"][value="on"] + div {
+ display: block !important;
+ }
+
+ button[type=roll].sheet-blank-roll-button::before {
+ content: '';
+ }
+
+ button[type="roll"].sheet-blank-roll-button {
+ color: #444444 !important;
+ border: 2px solid #444444 !important;
+ background-color: rgba(255, 255, 255, 0.6) !important;
+ width: 145px;
+ background-image: none !important;
+ padding: 2px 5px 2px 5px;
+ }
+
+ .sheet-locked[name="attr_Portrait"][value^="PC"] + div.sheet-pc {
+ display: block !important;
+ }
+ .sheet-locked[name="attr_Portrait"][value^="Cat"] + div.sheet-catalyst {
+ display: block !important;
+ }
+
+ .sheet-locked + div span,
+ .sheet-d0,
+ .sheet-d4,
+ .sheet-d6,
+ .sheet-d8,
+ .sheet-d10,
+ .sheet-d12,
+ .sheet-locked + div img.sheet-hide,
+ .sheet-locked + div .sheet-hide,
+ .sheet-locked + div.sheet-hide,
+ .sheet-locked + div span,
+ .sheet-locked[value="2"] + div h4,
+ .sheet-circle + div h4 {
+ display: none;
+ }
+ .sheet-locked[value="4"] + center img[alt="4"],
+ .sheet-locked[value="4"] + div img[alt="4"],
+ .sheet-locked[value="6"] + center img[alt="6"],
+ .sheet-locked[value="6"] + div img[alt="6"],
+ .sheet-locked[value="8"] + center img[alt="8"],
+ .sheet-locked[value="8"] + div img[alt="8"],
+ .sheet-locked[value="10"] + center img[alt="10"],
+ .sheet-locked[value="10"] + div img[alt="10"],
+ .sheet-locked[value="12"] + center img[alt="12"],
+ .sheet-locked[value="12"] + div img[alt="12"] {
+ display: block;
+ width: 35px;
+ height: 35px;
+ }
+ .sheet-locked[value="PC0"] + div img[alt="PC0"] {
+ display: block;
+ width: 240px;
+ height: 250px;
+ }
+
+ .sheet-locked[value="PC1"] + div img[alt="PC1"],
+ .sheet-locked[value="PC2"] + div img[alt="PC2"],
+ .sheet-locked[value="PC3"] + div img[alt="PC3"],
+ .sheet-locked[value="PC4"] + div img[alt="PC4"],
+ .sheet-locked[value="PC5"] + div img[alt="PC5"],
+ .sheet-locked[value="PC6"] + div img[alt="PC6"],
+ .sheet-locked[value="Cat1"] + div img[alt="Cat1"],
+ .sheet-locked[value="Cat2"] + div img[alt="Cat2"] {
+ display: block;
+ width: 234px;
+ height: 244px;
+ }
+
+ .sheet-locked[value="PC1"] + div.sheet-PC1,
+ .sheet-locked[value="PC2"] + div.sheet-PC2,
+ .sheet-locked[value="PC3"] + div.sheet-PC3,
+ .sheet-locked[value="PC4"] + div.sheet-PC4,
+ .sheet-locked[value="PC5"] + div.sheet-PC5,
+ .sheet-locked[value="PC6"] + div.sheet-PC6,
+ .sheet-locked[value="Cat1"] + div.sheet-Cat1,
+ .sheet-locked[value="Cat2"] + div.sheet-Cat2,
+ .sheet-locked[value="PC0"] + div div.sheet-PC0,
+ .sheet-locked[value="Cat1"] + div div.sheet-PC0,
+ .sheet-locked[value="Cat2"] + div div.sheet-PC0,
+ .sheet-locked[value="PC1"] + div div.sheet-PC1,
+ .sheet-locked[value="PC2"] + div div.sheet-PC2,
+ .sheet-locked[value="PC3"] + div div.sheet-PC3,
+ .sheet-locked[value="PC4"] + div div.sheet-PC4,
+ .sheet-locked[value="PC5"] + div div.sheet-PC5,
+ .sheet-locked[value="PC6"] + div div.sheet-PC6,
+ .sheet-locked[value="0"] + div[class="sheet-d0"],
+ .sheet-locked[value="4"] + div[class="sheet-d4"],
+ .sheet-locked[value="6"] + div[class="sheet-d6"],
+ .sheet-locked[value="8"] + div[class="sheet-d8"],
+ .sheet-locked[value="10"] + div[class="sheet-d10"],
+ .sheet-locked[value="12"] + div[class="sheet-d12"],
+ .sheet-locked[value="0"] + div span[class="sheet-d0"],
+ .sheet-locked[value="4"] + div span[class="sheet-d4"],
+ .sheet-locked[value="6"] + div span[class="sheet-d6"],
+ .sheet-locked[value="8"] + div span[class="sheet-d8"],
+ .sheet-locked[value="10"] + div span[class="sheet-d10"],
+ .sheet-locked[value="12"] + div span[class="sheet-d12"] {
+ display: block !important;
+ }
+
+ .sheet-locked[value|="PC"] + div button.sheet-pc {
+ display: inline-block !important;
+ }
+ .sheet-locked[value|="Cat"] + div button.sheet-catalyst {
+ display: inline-block !important;
+ }
+
+ .sheet-block-pc,
+ .sheet-block-switch:checked ~ .sheet-block-mobnpc {
+ display: block;
+ }
+ .sheet-block-mobpc,
+ .sheet-block-switch:checked ~ .sheet-block-pc {
+ display: none;
+ }
+ .sheet-circle[value="10"] + div h4 {
+ display: block;
+ }
+
+ .sheet-locked[value="4"] + div.sheet-skill,
+ .sheet-locked[value="4"] + div.sheet-skill {
+ display: none;
+ }
\ No newline at end of file
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.html b/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.html
new file mode 100644
index 0000000000..b4676e7e8a
--- /dev/null
+++ b/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.html
@@ -0,0 +1,1187 @@
+
+
+
Edit Dice Values
+
+
+ Catalyst or PC
+
+
+
+
+
+ Character
+
+
+
+
+
Attributes
+
+ [
+
+
+
+
+
+
+ ]
+
+
+ Agility
+
+
+
+
+ Awareness
+
+
+
+
+ Influence
+
+
+
+
+ Intellect
+
+
+
+
+ Spirit
+
+ hidden
+ 4
+ 6
+ 8
+ 10
+ 12
+
+
+
+
+ Strength
+
+
+
+ Catalyst
+
+
+
+
Values
+ [
+
+
+
+
+
+
+ ]
+
+
+ Devotion
+
+
+
+
+ Liberty
+
+
+
+
+ Glory
+
+
+
+
+ Mastery
+
+
+
+
+ Justice
+
+
+
+
+ Truth
+
+
+
+
Specialties
+ [
+
+
+ /
+
+
+
+ ]
+
+
+ Agriculture
+
+
+
+
+ Animal Training
+
+
+
+
+ Climbing
+
+
+
+
+ Crafting
+
+
+
+
+ Diplomacy
+
+
+
+
+ History
+
+
+
+
+ Politics
+
+
+
+
+ Spear Fighting
+
+
+
+
+ Sneaking
+
+
+
+
+ Stewardship
+
+
+
+
+ Strategy
+
+
+
+
+ Swordplay
+
+
+
+
+ Tracking
+
+
+
+
+ Dark Magic
+
+
+
+
+ Sky Magic
+
+
+
+
+ Sun Magic
+
+
+
+
+ Moon Magic
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dice Pool Builder
+
+
+
+
+
Name
+
+
+
+
Description
+
+
+
+
+
+
+
Values
+
+
Specialties
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Stress/Trauma [Added to your opponents pool]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Distinctions
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
+
Sunfire Elf
+
+
+
Heat-Being: Add
Angry stress in order to step up both your
Agility and
Strength for the duration of any test, contest, or challenge.
+
+
+
+
+
Hotheaded Sun Mage
+
+
+
+
+ Simplicity is the Best Solution
+
+
+
Straight to the Point: Spend a
and either gain a
asset or step up an existing asset when undertaking a challenge because of your keen insight.
+
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
+
Sunfire Elf
+
+
+
Heat-Being: Add
Angry stress in order to step up both your
Agility and
Strength for the duration of any test, contest, or challenge.
+
+
+
+
+
Knight of Lux Aurea
+
+
Stalwart: Spend a
to step down all of your stress dice after you succeed at a contest with a foe.
+
+
+
+
Fickle Luck
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
+
Moonshadow Elf
+
+
+
Elf Grace: Spend a
to step up your
Agility die in your dice pool for a test, contest, or challenge that factors in your elven speed and balance.
+
+
+
+
Moonshadow Form: When trying to hide, sneak, or go unseen during a full moon, spend a
to double your
Moonshadow Elf distinction die in your dice pool and keep an extra die in your total.
+
+
+
+
Homesick Assassin
+
+
+
A Song for All Occasions
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
+
Del Barian Hinterlander
+
+
+
Tough: Spend a
to convert your
Injured or
Exhausted stress into another kind of stress. If you already had stress of that new type, step up that stress.
+
+
+
+
+
Trailblazing Hunter
+
+
Keen Eye: Spend a
to double your
Awareness or
Agility die in your dice pool when following a trail, aiming at a distant target, or spotting something far off.
+
+
+
+
Foolhardy Friend
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
+
Durenian Noble
+
+
+
Herald of the Queen
+
+
Orate: Spend a
to double your
Influence or
Spirit die on a test, contest, or challenge that involves using your speaking voice.
+
+
+
+
You Don’t Have to Remind me!
+
+
+
Instant Recall: Spend a
to remember a helpful fact or detail from something you once read, giving yourself or an ally an asset for a single test, contest, or challenge.
+
+
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
+
Durenian Freefolk
+
+
+
Soldier of the Garden
+
+
Graceful Warrior: Spend a
to add both your
Agility and
Strength dice to your dice pool in a test, contest, or challenge that deals with battle, instead of just one attribute.
+
+
+
+
Never Back Down
+
+
+
Resolute: Spend a
to add one of your stress dice to a test, contest, or challenge. Step down that stress die afterwards.
+
+
+
+
+
+
Hinder: Gain a
when you switch out a distinction’s
for a
+
+
+
+
+
Asset
+
+
+
+
+
+
+
+
+
+
+
+
Tales of Xadia: The Dragon Prince Roleplaying Game is published by Fandom Inc.
+
Tales of Xadia: The Dragon Prince Roleplaying Game uses the Cortex system. The Cortex system and the Fandom logos are © 2020 Fandom Inc. All rights reserved. Reference to other copyrighted material in no way constitutes a challenge to the respective copyright holders of that material.
+
The Dragon Prince and all associated characters and elements are © 2020 Wonderstorm, Inc. and used under license by Fandom Inc. All rights reserved.
+
Artwork and graphics © and ™ Wonderstorm, Inc. All rights reserved.
+
+
\ No newline at end of file
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.png b/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.png
new file mode 100644
index 0000000000..a1c93ab645
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/ToX-CortexPrime.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/PC0.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC0.png
new file mode 100644
index 0000000000..702c8e4461
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC0.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/PC1.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC1.png
new file mode 100644
index 0000000000..d3fdfcf452
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC1.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/PC2.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC2.png
new file mode 100644
index 0000000000..4e367d1d2d
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC2.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/PC3.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC3.png
new file mode 100644
index 0000000000..ee4a08ef01
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC3.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/PC4.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC4.png
new file mode 100644
index 0000000000..09e350bdda
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC4.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/PC5.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC5.png
new file mode 100644
index 0000000000..b9fd8ba916
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC5.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/PC6.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC6.png
new file mode 100644
index 0000000000..5c5821d8c5
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/PC6.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/ToX_Logo.psd b/CortexPrime-Tales-of-Xadia-Playtest/assets/ToX_Logo.psd
new file mode 100644
index 0000000000..618080270b
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/ToX_Logo.psd differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/catalyst1.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/catalyst1.png
new file mode 100644
index 0000000000..3fc19284cc
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/catalyst1.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/catalyst2.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/catalyst2.png
new file mode 100644
index 0000000000..5f81132b64
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/catalyst2.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/cog-505x505.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/cog-505x505.png
new file mode 100644
index 0000000000..fbf4b1bd11
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/cog-505x505.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/d10-280x280.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/d10-280x280.png
new file mode 100644
index 0000000000..2dc95ecbcc
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/d10-280x280.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/d12-280x280.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/d12-280x280.png
new file mode 100644
index 0000000000..b51e8f6a7f
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/d12-280x280.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/d4-280x280.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/d4-280x280.png
new file mode 100644
index 0000000000..64950c165e
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/d4-280x280.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/d6-280x280.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/d6-280x280.png
new file mode 100644
index 0000000000..09838b2045
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/d6-280x280.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/d8-280x280.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/d8-280x280.png
new file mode 100644
index 0000000000..7f45f44eda
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/d8-280x280.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/parchment.jpg b/CortexPrime-Tales-of-Xadia-Playtest/assets/parchment.jpg
new file mode 100644
index 0000000000..f6b7a30e04
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/parchment.jpg differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/assets/plotpoint.png b/CortexPrime-Tales-of-Xadia-Playtest/assets/plotpoint.png
new file mode 100644
index 0000000000..0de78bb520
Binary files /dev/null and b/CortexPrime-Tales-of-Xadia-Playtest/assets/plotpoint.png differ
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/readme.md b/CortexPrime-Tales-of-Xadia-Playtest/readme.md
new file mode 100644
index 0000000000..10d629a5d7
--- /dev/null
+++ b/CortexPrime-Tales-of-Xadia-Playtest/readme.md
@@ -0,0 +1,43 @@
+Tales of Xadia: The Dragon Prince RPG - Playtest Character Sheet - Cortex Prime
+
+##Set up
+
+- Open the Journal tab, and add a new Character.
+- Click on save changes.
+- Open the Attributes and Abilities tab.
+- Add an attribute called 'Edit' and assign it the value'on'.
+- Now switch to the Character Sheet tab.
+- Select if this is going to be a PC or Catalyst character.
+- Select the Character name from the list - this will select the character portrait and fill out the distinction blocks. Select 'None' if you are not using any of the pregen characters.
+- Set the dice values for the Attributes, Values, and Specialities using the further drop downs.
+- Hide the Editor by removing the edit field from the Attributes and Abilities tab, or by assigning it the value 'off'.
+- Enter the remaining details - Name, Description, Value statements, Asset details and custom Distinctions in the editable text fields.
+
+- Repeat this for each of the remaining characters.
+
+##Dice Pool Builder
+
+The inbuilt Dice Pool Builder pulls from the character's attributes, rolls and keeps highest two dice in the pool by default. I refer to this as the suggested best result. If you create a Catalyst character the roller will adjust if you specified this in the edit feature.
+
+##Stress and Trauma
+
+I have been using API macro's to adjust Stress values. But these are simply Attributes (Afraid, Angry, Corrupted, Exhausted, Injured, Insecure and AfraidTrauma, AngryTrauma, CorruptedTrauma, ExhaustedTrauma, InjuredTrauma, InsecureTrauma).
+As with the Edit attribute you can add these to the Attributes and Abilities tab manually, and assign values ranging from the 4,6,8,10 or 12 corresponding to the dice value.
+
+The traits will only display on the character sheet as they are assigned to the character, in the same manner as the Specialities. If you have added a stress and it's not showing check the spelling, Capitalisation, and dice value to be sure you got those all correct.
+*Note* ToX does not use d4 stress so this value can be used to hide these fields on the character sheet.
+
+Any feedback, or requests - I'm happy to hear.
+
+---
+
+Tales of Xadia: The Dragon Prince Roleplaying Game is published by Fandom Inc.
+Tales of Xadia: The Dragon Prince Roleplaying Game uses the Cortex system. The Cortex system and the Fandom logos are © 2020 Fandom Inc. All rights reserved. Reference to other copyrighted material in no way constitutes a challenge to the respective copyright holders of that material.
+The Dragon Prince and all associated characters and elements are © 2020 Wonderstorm, Inc. and used under license by Fandom Inc. All rights reserved.
+Artwork and graphics © and ™ Wonderstorm, Inc. All rights reserved.
+
+
+##Changelog
+
+
+### v.1.2 2021-03-05
\ No newline at end of file
diff --git a/CortexPrime-Tales-of-Xadia-Playtest/sheet.json b/CortexPrime-Tales-of-Xadia-Playtest/sheet.json
new file mode 100644
index 0000000000..25375e33f6
--- /dev/null
+++ b/CortexPrime-Tales-of-Xadia-Playtest/sheet.json
@@ -0,0 +1,10 @@
+{
+ "html": "ToX-CortexPrime.html",
+ "css": "ToX-CortexPrime.css",
+ "authors": "Tapiochre",
+ "roll20userid": "73532",
+ "preview": "ToX-CortexPrime.png",
+ "instructions": "For use with the Cortex Prime Tales of Xadia Playtest.",
+ "legacy": true,
+ "instructions": "Tales of Xadia: The Dragon Prince RPG - Playtest Character Sheet - Cortex Prime\n\n##Set up\n\n- Open the Journal tab, and add a new Character.\n- Click on save changes.\n- Open the Attributes and Abilities tab.\n- Add an attribute called 'Edit' and assign it the value'on'.\n- Now switch to the Character Sheet tab.\n- Select if this is going to be a PC or Catalyst character. \n- Select the Character name from the list - this will select the character portrait and fill out the distinction blocks. Select 'None' if you are not using any of the pregen characters.\n- Set the dice values for the Attributes, Values, and Specialities using the further drop downs.\n- Hide the Editor by removing the edit field from the Attributes and Abilities tab, or by assigning it the value 'off'.\n- Enter the remaining details - Name, Description, Value statements, Asset details and custom Distinctions in the editable text fields.\n\n- Repeat this for each of the remaining characters.\n\n##Dice Pool Builder\n\nThe inbuilt Dice Pool Builder pulls from the character's attributes, rolls and keeps highest two dice in the pool by default. I refer to this as the suggested best result. If you create a Catalyst character the roller will adjust if you specified this in the edit feature.\n\n##Stress and Trauma\n\nI have been using API macro's to adjust Stress values. But these are simply Attributes (Afraid, Angry, Corrupted, Exhausted, Injured, Insecure and AfraidTrauma, AngryTrauma, CorruptedTrauma, ExhaustedTrauma, InjuredTrauma, InsecureTrauma).\nAs with the Edit attribute you can add these to the Attributes and Abilities tab manually, and assign values ranging from the 4,6,8,10 or 12 corresponding to the dice value.\n\nThe traits will only display on the character sheet as they are assigned to the character, in the same manner as the Specialities. If you have added a stress and it's not showing check the spelling, Capitalisation, and dice value to be sure you got those all correct.\n*Note* ToX does not use d4 stress so this value can be used to hide these fields on the character sheet.\n\nAny feedback, or requests - I'm happy to hear.\n\n---\n\nTales of Xadia: The Dragon Prince Roleplaying Game is published by Fandom Inc.\nTales of Xadia: The Dragon Prince Roleplaying Game uses the Cortex system. The Cortex system and the Fandom logos are © 2020 Fandom Inc. All rights reserved. Reference to other copyrighted material in no way constitutes a challenge to the respective copyright holders of that material.\nThe Dragon Prince and all associated characters and elements are © 2020 Wonderstorm, Inc. and used under license by Fandom Inc. All rights reserved.\nArtwork and graphics © and ™ Wonderstorm, Inc. All rights reserved.\n\n\n##Changelog\n\n\n### v.1.2 2021-03-05"
+}
\ No newline at end of file
diff --git a/Cultos-innombrables-hitos/HITOS.html b/Cultos-innombrables-hitos/HITOS.html
index dc2667476a..de785084ca 100644
--- a/Cultos-innombrables-hitos/HITOS.html
+++ b/Cultos-innombrables-hitos/HITOS.html
@@ -653,7 +653,7 @@ igual al resultado de su dado m.
Puntos de degeneración 7
Puntos de degeneración 6
Puntos de degeneración 5
- Putos de degeneración 4
+ Puntos de degeneración 4
Puntos de degeneración 3
Puntos de degeneración 2
Puntos de degeneración 1
@@ -968,7 +968,7 @@ igual al resultado de su dado m.
Puntos de drama 7
Puntos de drama 6
Puntos de drama 5
- Putos de drama 4
+ Puntos de drama 4
Puntos de drama 3
Puntos de drama 2
Puntos de drama 1
@@ -1037,7 +1037,7 @@ igual al resultado de su dado m.
Puntos de drama 7
Puntos de drama 6
Puntos de drama 5
- Putos de drama 4
+ Puntos de drama 4
Puntos de drama 3
Puntos de drama 2
Puntos de drama 1
diff --git a/Cyberpunk 2020/translations/fr.json b/Cyberpunk 2020/translations/fr.json
index b73d4e01ea..c22ee17374 100644
--- a/Cyberpunk 2020/translations/fr.json
+++ b/Cyberpunk 2020/translations/fr.json
@@ -5,26 +5,26 @@
"age": "Âge",
"aikido": "Aikido",
"aikido-3": "Aikido (3)",
- "aiming": "Aiming",
+ "aiming": "Viser",
"ambush": "Embuscade",
"ammo": "Munitions",
"animal-kung-fu": "Animal Kung Fu",
"animal-kung-fu-3": "Animal Kung Fu (3)",
"anthropology": "Anthropologie",
- "anti": "Anti-Person",
+ "anti": "Anti-personnel",
"anti-system": "Anti System",
"archery": "Tir à l’arc",
- "areo-tech": "Areo Tech",
+ "areo-tech": "Aerotech",
"armor": "Armure",
"armor-and-weapons": "Armes et armure",
"armor-notes": "Notes de l'Armure",
"athletics": "Athlétisme",
"attack": "Attaque",
"attacks-with": "attaque avec",
- "attractiveness": "Attractiveness",
- "attractiveness-abbr": "Attr",
- "attractiveness-skill": "Attractiveness Skill",
- "attribute": "Attribute",
+ "attractiveness": "Beauté",
+ "attractiveness-abbr": "BT",
+ "attractiveness-skill": "Compétence de Beauté",
+ "attribute": "Caractéristique",
"aug-total": "Aug Total",
"authority": "Autorité",
"autofire": "AutoFire",
@@ -37,7 +37,7 @@
"biology": "Biologie",
"blinded": "Aveuglé",
"body": "Corps",
- "body-skills": "Body Skills",
+ "body-skills": "Compétence de constitution",
"body-type": "Body Type",
"botany": "Botanique",
"boxing": "Boxe",
@@ -52,10 +52,10 @@
"cellular": " Cellular",
"character": "Personnage",
"character-points": "Character Points",
- "charismatic-leadership": "Charismatic Leadership",
+ "charismatic-leadership": "Commandement charismatique",
"chemistry": "Chimie",
- "chip": "Chip",
- "chipreader": " Chipreader",
+ "chip": "Puce",
+ "chipreader": "Lecteur de puce",
"choi-li-fut": "Choi Li Fut",
"choi-li-fut-3": "Choi Li Fut (3)",
"cipher": "Cipher",
@@ -64,7 +64,7 @@
"code-gate-strength": "Code Gate Strength",
"combat": "Combat",
"combat-deck": " Combat Deck",
- "combat-sense": "Combat Sense",
+ "combat-sense": "Sens du combat",
"comm": "Comm",
"command": "Command",
"command-points": "Command Points",
@@ -75,11 +75,11 @@
"cool": "Calme",
"cool-skills": "Cool Skills",
"cost": "Coût",
- "cost-total": "Cost Total",
+ "cost-total": "Coût total",
"cpu-number": "# of CPU",
- "credibility": "Credibility",
+ "credibility": "Crédibilité",
"critical": "Critique",
- "cryotank-operation": "Cryotank Operation",
+ "cryotank-operation": "Opération de Cryo-cuve",
"cyber": "Cyber",
"cyber-deck": "Cyber Deck",
"cyber-tech": "Cyber Tech",
@@ -192,13 +192,13 @@
"know-languages": "Know Languages",
"large": "Grande",
"laser-sight": "Laser Sight",
- "leadership": "Leadership",
+ "leadership": "Commandement",
"leap": "Saut",
- "left-arm": "L. Arm",
- "left-leg": "L. Leg",
+ "left-arm": "B. gauche",
+ "left-leg": "B. gauche",
"library-search": "Library Search",
- "life-events": "Life Events",
- "lift": "Lift",
+ "life-events": "Evènement de la vie",
+ "lift": "Soulever",
"light": "Lumière",
"locate": "Locate",
"location": "Localisation",
@@ -394,16 +394,16 @@
"very-reliable-abbr": "VR",
"videoboard": " Videoboard",
"voxbox": " Voxbox",
- "wardrobe": "Wardrobe & Style",
+ "wardrobe": "Habillement et style",
"weapon": "Arme",
- "weapon-accuracy-abbrv": "WA",
- "weapon-notes": "Weapon Notes",
+ "weapon-accuracy-abbrv": "Préc.",
+ "weapon-notes": "Info armes",
"weapons": "Armes",
- "weaponsmith": "Weaponsmith",
- "weaponsmith-2": "Weaponsmith (2)",
- "wilderness-survival": "Wilderness Survival",
- "wrestling": "Wrestling",
- "wrestling-1": "Wrestling (1)",
+ "weaponsmith": "Armurier",
+ "weaponsmith-2": "Armurier (2)",
+ "wilderness-survival": "Surv. milieu hostile",
+ "wrestling": "Catch",
+ "wrestling-1": "Catch (1)",
"yes": "Oui",
"zoology": "Zoologie"
}
\ No newline at end of file
diff --git a/Cyberpunk 2020/translations/ko.json b/Cyberpunk 2020/translations/ko.json
index 7658e8b7d0..7bbd302aa4 100644
--- a/Cyberpunk 2020/translations/ko.json
+++ b/Cyberpunk 2020/translations/ko.json
@@ -2,7 +2,7 @@
"accounting": "Accounting",
"aero-tech": "Aero Tech",
"aero-tech-2": "Aero Tech (2)",
- "age": "Age",
+ "age": "나이",
"aikido": "Aikido",
"aikido-3": "Aikido (3)",
"aiming": "Aiming",
@@ -10,7 +10,7 @@
"ammo": "Ammo",
"animal-kung-fu": "Animal Kung Fu",
"animal-kung-fu-3": "Animal Kung Fu (3)",
- "anthropology": "Anthropology",
+ "anthropology": "인류학",
"anti": "Anti-Person",
"anti-system": "Anti System",
"archery": "궁술",
@@ -21,12 +21,12 @@
"athletics": "Athletics",
"attack": "Attack",
"attacks-with": "attacks with",
- "attractiveness": "Attractiveness",
- "attractiveness-abbr": "Attr",
- "attractiveness-skill": "Attractiveness Skill",
+ "attractiveness": "매력",
+ "attractiveness-abbr": "매력",
+ "attractiveness-skill": "매력 계열 스킬",
"attribute": "Attribute",
"aug-total": "Aug Total",
- "authority": "Authority",
+ "authority": "권위",
"autofire": "AutoFire",
"av-tech": "AV Tech",
"av-tech-3": "AV Tech (3)",
@@ -37,22 +37,22 @@
"biology": "Biology",
"blinded": "Blinded",
"body": "Body",
- "body-skills": "Body Skills",
- "body-type": "Body Type",
+ "body-skills": "신체 계열 기술",
+ "body-type": "신체",
"botany": "Botany",
- "boxing": "Boxing",
- "boxing-1": "Boxing (1)",
+ "boxing": "복싱",
+ "boxing-1": "복싱 (1)",
"brawling": "Brawling",
"btm": "BTM",
"called-shot": "Called Shot",
- "capoeria": "Capoeria",
- "capoeria-3": "Capoeria (3)",
+ "capoeria": "카포에라",
+ "capoeria-3": "카포에라 (3)",
"carried": "Carried/Max",
"carry": "Carry",
- "cellular": " Cellular",
+ "cellular": "셀룰러",
"character": "캐릭터",
"character-points": "Character Points",
- "charismatic-leadership": "Charismatic Leadership",
+ "charismatic-leadership": "통솔력",
"chemistry": "Chemistry",
"chip": "Chip",
"chipreader": " Chipreader",
@@ -62,7 +62,7 @@
"class": "Class",
"close": "가까운",
"code-gate-strength": "Code Gate Strength",
- "combat": "Combat",
+ "combat": "전투",
"combat-deck": " Combat Deck",
"combat-sense": "Combat Sense",
"comm": "Comm",
@@ -73,22 +73,22 @@
"control": "Control",
"controller": "Controller",
"cool": "침착",
- "cool-skills": "Cool Skills",
+ "cool-skills": "냉정 계열 기술",
"cost": "Cost",
"cost-total": "Cost Total",
- "cpu-number": "# of CPU",
- "credibility": "Credibility",
- "critical": "Critical",
+ "cpu-number": "CPU 개수",
+ "credibility": "신용",
+ "critical": "중상",
"cryotank-operation": "Cryotank Operation",
"cyber": "Cyber",
"cyber-deck": "Cyber Deck",
"cyber-tech": "사이버네틱 기술자",
"cyberdeck-design": "Cyberdeck Design",
"cyberdeck-design-2": "Cyberdeck Design (2)",
- "cyberdeck-specs": "Cyberdeck Specs",
+ "cyberdeck-specs": "사이버 덱 사양",
"cyberlimb-deck": " Cyberlimb Deck",
"cybernetics": "사이버네틱",
- "cyberpunk": "Cyberpunk 2020 Character Sheet",
+ "cyberpunk": "Cyberpunk 2020 캐릭터 시트",
"cybertech": "Cybertech",
"cybertech-2": "Cybertech (2)",
"damage": "Damage",
@@ -117,11 +117,11 @@
"electronic-security": "Electronics Security",
"electronic-security-2": "Electronics Security (2)",
"electronics": "Electronics",
- "empathy": "Empathy",
- "empathy-abbr": "Emp",
+ "empathy": "공감",
+ "empathy-abbr": "공감",
"empathy-convince-fast": "Empathy, Convince, Fast-Talk",
- "empathy-skills": "Empathy Skills",
- "endurance": "Endurance",
+ "empathy-skills": "공감 계열 기술",
+ "endurance": "인내",
"eurobucks": "Eurobucks",
"evasion": "회피도",
"execute": "Execute",
@@ -130,7 +130,7 @@
"extra-chips": " Extra Chips",
"extreme": "Extreme",
"familiarity-points": "Familiarity Points",
- "family": "Family",
+ "family": "가족",
"fast-draw": "Fast draw/Snapshot",
"fencing": "Fencing",
"file": "File/Database",
@@ -152,7 +152,7 @@
"gyro-tech-3": "Gyro Tech (3)",
"hacking": "Hacking",
"handgun": "Handgun",
- "handle": "Handle",
+ "handle": "이름",
"head": "머리",
"heavy-weapon": "Heavy Weapon",
"heavy-weapons": "Heavy Weapons",
@@ -166,27 +166,27 @@
"hit-location-7to8": "Hit Location '7 to 8' ",
"hit-location-9to10": "Hit Location '9 to 10' ",
"human-perception": "Human Perception",
- "humanity": "Humanity",
+ "humanity": "인간성",
"humanity-loss-abbr": "HL",
"immobile": "Immobile",
"improvement-points-abbr": "IP",
"infiltrate": "Infiltrate/Login",
"initiates-program": "initiates program",
"initiative": "Initiative",
- "intelligence": "Intelligence",
- "intelligence-abbr": "Int",
- "intelligence-skills": "Intelligence Skills",
+ "intelligence": "지능",
+ "intelligence-abbr": "지능",
+ "intelligence-skills": "지능 계열 기술",
"interface": "인터페이스",
- "interrogation": "Interrogation",
+ "interrogation": "심문",
"interview": "인터뷰",
- "intimidate": "Intimidate",
+ "intimidate": "위협",
"intrusion": "Intrusion",
- "inventory": "Inventory",
- "judo": "Judo",
- "judo-1": "Judo (1)",
- "jury-rig": "Jury Rig",
- "karate": "Karate",
- "karate-2": "Karate (2)",
+ "inventory": "소지품",
+ "judo": "유도",
+ "judo-1": "유도 (1)",
+ "jury-rig": "임시 방편",
+ "karate": "가라테",
+ "karate-2": "가라테 (2)",
"keyboard": " Keyboard",
"know-language": "Know Language",
"know-languages": "Know Languages",
@@ -194,51 +194,51 @@
"laser-sight": "Laser Sight",
"leadership": "Leadership",
"leap": "Leap",
- "left-arm": "L. Arm",
- "left-leg": "L. Leg",
+ "left-arm": "왼팔",
+ "left-leg": "왼다리",
"library-search": "Library Search",
"life-events": "Life Events",
"lift": "Lift",
- "light": "빛",
+ "light": "경상",
"locate": "Locate",
"location": "Location",
"location-roll": "Location Roll",
"long": "Long",
"lose-cool": "lose their cool and draws down!",
- "luck": "Luck",
+ "luck": "행운",
"martial-art-aikido": "Martial Art - Aikido",
"martial-art-animal-kungfu": "Martial Art - Animal Kung Fu",
- "martial-art-boxing": "Martial Art - Boxing",
- "martial-art-capoeria": "Martial Art - Capoeria",
+ "martial-art-boxing": "무술 - 복싱",
+ "martial-art-capoeria": "무술 - 카포에라",
"martial-art-choi-li-fut": "Martial Art - Choi Li Fut",
- "martial-art-judo": "Martial Art - Judo",
- "martial-art-karate": "Martial Art - Karate",
- "martial-art-savate": "Martial Art - Savate",
- "martial-art-tae-kwon-do": "Martial Art - Tae Kwon Do",
- "martial-art-thai-kick-boxing": "Martial Art - Thai Kick Boxing",
- "martial-art-wrestling": "Martial Art - Wrestling",
+ "martial-art-judo": "무술 - 유도",
+ "martial-art-karate": "무술 - 가라테",
+ "martial-art-savate": "무술 - 사바트",
+ "martial-art-tae-kwon-do": "무술 - 태권도",
+ "martial-art-thai-kick-boxing": "무술 - 무에타이",
+ "martial-art-wrestling": "무술 - 레슬링",
"martial-arts": "무술",
"mathematics": "Mathematics",
- "medical-tech": "Medical Tech",
+ "medical-tech": "의술",
"medium": "중화질",
"medium-plus": "Medium +",
- "melee": "Melee",
- "memory": "Memory",
+ "melee": "백병전",
+ "memory": "메모리",
"memory-units-abbr": "MU",
"mod": "모",
- "model": "Model",
+ "model": "모델",
"modem": "Modem",
"modifier": "Modifier",
"modifiers": "Modifiers",
"mortal": "Mortal",
- "mortal-0": "Mortal 0",
- "mortal-1": "Mortal 1",
- "mortal-2": "Mortal 2",
- "mortal-3": "Mortal 3",
- "mortal-4": "Mortal 4",
- "mortal-5": "Mortal 5",
- "mortal-6": "Mortal 6",
- "motorcycle": "Motorcycle",
+ "mortal-0": "치명상 0",
+ "mortal-1": "치명상 1",
+ "mortal-2": "치명상 2",
+ "mortal-3": "치명상 3",
+ "mortal-4": "치명상 4",
+ "mortal-5": "치명상 5",
+ "mortal-6": "치명상 6",
+ "motorcycle": "오토바이",
"movement-allowence-abbr": "Ma",
"moving": "Moving",
"name": "이름",
@@ -247,24 +247,24 @@
"none": "없음",
"not-listed": "not listed",
"notes": "Notes",
- "operate-heavy-machine": "Operate Heavy Machinery",
- "options": "Options?",
- "oratory": "Oratory",
+ "operate-heavy-machine": "중장비 조작",
+ "options": "옵션?",
+ "oratory": "웅변",
"other": "Other",
- "other-attractiveness": "Other Attractiveness Skills",
- "other-body-skills": "Other Body Skills",
- "other-cool-skills": "Other Cool Skills",
- "other-empathy-skills": "Other Empathy Skills",
- "other-intelligence-skill": "Other Intelligence Skill",
- "other-intelligence-skills": "Other Intelligence Skills",
- "other-notes": "Other Notes",
- "other-reflex-skills": "Other Reflex Skills",
- "other-special-abilities": "Other Special Abilities",
- "other-technical-skill": "Other Technical Skills",
+ "other-attractiveness": "기타 매력 계열 스킬",
+ "other-body-skills": "기타 신체 계열 기술",
+ "other-cool-skills": "기타 냉정 계열 기술",
+ "other-empathy-skills": "기타 공감 계열 기술",
+ "other-intelligence-skill": "기타 지능 계열 기술",
+ "other-intelligence-skills": "기타 지능 계열 기술",
+ "other-notes": "기타",
+ "other-reflex-skills": "기타 반사신경 계열 기술",
+ "other-special-abilities": "기타 특수 능력",
+ "other-technical-skill": "기타 테크능력 계열 기술",
"paint-or-draw": "Paint or Draw",
"perform": "Perform",
"personal-grooming": "Personal Grooming",
- "personal-information": "Personal Information",
+ "personal-information": "개인 정보",
"persuasion": "Persuasion & Fast Talk",
"pharmaceuticals": "Pharmaceuticals",
"pharmaceuticals-2": "Pharmaceuticals (2)",
@@ -280,7 +280,7 @@
"play-instrument": "Play Instrument",
"points": "Points",
"points-abbr": "Pts",
- "portable": " Portable",
+ "portable": "휴대용",
"printer": " Printer",
"process-limit": "Process Limit:",
"program-notes": "Programs Notes",
@@ -291,23 +291,23 @@
"R": "ST",
"range": "Range",
"rate-of-fire-abbrv": "ROF",
- "reflex": "Reflex",
- "reflex-10": "Reflex > 10",
- "reflex-12": "Reflex > 12",
- "reflex-14": "Reflex > 14",
- "reflex-skills": "Reflex Skills",
- "reflexes-abbr": "Ref",
+ "reflex": "반사신경",
+ "reflex-10": "반사신경 > 10",
+ "reflex-12": "반사신경 > 12",
+ "reflex-14": "반사신경 > 14",
+ "reflex-skills": "반사신경 계열 기술",
+ "reflexes-abbr": "반사신경",
"reliability-abbrv": "Rel.",
"reliable-abbr": "R",
"remote": "Remote",
"repair-build>": "Repair/Build",
"requires-a-target-token": "Requires a target token",
- "resist-torture": "Resist Torture/Drugs",
+ "resist-torture": "고문/약물 저항",
"resources": "Resources",
"ricochet": "Ricochet/Indirect",
- "rifle": "Rifle",
- "right-arm": "R. Arm",
- "right-leg": "R. Leg",
+ "rifle": "소총",
+ "right-arm": "오른팔",
+ "right-leg": "오른다리",
"role": "Role",
"roll": "굴림",
"roll-less-than": "Roll less than:",
@@ -320,8 +320,8 @@
"run-dot-net-combat": "Run.Net Combat",
"run-program": "Run Program",
"running": "Running",
- "savate": "Savate",
- "savate-2": "Savate (2)",
+ "savate": "사바트",
+ "savate-2": "사바트 (2)",
"save": "Save",
"scan": "Scan",
"scanner": " Scanner",
@@ -329,7 +329,7 @@
"secure": "보안",
"seduction": "Seduction",
"sensor": "Sensor",
- "serious": "Serious",
+ "serious": "부상",
"shadow": "Shadow/Track",
"shield": "Shield",
"shooter": "Shooter",
@@ -337,29 +337,29 @@
"silhouetted": "Silhouetted",
"simple": "Simple",
"size": "Size",
- "skill": "Skill",
+ "skill": "기술",
"skill-setup": "Skill Setup",
"skills": "Skills",
"small": "작음",
"smartgun": "Smartgun/Goggles",
"social": "Social",
- "special-abilities": "Special Abilities",
+ "special-abilities": "특수 능력",
"speed": "Speed",
- "standard": " Standard",
+ "standard": " 기본",
"stealth": "Stealth",
"stealth-2": "Stealth (2)",
"stock-market": "Stock Market",
"str": "Str",
- "streetdeal": "Streetdeal",
- "streetwise": "Streetwise",
- "strength-feat": "Strength Feat",
+ "streetdeal": "뒷소문",
+ "streetwise": "거리지식",
+ "strength-feat": "차력",
"style-and-motivations": "Style and Motivations",
"submachinegun": "Submachinegun",
- "swimming": "Swimming",
+ "swimming": "수영",
"system": "System",
"system-knowledge": "System Knowledge",
- "tae-kwon-do": "Tae Kwon Do",
- "tae-kwon-do-3": "Tae Kwon Do (3)",
+ "tae-kwon-do": "태권도",
+ "tae-kwon-do-3": "태권도 (3)",
"target": "Target",
"target-points": "Target Points",
"targeted": "Targeted",
@@ -367,23 +367,23 @@
"targeting": "Targeting",
"teaching": "Teaching",
"technical": "Technical",
- "technical-ability-abbr": "Tech",
- "technical-skills": "Technical Skills",
+ "technical-ability-abbr": "테크능력",
+ "technical-skills": "테크능력 계열 기술",
"telescopic-extreme": "Telescopic, Extreme",
"telescopic-long": "Telescopic, Long",
"temporary-modifier-abbr": "Temp Mod",
- "thai-kick-boxing": "Thai Kick Boxing",
- "thai-kick-boxing-4": "Thai Kick Boxing (4)",
+ "thai-kick-boxing": "무에타이",
+ "thai-kick-boxing-4": "무에타이 (4)",
"three-round-burst": "Three Round Burst",
"tiny": "Tiny",
- "torso": "Torso",
+ "torso": "몸통",
"total": "총",
"total-cost": "Total Cost",
"tries-to-stay-in-the-fight": "tries to stay in the fight!",
"trodes": " Trodes",
"turret": "Turret",
"two-weapons": "Two Weapons",
- "uninjured": "Uninjured",
+ "uninjured": "무사",
"unreliable-abbr": "UR",
"user": "User/Runner",
"utility": "Utility",
@@ -402,8 +402,8 @@
"weaponsmith": "Weaponsmith",
"weaponsmith-2": "Weaponsmith (2)",
"wilderness-survival": "Wilderness Survival",
- "wrestling": "Wrestling",
- "wrestling-1": "Wrestling (1)",
+ "wrestling": "레슬링",
+ "wrestling-1": "레슬링 (1)",
"yes": "예",
"zoology": "Zoology"
}
\ No newline at end of file
diff --git a/Cyberpunk 2020/translations/pl.json b/Cyberpunk 2020/translations/pl.json
index 8d903697ec..9f6839d893 100644
--- a/Cyberpunk 2020/translations/pl.json
+++ b/Cyberpunk 2020/translations/pl.json
@@ -199,7 +199,7 @@
"library-search": "Przeszukiwanie baz danych",
"life-events": "Wydarzenia życiowe",
"lift": "Podn.",
- "light": "Światło",
+ "light": "Lekkie",
"locate": "Zlokalizuj",
"location": "Lokacja",
"location-roll": "Rzut na lokalizacje",
diff --git a/D&D_3-5/translations/pl.json b/D&D_3-5/translations/pl.json
index 2c93a8fc41..252a7d3c90 100644
--- a/D&D_3-5/translations/pl.json
+++ b/D&D_3-5/translations/pl.json
@@ -1,14 +1,14 @@
{
"pc": "PC ",
- "npc": "NPC",
+ "npc": "BN",
"header": "Header",
- "character-name": "Character Name",
- "player-name": "Player Name",
- "experience-points": "Experience Points",
+ "character-name": "Imię bohatera",
+ "player-name": "Imię Gracza/Graczki",
+ "experience-points": "Punkty doświadczenia",
"homeland": "Homeland",
- "race": "Race",
+ "race": "Rasa",
"type": "Typ",
- "colossal": "Colossal",
+ "colossal": "Kolosalny",
"gargantuan": "Gargantuan",
"huge": "Huge",
"large": "Duży",
@@ -17,46 +17,46 @@
"tiny": "Tiny",
"diminutive": "Diminutive",
"fine": "Fine",
- "size": "Size",
- "gender": "Gender",
+ "size": "Rozmiar",
+ "gender": "Płeć",
"alignment": "Alignment",
"deity": "Deity",
- "class": "Class",
+ "class": "Klasa",
"level": "Poziom",
"hit-dice-i": "HD",
- "age": "Age",
+ "age": "Wiek",
"height": "Wzrost",
- "weight": "Weight",
- "eyes": "Eyes",
- "hair": "Hair",
+ "weight": "Waga",
+ "eyes": "Oczy",
+ "hair": "Włosy",
"stats": "Stats",
"weapons": "Weapons",
- "armor-class-i": "AC",
- "equipment": "Equipment",
- "skills": "Skills",
- "spells": "Spells",
- "notes": "Notes",
- "miscellaneous": "Misc",
+ "armor-class-i": "KP",
+ "equipment": "Ekwipunek",
+ "skills": "Umiejętności",
+ "spells": "Czary",
+ "notes": "Notatki",
+ "miscellaneous": "Inne",
"all": "All",
"abilities": "Abilities",
"ability-scores": "Ability Scores",
"ability": "Ability",
"total": "Suma",
- "modifier": "Mod",
+ "modifier": "Mod.",
"base": "Bazowy",
"temporary": "Temp",
- "strength-i": "STR",
+ "strength-i": "Sił",
"note": "Note",
- "dexterity-i": "DEX",
- "constitution-i": "CON",
+ "dexterity-i": "ZR",
+ "constitution-i": "Kon",
"intelligence-i": "INT",
- "wisdom-i": "WIS",
- "charisma-i": "CHA",
+ "wisdom-i": "Mdr",
+ "charisma-i": "Cha",
"show-ability-macros": "Show Ability Macros",
- "hit-points-i": "HP",
- "hit-points": "Hit Points",
+ "hit-points-i": "PW",
+ "hit-points": "Punkty Wytrzymałości",
"current-hit-points": "Current HP",
- "max": "Max",
+ "max": "Maks.",
"nonlethal-damage": "Nonlethal Damage",
"initiative-u": "INITIATIVE",
"dexterity-modifier": "Dex Mod",
@@ -87,9 +87,9 @@
"touch-u": "TOUCH",
"flat-footed-u": "FLAT-FOOTED",
"immobile": "Immobile",
- "damage-reduction": "Damage Reduction",
+ "damage-reduction": "Redukcja Obrażeń",
"saves-combat-notes": "Saves, Combat, Notes",
- "saving-throws-s": "Saving Throws",
+ "saving-throws-s": "Rzuty Obronne",
"base-save-s": "Base Save",
"ability-modifier-s": "Ability Modifier",
"epic-save-bonus-s": "Epic Save Bonus",
@@ -99,19 +99,19 @@
"fortitude": "Fortitude",
"constitution": "Constitution",
"reflex": "Reflex",
- "dexterity": "Dexterity",
- "will": "Will",
- "wisdom": "Wisdom",
+ "dexterity": "Zręczność",
+ "will": "Wola",
+ "wisdom": "Mądrość",
"show-save-macros": "Show Save Macros",
"spell-resistance": "Spell Resist",
"arcane-spell-failure": "Arcane Spell Failure",
"base-attack": "Base Attack",
"grapple": "Grapple",
"base-attack-bonus-epic-attack-bonus-i": "BAB+ EAB",
- "strength-modifier-a": "Str Mod",
+ "strength-modifier-a": "Mod. z Siły",
"base-attack-bonus-epic-attack-bonus-a": "Base AB + Epic AB",
- "strength-modifier": "Strength Modifier",
- "size-modifier": "Size Modifier",
+ "strength-modifier": "Modyfikator z Siły",
+ "size-modifier": "Modyfikator Rozmiaru",
"miscellaneous-modifier": "Misc Modifier",
"temporary-modifier": "Temp Modifier",
"melee": "Melee",
@@ -121,9 +121,9 @@
"epic-levels": "Epic Levels",
"epic-save-bonus": "Epic Save Bonus",
"epic-attack-bonus": "Epic Attack Bonus",
- "languages": "Languages",
- "racial-abilities": "Racial Abilities",
- "class-abilities": "Class Abilities",
+ "languages": "Języki",
+ "racial-abilities": "Atuty Rasowe",
+ "class-abilities": "Atuty klasowe",
"feats": "Feats",
"other": "Other",
"weapon": "Weapon",
diff --git a/Daemon Exilia/Bug.txt b/Daemon Exilia/Bug.txt
new file mode 100644
index 0000000000..9f7e1dcc83
--- /dev/null
+++ b/Daemon Exilia/Bug.txt
@@ -0,0 +1,11 @@
+
+
+A ficha de personagem Daemon Exilia apresenttou um problema na ultima semana, aparentemente ela não reconhece o css.
+a ficha de personagem custon com a opição "Forces sheet to use the more limited legacy version of CSS and HTML sanitization"
+funciona normalmente mas a vesão do roll20 esta bugada.
+
+tradutor goglee
+
+The character sheet Daemon Exilia had a problem in the last week, apparently she does not recognize the css.
+the custon character sheet with the option "Force sheet to use the more limited legacy version of CSS and sanitization of HTML"
+works normally but the roll20 version is buggy.
\ No newline at end of file
diff --git a/Daemon Exilia/Exilia.css b/Daemon Exilia/Exilia.css
new file mode 100644
index 0000000000..5e803a5fe0
--- /dev/null
+++ b/Daemon Exilia/Exilia.css
@@ -0,0 +1,1561 @@
+@font-face {
+ font-family: 'Round Style Basic';
+ src: url('https://candyfonts.com/wp-data/2018/10/09/228/RoundStyleBasic.ttf') format('truetype');
+ font-weight: normal;
+ font-style: normal;
+}
+* {
+ font-family: "Round Style Basic";
+}
+.charsheet {
+ background-color:#F5F5F5;
+ width: 804px;
+ background-repeat: repeat;
+ background-size: cover;
+ border: solid 3px black;
+ color: transparent;
+ margin-left: 20px;
+
+}
+
+/*corpo da ficha*/
+.sheet-main {
+ margin: 0 auto;
+ font-size: 13px;
+ color: black;
+ width: 800px;
+ background-repeat: no-repeat;
+ background-size: cover;
+ column-gap: 22px;
+ grid-template-columns: 516px 312px;
+ min-height: 1200px
+}
+/* css logo exilia*/
+.sheet-main .sheet-container-logo .sheet-logo-exilia {
+ width: 200px;
+ height: 185px;
+ float: right;
+}
+/*css do cabeçalho de informações do personagem*/
+.sheet-main .sheet-header-info {
+ margin-top: 1%;
+ display: grid;
+ width: 600px;
+ height: 100px;
+ grid-template-columns: 50px 50px left;
+ column-gap: 10px;
+ }
+.sheet-main .sheet-input-with-text-bellow {
+ display: flex;
+ flex-direction: column
+}
+.sheet-main .sheet-input-with-text-bellow input {
+ width: 100%;
+ height: 24px;
+ border: 0;
+ background-color: transparent;
+ border-bottom: solid 2px black;
+ line-height: 24px;
+ padding-left: 2px;
+ padding-right: 2px
+}
+.sheet-main .sheet-input-with-text-bellow span {
+ display: block;
+ padding-top: 2px;
+ padding-left: 2px;
+ width: 100%;
+ font-size: 13px;
+ font-weight: bold;
+ text-transform: uppercase
+}
+.sheet-main .sheet-input-with-text-bellow.sheet-char-name {
+ padding-top: 15px;
+ grid-column: 1/5
+}
+.sheet-char-info {
+ font-size: 13px;
+ font-weight: bold;
+ color: #808080;
+}
+/*linha de difisão do atributo*/
+.sheet-main .sheet-linha-de-divisao {
+ margin-top: 50px;
+ background-image: url(https://i.imgur.com/NTZLN33.png);
+ background-size: 800px 65px;
+ background-repeat: no-repeat;
+ width: 800px;
+ height: 70px;
+ text-align: center;https://app.roll20.net/campaigns/campaignsettings/9178552#customsheet-translation
+ position: relative;
+}
+.sheet-main .sheet-linha-de-divisao h3 {
+ padding-top: 35px;
+}
+/*css dos dados atributo*/
+.sheet-atri1{
+ margin-top:-22px;
+
+}
+
+.sheet-coluna-atributo{
+ margin-top:-16px;
+}
+
+button[type="roll"].sheet-dado1:before {
+ content: ' ';
+}
+button[type="roll"].sheet-dado1:hover {
+ background-position: 0;
+ box-shadow: 0px 0px 20px #00FF0B;
+ background-color: #9CF7A0;
+}
+button[type="roll"].sheet-dado1 {
+ background-image: url(https://i.imgur.com/7qkxCK7.png);
+ background-size: 25px 26px;
+ background-repeat: no-repeat;
+ width: 19px;
+ height: 26px;
+ border-style: none;
+ background-color: transparent;
+}
+button[type="roll"].sheet-dado2:before {
+ content: ' ';
+}
+button[type="roll"].sheet-dado2:hover {
+ background-position: 0;
+ box-shadow: 0px 0px 20px #FCE300;
+ background-color: #F7EE9C;
+}
+button[type="roll"].sheet-dado2 {
+ background-image: url(https://i.imgur.com/7qkxCK7.png);
+ background-size: 25px 26px;
+ background-repeat: no-repeat;
+ width: 19px;
+ height: 26px;
+ border-style: none;
+ background-color: transparent;
+}
+button[type="roll"].sheet-dado3:before {
+ content: ' ';
+}
+button[type="roll"].sheet-dado3:hover {
+ background-position: 0;
+ box-shadow: 0px 0px 20px #FF0003;
+ background-color: #F9999A;
+}
+button[type="roll"].sheet-dado3 {
+ background-image: url(https://i.imgur.com/7qkxCK7.png);
+ background-size: 25px 26px;
+ background-repeat: no-repeat;
+ width: 19px;
+ height: 26px;
+ border-style: none;
+ background-color: transparent;
+}
+/*--dado inciativa--*/
+button[type="roll"].sheet-dado7:before {
+ content: ' ';
+}
+button[type="roll"].sheet-dado7:hover {
+ background-position: 0;
+ background-image: url(https://i.imgur.com/zfXSgvw.png);
+ box-shadow: 0px 0px 20px #FF7E00;
+ background-color: #FFD0A4;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+button[type="roll"].sheet-dado7 {
+ background-image: url(https://i.imgur.com/zfXSgvw.png);
+ background-size: 30px 30px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 30px;
+ height: 30px;
+ border-style: none;
+ border: none;
+}
+/*css linhas e colunas dos atributos*/
+.sheet-coluna1 {
+ background-image: url();
+ background-size: 92px 26px;
+ background-repeat: no-repeat;
+ background-color: #D3D3D3;
+ padding-left: 1px;
+ border: 1px solid #333333;
+ border-bottom: 2px solid #333333;
+ margin-top: 3px;
+ font-size: 13px;
+ font-weight: bold;
+ color: black text-align: center;
+ width: 80px;
+ height: 30px;
+}
+.sheet-linha1 {
+ background-image: url();
+ background-size: 46px 26px;
+ background-repeat: no-repeat;
+ border-style: black;
+ background-color: ;
+ padding-left: 1px;
+ border: 1px solid #333333;
+ border-bottom: 2px solid #333333;
+ margin-top: 3px;
+ font-size: 13px;
+ font-weight: bold;
+ color: black text-align: center;
+ width: 47px;
+ height: 30px;
+}
+.sheet-linha_dado {
+ background-image: url();
+ background-size: 21px 26px;
+ text-align: center;
+ background-repeat: no-repeat;
+ margin-top: 5px;
+ margin-bottom: 4px;
+ margin-left: 6px;
+ margin-right: 4PX;
+ width: 21px;
+ height: 2px;
+ border-style: black;
+ background-color: ;
+ padding-left: 1px;
+ border: 1px solid #333333;
+ border-bottom: 2px solid #333333;
+ font-weight: bold;
+ color: black text-align: center;
+}
+
+.sheet-inic-add {
+ font-size: 20px;
+ font-weight: bold;
+ color: black
+ text-align: center;
+ background-color: transparent;
+ Border:none;
+}
+/*css linhas e colunas dos sub-atributos*/
+.sheet-block-a, .sheet-block-switch:checked ~ .sheet-block-b {
+ display: block;
+}
+.sheet-block-b, .sheet-block-switch:checked ~ .sheet-block-a {
+ display: none;
+}
+.sheet-I1 input[type="text"] {
+ background-image: url(https://i.imgur.com/GUI0tbP.png);
+ background-size: 98px 40px;
+ margin-left: 12px;
+ margin-right: 5px;
+ background-repeat: no-repeat;
+ width: 100px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-left: 12px;
+ margin-right: 5px;
+ font-size: 14px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-I3 input[type="text"] {
+ background-image: url(https://i.imgur.com/GUI0tbP.png);
+ background-size: 98px 40px;
+ margin-left: 12px;
+ margin-right: 5px;
+ margin-bottom: 1px;
+ background-repeat: no-repeat;
+ width: 100px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-left: 12px;
+ margin-right: 5px;
+ font-size: 14px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-info-1 input[type="text"] {
+ border-style: #2F4F4F;
+ background-color: #DCDCDC;
+ width: 100px;
+ height: 30px;
+ margin-left: 12px;
+ margin-right: 4px;
+ margin-top: 3px;
+ margin-bottom: -0px;
+ border-top: 2px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 2px solid #333333;
+ border-left: 2px solid #333333;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-info-2 input[type="text"] {
+ border-style: #2F4F4F;
+ background-color: #FAEBD7;
+ width: 100px;
+ height: 30px;
+ margin-left: 12px;
+ margin-right: 4px;
+ margin-top: 3px;
+ font-size: 20px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-info-3 input[type="text"] {
+ border-style: #2F4F4F;
+ background-color: #DCDCDC;
+ width: 100px;
+ height: 30px;
+ margin-left: 12px;
+ margin-right: 5px;
+ margin-top: 3px;
+ border-top: 2px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 2px solid #333333;
+ border-left: 2px solid #333333;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-sub {
+ border-style: black;
+ background-color: ;
+ padding-left: 1px;
+ border: 1px solid #333333;
+ border-top: 0px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 0px solid #333333;
+ border-left: 0px solid #333333;
+ margin-top: 6px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-sub2 {
+ margin-top: 6px;
+ border-style: ;
+ border: 0px;
+ background-color: #C0C0C0;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-sub3 {
+ margin-top: 1px;
+ border-style: none;
+ background-color: #C0C0C0;
+ padding-left: 1px;
+ border: none;
+ border-top: 0px solid #333333;
+ border-bottom: 0px solid #333333;
+ border-right: 0px solid #333333;
+ border-left: 0px solid #333333;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+/**titulo dos atributos e modificadores**/
+.sheet-img-dragon {
+ position: relative;
+ left: 335px;
+ bottom: -25px;
+ width: 41px;
+ height: 29px;
+}
+.sheet-atributo-name h2 {
+ font-size: 20px;
+ text-align: center;
+ border-bottom: solid 2px black;
+ line-height: 24px;
+ background-color: transparent;
+}
+.sheet-linha-vida {
+ background-image: url(https://i.imgur.com/PLEaV2V.png);
+ background-size: 28px 28px;
+ background-repeat: no-repeat;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 5px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-mana {
+ background-image: url(https://i.imgur.com/tX4uoof.png);
+ background-size: 29px 29px;
+ background-repeat: no-repeat;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 5px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-fe {
+ background-image: url(https://i.imgur.com/Kkl5ifT.png);
+ background-size: 28px 28px;
+ background-repeat: no-repeat;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 5px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-ip {
+ background-image: url(https://i.imgur.com/VjcBBCt.png);
+ background-size: 28px 28px;
+ background-repeat: no-repeat;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 5px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-rm {
+ background-image: url(https://i.imgur.com/iolQs0A.png);
+ background-size: 28px 28px;
+ background-repeat: no-repeat;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 5px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-move{
+ background-image: url(https://i.imgur.com/8kGNCPs.png);
+ background-size: 29px 25px;
+ background-repeat: no-repeat;
+ width: 32px;
+ height: 42px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 5px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-decisivo {
+ background-image: url(https://i.imgur.com/sUBkbOk.png);
+ background-size: 27px 25px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 8px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-critico {
+ background-image: url(https://i.imgur.com/FxgTzPb.png);
+ background-size: 27px 27px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 8px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+.sheet-linha-penalidade {
+ background-image: url(https://i.imgur.com/5hhA50Y.png);
+ background-size: 25px 26px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 5px;
+ margin-Bottom: 8px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+}
+
+.sheet-modificador-global {
+ margin-top: -15px;
+ margin-bottom:10px;
+}
+/*linha de divisão das perícias*/
+.sheet-linha-de-divisao-2 {
+ margin-top:10px;
+ margin-bottom: 10px;
+ background-image: url(https://i.imgur.com/NTZLN33.png);
+ background-size: 800px 65px;
+ background-repeat: no-repeat;
+ width: 800px;
+ height: 60px;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-de-divisao-2 h3 {
+ padding-top: 35px;
+}
+
+/*css linhas pericias*/
+.sheet-pericias {
+ margin-top: 3px;
+}
+.sheet-linha-inicial-pericias {
+ border-style: none;
+ background-color: transparent;
+ font-size: 13px;
+ font-weight: bold;
+ color: black font-weight: bold;
+ text-align: left;
+ position: center;
+ text-align: center;
+ width: 80px;
+ height: 30px;
+ margin-top: 3px;
+}
+.sheet-linha-inicial-pericias2 {
+ border-style: none;
+ background-color: transparent;
+ font-size: 13px;
+ font-weight: bold;
+ color: black font-weight: bold;
+ text-align: left;
+ position: left;
+ text-align: left;
+ width: 80px;
+ height: 30px;
+ margin-top: 3px;
+}
+.sheet-linha2 {
+ border-style: none;
+ background-color: transparent;
+ padding-left: 1px;
+ margin-top: 1px;
+ font-size: 13px;
+ font-weight: bold;
+ color: black text-align: center;
+ width: 47px;
+ height: 30px;
+ margin-top: 5px;
+}
+.sheet-linha3 {
+ margin-top: 1px;
+ margin-bottom: 1px;
+ border-style: black;
+ background-color: ;
+ padding-left: 1px;
+ border: black;
+ border-top: 1px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 1px solid #333333;
+ border-left: 1px solid #333333;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha4 {
+ margin-top: 1px;
+ margin-bottom: 1px;
+ border-style: black;
+ background-color: ;
+ padding-left: 1px;
+ border: black;
+ border-top: 1px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 1px solid #333333;
+ border-left: 1px solid #333333;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: left;
+ position: relative;
+}
+.sheet-linha-secundaria {
+ margin-top: 1px;
+ margin-bottom: 2px;
+ border-style: black;
+ background-color: transparent;
+ padding-left: 1px;
+ border: black;
+ border-top: 0px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 0px solid #333333;
+ border-left: 0px solid #333333;
+ font-size: 12px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-secundaria2 {
+ margin-top: 1px;
+ margin-bottom: 2px;
+ border-style: black;
+ background-color: transparent;
+ padding-left: 1px;
+ border: black;
+ border-top: 0px solid #333333;
+ border-bottom: 0px solid #333333;
+ border-right: 0px solid #333333;
+ border-left: 0px solid #333333;
+ font-size: 12px;
+ font-weight: bold;
+ color: #A52A2A;
+ text-align: center;
+ position: relative;
+}
+
+.sheet-linha_N {
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 0px;
+ margin-Bottom: 0px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+ }
+
+ .sheet-linha_D {
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 0px;
+ margin-Bottom: 0px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+ }
+
+ .sheet-linha_M {
+ width: 30px;
+ height: 40px;
+ border-style: none;
+ background-color: transparent;
+ margin-top: 0px;
+ margin-Bottom: 0px;
+ font-weight: bold;
+ text-align: center;
+ color: black
+ }
+
+/*css dos dados de pericias*/
+.sheet-linha-dado2 {
+ border-style: none;
+ background-color: transparent;
+ text-align: center;
+ background-repeat: no-repeat;
+ margin-top: 1px;
+ margin-left: 6px;
+ width: 21px;
+ height: 2px;
+ border-style: black;
+ background-color: ;
+ padding-left: 1px;
+ margin-top: 5px;
+ font-weight: bold;
+ color: black text-align: center;
+}
+button[type="roll"].sheet-dado4:before {
+ content: ' ';
+}
+button[type="roll"].sheet-dado4:hover {
+ background-position: 0;
+ box-shadow: 0px 0px 20px #00FF0B;
+ background-color: #9CF7A0;
+}
+button[type="roll"].sheet-dado4 {
+ background-image: url(https://i.imgur.com/7qkxCK7.png);
+ background-size: 25px 26px;
+ background-repeat: no-repeat;
+ width: 19px;
+ height: 26px;
+ border-style: none;
+ background-color: transparent;
+}
+button[type="roll"].sheet-dado5:before {
+ content: ' ';
+}
+button[type="roll"].sheet-dado5:hover {
+ background-position: 0;
+ box-shadow: 0px 0px 20px #FCE300;
+ background-color: #F7EE9C;
+}
+button[type="roll"].sheet-dado5 {
+ background-image: url(https://i.imgur.com/7qkxCK7.png);
+ background-size: 25px 26px;
+ background-repeat: no-repeat;
+ width: 19px;
+ height: 26px;
+ border-style: none;
+ background-color: transparent;
+}
+button[type="roll"].sheet-dado6:before {
+ content: ' ';
+}
+button[type="roll"].sheet-dado6:hover {
+ background-position: 0;
+ box-shadow: 0px 0px 20px #FF0003;
+ background-color: #F9999A;
+}
+button[type="roll"].sheet-dado6 {
+ background-image: url(https://i.imgur.com/7qkxCK7.png);
+ background-size: 25px 26px;
+ background-repeat: no-repeat;
+ width: 19px;
+ height: 26px;
+ border-style: none;
+ background-color: transparent;
+}
+.sheet-linha_dado3 {
+ background-image: url();
+ background-size: 21px 26px;
+ text-align: center;
+ background-repeat: no-repeat;
+ margin-top: 1px;
+ margin-left: 9px;
+ width: 21px;
+ height: 2px;
+ border-style: none;
+ background-color: transparent;
+ padding-left: 1px;
+ margin-top: 0px;
+ font-size: 13px;
+ font-weight: bold;
+ color: black text-align: center;
+}
+/*display das pericias de combate e pericias gerais*/
+.sheet-columns {
+ display: flex;
+ justify-content: space-between;
+ width: 400px;
+}
+.sheet-columns > * {
+ flex: 1;
+}
+input.sheet-toggle-show:not(:checked) ~ div.sheet-body, input.sheet-toggle-hide:checked ~ div.sheet-body {
+ display: none;
+}
+/*linha de divisão dos aprimoramentos e manobras*/
+.sheet-linha-de-divisao-3 {
+ margin-top: 15px;
+ margin-bottom: 1px;
+ background-image: url(https://i.imgur.com/NTZLN33.png);
+ background-size: 800px 65px;
+ background-repeat: no-repeat;
+ width: 800px;
+ height: 65px;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-de-divisao-3 h3 {
+ padding-top: 35px;
+}
+/*display dos aprimoramentos e manobras*/
+.sheet-aprimoramentos-e-manobras {
+ margin-top: 1px;
+ margin-bottom: 1px;
+ border-style: black;
+ background-color: #F8F8FF;
+ padding-left: 1px;
+ border: black;
+ border-top: 1px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 1px solid #333333;
+ border-left: 1px solid #333333;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: left;
+ position: relative;
+}
+.sheet-linha-inicial-aprimoramentos-manobras {
+ border-style: none;
+ background-color: transparent;
+ font-size: 13px;
+ font-weight: bold;
+ color: black text-align: center;
+ font-weight: bold;
+ margin-left: ;
+ position: relative;
+ width: 80px;
+ height: 30px;
+ margin-top: 2px;
+}
+/* CSS checkbox sub-atributos */
+input[type="checkbox"].sheet-block-switch {
+ appearance: none;
+ border: none;
+ outline: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch {
+ opacity: transparent;
+ height: 30px;
+ width: 30px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch {
+ background-image: url(https://i.imgur.com/bs0x98x.png);
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch:checked {
+ background-image: url(https://i.imgur.com/iJhgLtR.png);
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+/* CSS checkbox pericias*/
+input[type="checkbox"].sheet-toggle-show {
+ appearance: none;
+ border: none;
+ outline: none;
+}
+input[type="checkbox"].sheet-toggle-show {
+ opacity: transparent;
+ height: 29px;
+ width: 30px;
+ margin: top;
+ 25px;
+}
+input[type="checkbox"].sheet-toggle-show {
+ background-image: url("https://i.imgur.com/vFxlBEm.png");
+ background-size: 29px 29px;
+ background-position: center;
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+}
+/*linha de fechamento das paginas*/
+.sheet-linha-de-divisao-4 {
+ margin-top: 50px;
+ margin-bottom: 10px;
+ background-image: url(https://i.imgur.com/Eh99AH2.png);
+ background-size: 798px 64px;
+ background-repeat: no-repeat;
+ width: 800px;
+ height: 100px;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-de-divisao-4 h3 {
+ padding-top: 35px;
+}
+/*CSS Botões troca pagina 1*/
+.sheet-character {
+ margin-top: 0px;
+}
+button[type="action"].sheet-button-personagem:before {
+ content: ' ';
+}
+button[type="action"].sheet-button-personagem:hover {
+ background-image: url(https://i.imgur.com/BeJ5nXO.png);
+
+}
+button[type="action"].sheet-button-personagem:hover h4 {
+ text-shadow: 0 0 10px #FF9601, 0 0 20px #FF9601, 0 0 40px #FF9601;
+ color: #fff
+}
+button[type="action"].sheet-button-personagem {
+ background-image: url(https://i.imgur.com/7O2DIdH.png);
+ background-size: 127px 30px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 115px;
+ height: 30px;
+ border-style: none;
+ background-color: transparent;
+}
+/*CSS Botões troca pagina 2*/
+.sheet-container-botao{
+ margin-top:60px;
+ margin-bottom:-50px;
+}
+button[type="action"].sheet-button-magia:before {
+ content: ' ';
+}
+button[type="action"].sheet-button-magia:hover {
+ background-image: url(https://i.imgur.com/IJekFec.png);
+}
+button[type="action"].sheet-button-magia:hover h4 {
+ text-shadow: 0 0 10px #FF9601, 0 0 20px #FF9601, 0 0 40px #FF9601;
+ color: #fff
+}
+button[type="action"].sheet-button-magia {
+ background-image: url(https://i.imgur.com/VuXzAma.png);
+ background-size: 127px 30px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 115px;
+ height: 30px;
+ border-style: none;
+ background-color: transparent;
+}
+.sheet-button-personagem h4 {
+ color: #FFFFFF;
+ position: center;
+ padding-left: 22px;
+ font-size: 13px;
+}
+.sheet-button-magia h4 {
+ color: #FFFFFF;
+ position: center;
+ padding-left: 20px;
+ font-size: 13px;
+}
+/*CSS Botões troca pagina 3*/
+.sheet-button-equipamento h4 {
+ color: #FFFFFF;
+ position: center;
+ padding-left: 23px;
+ font-size: 13px;
+}
+button[type="action"].sheet-button-equipamento:before {
+ content: ' ';
+}
+button[type="action"].sheet-button-equipamento:hover {
+ background-image: url(https://i.imgur.com/dnazVgl.png);
+}
+button[type="action"].sheet-button-equipamento:hover h4 {
+ text-shadow: 0 0 10px #FF9601, 0 0 20px #FF9601, 0 0 40px #FF9601;
+ color: #fff
+}
+button[type="action"].sheet-button-equipamento {
+ background-image: url(https://i.imgur.com/QnOwFo9.png);
+ background-size: 127px 30px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 115px;
+ height: 30px;
+ border-style: none;
+ background-color: transparent;
+}
+/*Botões do cabeçalho*/
+.sheet-character, .sheet-config, .sheet-journal {
+ display: none;
+}
+.sheet-tabstoggle[value="character"] ~ div.sheet-character, .sheet-tabstoggle[value="configuration"] ~ div.sheet-config, .sheet-tabstoggle[value="journal"] ~ div.sheet-journal {
+ display: block;
+}
+/* CSS Pagina 2 */
+.sheet-texto-magias textarea {
+ height: 30%;
+ width: 98%;
+ border: 2px solid black;
+ font-weight: bold;
+}
+.sheet-body {
+ background-color: #DCDCDC;
+ padding: 2px;
+}
+.sheet-linha-focus input[type="text"] {
+ background-image: url(https://i.imgur.com/IS0rG1Q.png);
+ background-size: 100px 45px;
+ margin-Top: 0px;
+ margin-left: 30px;
+ margin-right: 20px;
+ background-repeat: no-repeat;
+ width: 100px;
+ height: 45px;
+ border-style: none;
+ background-color: transparent;
+ margin-left: 30px;
+ margin-right: 20px;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-focus2 input[type="text"] {
+ border-style: #2F4F4F;
+ background-color: #DCDCDC;
+ width: 100px;
+ height: 30px;
+ margin-left: 30px;
+ margin-right: 20px;
+ margin-top: 5px;
+ margin-bottom: 0px;
+ border-top: 2px solid #333333;
+ border-bottom: 2px solid #333333;
+ border-right: 2px solid #333333;
+ border-left: 2px solid #333333;
+ font-size: 13px;
+ font-weight: bold;
+ text-align: center;
+ position: relative;
+}
+/* CSS Pagina 3*/
+.sheet-linha-equip {
+ border-style: black;
+ background-color: transparent;
+ padding-left: 1px;
+ border: none;
+ border-bottom: 2px solid #333333;
+ margin-top: 5px;
+ font-weight: bold;
+ text-align: center;
+}
+.sheet-texto-equip textarea {
+ width: 225px;
+ height: 100px;
+ border: 2px solid black;
+ font-weight: bold;
+ font-size: 13px;
+}
+/*CSS troca de personagem*/
+.sheet-block-feminino, .sheet-block-switch-personagem:checked ~ .sheet-block-masculino {
+ display: block;
+}
+.sheet-block-masculino, .sheet-block-switch-personagem:checked ~ .sheet-block-feminino {
+ display: none;
+}
+input[type="checkbox"].sheet-block-switch-personagem {
+ appearance: none;
+ border: none;
+ outline: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch-personagem {
+ opacity: transparent;
+ height: 30px;
+ width: 30px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch-personagem {
+ background-image: url(https://i.imgur.com/mKNfjiC.png);
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch-personagem:checked {
+ background-image: url(https://i.imgur.com/gpOwBpW.png);
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+.sheet-block-feminino {
+ background-size: 200px 65px;
+ margin-bottom: 100px;
+ margin-left: 30px;
+ margin-right: 20px;
+ background-repeat: no-repeat;
+ width: 200px;
+ height: 65px;
+}
+.sheet-block-masculino {
+ background-size: 200px 65px;
+ margin-bottom: 100px;
+ margin-left: 30px;
+ margin-right: 20px;
+ background-repeat: no-repeat;
+ width: 200px;
+ height: 65px;
+}
+/*CSS mochila e anotacoes*/
+.sheet-linha-de-divisao-5 {
+ background-image: url(https://i.imgur.com/NTZLN33.png);
+ background-size: 800px 65px;
+ background-repeat: no-repeat;
+ margin-top: 50px;
+ width: 800px;
+ height: 65px;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-de-divisao-5 h3 {
+ padding-top: 35px;
+ text-align: center;
+ margin-bottom: 10px;
+}
+.sheet-linha-de-divisao-6 {
+ background-image: url(https://i.imgur.com/NTZLN33.png);
+ background-size: 800px 65px;
+ background-repeat: no-repeat;
+ margin-top: 55px;
+ margin-bottom: 5px;
+ width: 800px;
+ height: 65px;
+ text-align: center;
+ position: relative;
+}
+.sheet-linha-de-divisao-6 h3 {
+ padding-top: 35px;
+ text-align: center;
+ margin-bottom: 10px;
+}
+/*CSS anotacoes*/
+.sheet-texto-notas-1 {
+ background-image: url(https://i.imgur.com/i3vy64w.png);
+ background-size: 800px 380px;
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 800px;
+ height: 385px;
+}
+.sheet-texto-notas-1 h3 {
+ text-align: center;
+ position: relative;
+ padding-top: 50px;
+}
+.sheet-texto-notas-1 textarea {
+ width: 662px;
+ height: 240px;
+ text-align: left;
+ margin-left: 65px;
+ position: relative;
+ resize: vertical;
+ overflow-y: auto;
+ min-height: 5em;
+ font-weight: bold;
+ font-size: 16px;
+ background-color: transparent;
+ border: none;
+}
+/*CSS mochila*/
+.sheet-mochila {
+ background-image: url(https://i.imgur.com/ZJa4qi1.png);
+ background-size: 350px 410px;
+ background-repeat: no-repeat;
+ background-position: left;
+ padding-left: 30px;
+ padding-top: 70px;
+ width: 350px;
+ height: 410px;
+}
+.sheet-mochila textarea {
+ width: 275px;
+ height: 330px;
+ text-align: left;
+ position: relative;
+ resize: vertical;
+ overflow-y: auto;
+ font-weight: bold;
+ font-size: 16px;
+ background-color: transparent;
+ border: none;
+}
+.sheet-imgbag {
+ margin-left: 10px;
+}
+
+.sheet-mochila-texto{
+margin-left:12px;
+}
+.sheet-moedas {
+ text-align: center;
+ margin-top: 5px;
+ margin-bottom: 2px;
+ position: relative;
+ border-bottom: solid 2px black;
+}
+.sheet-tabela-moedas table {
+ text-align: center;
+ margin-left: 50px;
+}
+.sheet-bronze {
+ background-image: url(https://i.imgur.com/yk2LSG3.png);
+ background-size: 20px 22px;
+ background-repeat: no-repeat;
+ text-align: center;
+ width: 20px;
+ height: 22px;
+}
+.sheet-prata {
+ background-image: url(https://i.imgur.com/rc5flre.png);
+ background-size: 20px 20px;
+ background-repeat: no-repeat;
+ text-align: center;
+}
+.sheet-ouro {
+ background-image: url(https://i.imgur.com/2kn1Qt5.png);
+ background-size: 20px 20px;
+ background-repeat: no-repeat;
+ text-align: center;
+}
+.sheet-tabela-moedas td {
+ text-align: center;
+ border: 3px double;
+}
+.sheet-block-moeda, .sheet-block-switch-mochila:checked ~ .sheet-block-livro {
+ display: block;
+}
+.sheet-block-livro, .sheet-block-switch-mochila:checked ~ .sheet-block-moeda {
+ display: none;
+}
+.sheet-2coluna {
+ background-image: url(https://i.imgur.com/c12YfkI.png);
+ background-size: 430px 380px;
+ background-repeat: no-repeat;
+ margin-left: -45px;
+ width: 436px;
+ height: 385px;
+ margin-top: -10px;
+}
+.sheet-texto-pag1 {
+ background-repeat: no-repeat;
+ background-position: left;
+ margin-left: 35px;
+ margin-top: 20px;
+ width: 150px;
+ height: 300px;
+ background-color: transparent;
+ border: none;
+}
+.sheet-texto-pag1 textarea {
+ text-align: left;
+ position: relative;
+ resize: vertical;
+ overflow-y: auto;
+ font-weight: bold;
+ font-size: 16px;
+}
+.sheet-texto-pag2 {
+ background-repeat: no-repeat;
+ background-position: left;
+ margin-left: 20px;
+ margin-top: 20px;
+ width: 140px;
+ height: 300px;
+ background-color: transparent;
+ border: none;
+}
+.sheet-texto-pag2 textarea {
+ text-align: left;
+ position: relative;
+ resize: vertical;
+ overflow-y: auto;
+ font-weight: bold;
+ font-size: 16px;
+
+}
+.sheet-treinamento h3 {
+ text-align: center;
+ margin-top: -10px;
+ margin-bottom: 10px;
+ margin-left: -40px;
+ position: relative;
+}
+input[type="checkbox"].sheet-block-switch-mochila {
+ appearance: none;
+ border: none;
+ outline: none;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch-mochila {
+ opacity: transparent;
+ height: 30px;
+ width: 30px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch-mochila {
+ background-image: url(https://i.imgur.com/PXN6O0U.png);
+ background-size: 38px 40px;
+ height: 50px;
+ width: 50px;
+ background-repeat: no-repeat;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+input[type="checkbox"].sheet-block-switch-mochila:checked {
+ background-image: url(https://i.imgur.com/tltOCr8.png);
+ background-size: 38px 40px;
+ height: 50px;
+ width: 50px;
+ background-repeat: no-repeat;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+/*--equipamento--*/
+input.sheet-toggle-show-arma:not(:checked) ~ div.sheet-body, input.sheet-toggle-hide:checked ~ div.sheet-body {
+ display: none;
+}
+/*CSS linha de armas*/
+input[type="checkbox"].sheet-toggle-show-arma {
+ appearance: none;
+ border: none;
+ outline: none;
+}
+input[type="checkbox"].sheet-toggle-show-arma {
+ opacity: transparent;
+ height: 29px;
+ width: 30px;
+ margin: top;
+ 25px;
+}
+input[type="checkbox"].sheet-toggle-show-arma {
+ background-image: url("https://i.imgur.com/MTW75Uh.png");
+ background-size: 29px 29px;
+ background-position: center;
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+}
+/*CSS linha de municao*/
+input.sheet-toggle-show-municao:not(:checked) ~ div.sheet-body, input.sheet-toggle-hide:checked ~ div.sheet-body {
+ display: none;
+}
+input[type="checkbox"].sheet-toggle-show-municao {
+ appearance: none;
+ border: none;
+ outline: none;
+}
+input[type="checkbox"].sheet-toggle-show-municao {
+ opacity: transparent;
+ height: 29px;
+ width: 30px;
+ margin: top;
+ 25px;
+}
+input[type="checkbox"].sheet-toggle-show-municao {
+ background-image: url("https://i.imgur.com/zjjY2M3.png");
+ background-size: 29px 29px;
+ background-position: center;
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+}
+/*CSS linha de armadura*/
+input.sheet-toggle-show-armadura:not(:checked) ~ div.sheet-body, input.sheet-toggle-hide:checked ~ div.sheet-body {
+ display: none;
+}
+input[type="checkbox"].sheet-toggle-show-armadura {
+ appearance: none;
+ border: none;
+ outline: none;
+}
+input[type="checkbox"].sheet-toggle-show-armadura {
+ opacity: transparent;
+ height: 29px;
+ width: 30px;
+ margin: top;
+ 25px;
+}
+input[type="checkbox"].sheet-toggle-show-armadura {
+ background-image: url("https://i.imgur.com/qj65zXo.png");
+ background-size: 29px 29px;
+ background-position: center;
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+}
+/*CSS linha de item*/
+input.sheet-toggle-show-item:not(:checked) ~ div.sheet-body, input.sheet-toggle-hide:checked ~ div.sheet-body {
+ display: none;
+}
+input[type="checkbox"].sheet-toggle-show-item {
+ appearance: none;
+ border: none;
+ outline: none;
+}
+input[type="checkbox"].sheet-toggle-show-item {
+ opacity: transparent;
+ height: 29px;
+ width: 30px;
+ margin: top;
+ 25px;
+}
+input[type="checkbox"].sheet-toggle-show-item {
+ background-image: url("https://i.imgur.com/qI3aGTm.png");
+ background-size: 29px 29px;
+ background-position: center;
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+}
+
+/*CSS linha de reliquias*/
+input.sheet-toggle-show-rel:not(:checked) ~ div.sheet-body, input.sheet-toggle-hide:checked ~ div.sheet-body {
+ display: none;
+}
+input[type="checkbox"].sheet-toggle-show-rel {
+ appearance: none;
+ border: none;
+ outline: none;
+}
+input[type="checkbox"].sheet-toggle-show-rel {
+ opacity: transparent;
+ height: 20px;
+ width: 28px;
+ margin: top;
+ 25px;
+}
+input[type="checkbox"].sheet-toggle-show-rel {
+ background-image: url("https://i.imgur.com/lA8jXI3.png");
+ background-size: 29px 20px;
+ background-position: center;
+ height: 29px;
+ width: 30px;
+ background-repeat: no-repeat;
+}
+/*CSS linha de pocoes*/
+input.sheet-toggle-show-pocao:not(:checked) ~ div.sheet-body, input.sheet-toggle-hide:checked ~ div.sheet-body {
+ display: none;
+}
+input[type="checkbox"].sheet-toggle-show-pocao {
+ appearance: none;
+ border: none;
+ outline: none;
+}
+input[type="checkbox"].sheet-toggle-show-pocao {
+ opacity: transparent;
+ height: 29px;
+ width: 30px;
+ margin: top;
+ 25px;
+}
+input[type="checkbox"].sheet-toggle-show-pocao {
+ background-image: url("https://i.imgur.com/ddt3mgD.png");
+ background-size: 29px 29px;
+ background-position: center;
+ height: 30px;
+ width: 30px;
+ background-repeat: no-repeat;
+}
+
+
+/* FICHA DESENVOLVIDA POR BLACK & VERYDYCA
+-.----------------------------------------------------------------------------.
+
+-..................................-----::-:+:-..---...........................
+
+-..............................-**+**+*+:++--::::::*+..........................
+
+-.......................+*:..--...-+#@##@#*+:::::::::+++-......................
+
+-.........................-*W@#@==@###@@@@@@@*+#*:--::::::+-...................
+
+-..................---.-==+-:-:+:-...--*@WWW@WWW@*::::::*#=+:-.................
+
+-.............--*+-:+-.-..-:*+::=**::::-----::++=#=:::===WWW@@=-...............
+
+-...........+++:-........:+:+::-::-+=:......-::-.-++-:#W@=:+@W@#+..............
+
+-............-+++-.-...-+==++*+-:-::-+*:----------:#=*+*=-...-+:-:*-...........
+
+-...........:+++--*#+:**::-.-*:-:::::::-=#=*:...-===#=+*::*-....-+::...........
+
+-........-*#*----==*---+=:-.++::-::::-:#==:-:+-.==*:-==+*--:+--...-==-.........
+
+-.......*@#++:-+#=*:-----:*-::::-::--:=#:-----:*#**:-#=+=+.-=#=+:*-*@=:........
+
+-......:@#******=+-----:--:=#+:::++::--+#=+----+#***+#*=::*#=*++#@@#@@#:.......
+
+-....-*#*=#===##:----:==*:*#++*===*-+##****----+#**#===+---:-*::#@@@++@#.......
+
+-...:=*-:*@@*@=:+==-:#=*+*#=***==+-:**==**++---*#**==:-:+*==**+--*#@@:=W+......
+
+-.-*=+-+@W@###===*::@##=*+*=**+:-::--:==**:::-:#=**+----+*=#**+---:#@W@@=:.....
+
+--==*.-@@=*****=+::---+#*+*:--+*:::--:==+*++:=##=**:------*=**+---:##*+*@*-....
+
+-==*--=@=####=+::::-:-:#**+*-===:-:::+#=+*++**:==**+--++--*=****:*#*@@=*+*=+...
+
+*#**-+###=#:---:==::-+=##*++==*---:-:+==++==+:+==*++*==+--==**--:==+==@@**+....
+
+==*+===#::==-:===:--+#=:==***+::++::++##**==-::-=#***=+--:#=++*=+*=*+=@@*++....
+
++#**++*=***====*---+#*:-:=#*:*++..-..-:*=:.--:++:=#=+-----*#***#::==*+=#*+*:...
+
+-+#=********=*+---+#=***:.......-....----+++++-..-++-------:=+-:+.+@===*#=+***-
+
+-..-+=###=*:-----:==*+-........---......-+::++--...:*:------++--:+:-::--+##=+..
+
+-....+**+:::::---*=#+.---...-==:...-----..::.........-::----+-:+:---::-:+......
+
+-....-+:+::++-:-+#=*....-:--#**:..........:+*::-....-.::----:+:+:+::::-+-......
+
+-.....-++::+:-:*=#**---...--==*-.............-+*:+-.-::+-----:+::+:--::+.......
+
+-.......++:--+*:+#=++-:...-==*:-.--.............-..:+:::++++--+:-:*+:++-.......
+
+-........-+:-:+-.*@*+*+::*#**-......-:-.....----.....-----.:*+:-:::::++........
+
+-..........:+:.-..-=#****==+............---..........--..--:+*=+-:+=+..........
+
+-..............++-.--=#+::-.:-.........++..........-----::+-..:=-++-...........
+
+-.............-*+--.+#@@=+:::---..--.--:--..-----------::-...:=*:-.............
+
+-...............-+-.-#@@@@@#+:---:++*++::-..---.-.-:+:---...-:+-...............
+
+-..................:**#@==#@W@*:::----+*++::::++=W@*--.-*:-:-..................
+
+-....................-:+---:+=##-------:+-:=:......-:+=+-......................
+
+-.......................-:+:--------::--:**=@#*:-..............................
+
+-..........................-++++*+::++::::::::--...............................
+
+-...............................--.............................................
+
+-.----------------------------------------------------------------------------.
+--*/
diff --git a/Daemon Exilia/Exilia.html b/Daemon Exilia/Exilia.html
new file mode 100644
index 0000000000..c16e8bbef0
--- /dev/null
+++ b/Daemon Exilia/Exilia.html
@@ -0,0 +1,1165 @@
+
+
+
+
+
+
+
+
+
+
+ Personagem
+
+
+ Magia
+
+
+ Equipamentos
+
+
+
+
+
+
+
Personagem
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Perícias de Combate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Perícias Gerais
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Aprimoramentos e Manobras de Combate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Habilidades de Raça
+
+
+
+
+
+
+
+
+
+
+
Habilidades de Classe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Equipamentos
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Mochila
+
+
+
+
+
+
+
+
+
+
Estudo & Treinamento
+
+
+
+
+
+
+
+
+
Anotações
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Daemon Exilia/Exilia.png b/Daemon Exilia/Exilia.png
new file mode 100644
index 0000000000..923037655b
Binary files /dev/null and b/Daemon Exilia/Exilia.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-2coluna.png b/Daemon Exilia/Imagens/.sheet-2coluna.png
new file mode 100644
index 0000000000..fd17289187
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-2coluna.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-I1.sheet-I3.sheet-linha-focus.png b/Daemon Exilia/Imagens/.sheet-I1.sheet-I3.sheet-linha-focus.png
new file mode 100644
index 0000000000..8feedd33b4
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-I1.sheet-I3.sheet-linha-focus.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-block-switch-mochila.png b/Daemon Exilia/Imagens/.sheet-block-switch-mochila.png
new file mode 100644
index 0000000000..41d5ae43ae
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-block-switch-mochila.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-block-switch-mochilachecked.png b/Daemon Exilia/Imagens/.sheet-block-switch-mochilachecked.png
new file mode 100644
index 0000000000..484ad62137
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-block-switch-mochilachecked.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-block-switch-personagem.png b/Daemon Exilia/Imagens/.sheet-block-switch-personagem.png
new file mode 100644
index 0000000000..90900a8078
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-block-switch-personagem.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-block-switch-personagemchecked.png b/Daemon Exilia/Imagens/.sheet-block-switch-personagemchecked.png
new file mode 100644
index 0000000000..a6672e0ccf
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-block-switch-personagemchecked.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-block-switch.png b/Daemon Exilia/Imagens/.sheet-block-switch.png
new file mode 100644
index 0000000000..cca38b2a4f
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-block-switch.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-block-switchchecked.png b/Daemon Exilia/Imagens/.sheet-block-switchchecked.png
new file mode 100644
index 0000000000..b139f94dc9
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-block-switchchecked.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-bronze.png b/Daemon Exilia/Imagens/.sheet-bronze.png
new file mode 100644
index 0000000000..e1aa434937
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-bronze.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-button-equipamento.png b/Daemon Exilia/Imagens/.sheet-button-equipamento.png
new file mode 100644
index 0000000000..c71613aa98
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-button-equipamento.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-button-equipamentohover.png b/Daemon Exilia/Imagens/.sheet-button-equipamentohover.png
new file mode 100644
index 0000000000..1e86effa52
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-button-equipamentohover.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-button-magia.png b/Daemon Exilia/Imagens/.sheet-button-magia.png
new file mode 100644
index 0000000000..dbfdd225f5
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-button-magia.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-button-magiahover.png b/Daemon Exilia/Imagens/.sheet-button-magiahover.png
new file mode 100644
index 0000000000..044774a4bb
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-button-magiahover.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-button-personagem.png b/Daemon Exilia/Imagens/.sheet-button-personagem.png
new file mode 100644
index 0000000000..7043b2fbb6
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-button-personagem.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-button-personagemhover.png b/Daemon Exilia/Imagens/.sheet-button-personagemhover.png
new file mode 100644
index 0000000000..c29dc3d905
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-button-personagemhover.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-critico.png b/Daemon Exilia/Imagens/.sheet-linha-critico.png
new file mode 100644
index 0000000000..f754299b12
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-critico.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-de-divisao-4.png b/Daemon Exilia/Imagens/.sheet-linha-de-divisao-4.png
new file mode 100644
index 0000000000..d43af801f0
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-de-divisao-4.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-decisivo.png b/Daemon Exilia/Imagens/.sheet-linha-decisivo.png
new file mode 100644
index 0000000000..23ab99e8a7
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-decisivo.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-fe.png b/Daemon Exilia/Imagens/.sheet-linha-fe.png
new file mode 100644
index 0000000000..d520d3d873
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-fe.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-ip.png b/Daemon Exilia/Imagens/.sheet-linha-ip.png
new file mode 100644
index 0000000000..5865e7fb48
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-ip.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-mana.png b/Daemon Exilia/Imagens/.sheet-linha-mana.png
new file mode 100644
index 0000000000..86ac797045
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-mana.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-move.png b/Daemon Exilia/Imagens/.sheet-linha-move.png
new file mode 100644
index 0000000000..36921421fd
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-move.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-penalidade.png b/Daemon Exilia/Imagens/.sheet-linha-penalidade.png
new file mode 100644
index 0000000000..7d8fe904c9
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-penalidade.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-rm.png b/Daemon Exilia/Imagens/.sheet-linha-rm.png
new file mode 100644
index 0000000000..aee238b10e
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-rm.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-linha-vida.png b/Daemon Exilia/Imagens/.sheet-linha-vida.png
new file mode 100644
index 0000000000..577ab1bf0e
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-linha-vida.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-mochila.png b/Daemon Exilia/Imagens/.sheet-mochila.png
new file mode 100644
index 0000000000..518b4dbb72
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-mochila.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-ouro.png b/Daemon Exilia/Imagens/.sheet-ouro.png
new file mode 100644
index 0000000000..5ed48e98e7
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-ouro.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-prata.png b/Daemon Exilia/Imagens/.sheet-prata.png
new file mode 100644
index 0000000000..04e1522e2b
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-prata.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-texto-notas-1.png b/Daemon Exilia/Imagens/.sheet-texto-notas-1.png
new file mode 100644
index 0000000000..c9fce66627
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-texto-notas-1.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-toggle-show-arma.png b/Daemon Exilia/Imagens/.sheet-toggle-show-arma.png
new file mode 100644
index 0000000000..8463b4cfe4
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-toggle-show-arma.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-toggle-show-armadura.png b/Daemon Exilia/Imagens/.sheet-toggle-show-armadura.png
new file mode 100644
index 0000000000..5865e7fb48
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-toggle-show-armadura.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-toggle-show-item.png b/Daemon Exilia/Imagens/.sheet-toggle-show-item.png
new file mode 100644
index 0000000000..a09d783ca4
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-toggle-show-item.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-toggle-show-municao.png b/Daemon Exilia/Imagens/.sheet-toggle-show-municao.png
new file mode 100644
index 0000000000..dd1ba53ad5
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-toggle-show-municao.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-toggle-show-pocao.png b/Daemon Exilia/Imagens/.sheet-toggle-show-pocao.png
new file mode 100644
index 0000000000..c2882d0c55
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-toggle-show-pocao.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-toggle-show-rel.png b/Daemon Exilia/Imagens/.sheet-toggle-show-rel.png
new file mode 100644
index 0000000000..ac3d77ffc9
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-toggle-show-rel.png differ
diff --git a/Daemon Exilia/Imagens/.sheet-toggle-show.png b/Daemon Exilia/Imagens/.sheet-toggle-show.png
new file mode 100644
index 0000000000..ffe9d4d11e
Binary files /dev/null and b/Daemon Exilia/Imagens/.sheet-toggle-show.png differ
diff --git a/Daemon Exilia/Imagens/Fundo.jpg b/Daemon Exilia/Imagens/Fundo.jpg
new file mode 100644
index 0000000000..5d6d326161
Binary files /dev/null and b/Daemon Exilia/Imagens/Fundo.jpg differ
diff --git a/Daemon Exilia/Imagens/class=imgbag.png b/Daemon Exilia/Imagens/class=imgbag.png
new file mode 100644
index 0000000000..1d6dca6736
Binary files /dev/null and b/Daemon Exilia/Imagens/class=imgbag.png differ
diff --git a/Daemon Exilia/Imagens/img-dragon.png b/Daemon Exilia/Imagens/img-dragon.png
new file mode 100644
index 0000000000..491a0bedac
Binary files /dev/null and b/Daemon Exilia/Imagens/img-dragon.png differ
diff --git a/Daemon Exilia/Imagens/inic.png b/Daemon Exilia/Imagens/inic.png
new file mode 100644
index 0000000000..35e938bc61
Binary files /dev/null and b/Daemon Exilia/Imagens/inic.png differ
diff --git a/Daemon Exilia/Imagens/sheet-block-feminino.png b/Daemon Exilia/Imagens/sheet-block-feminino.png
new file mode 100644
index 0000000000..44c50fe216
Binary files /dev/null and b/Daemon Exilia/Imagens/sheet-block-feminino.png differ
diff --git a/Daemon Exilia/Imagens/sheet-block-masculino.png b/Daemon Exilia/Imagens/sheet-block-masculino.png
new file mode 100644
index 0000000000..0ea076d9e6
Binary files /dev/null and b/Daemon Exilia/Imagens/sheet-block-masculino.png differ
diff --git a/Daemon Exilia/Imagens/sheet-dado.png b/Daemon Exilia/Imagens/sheet-dado.png
new file mode 100644
index 0000000000..22d4000585
Binary files /dev/null and b/Daemon Exilia/Imagens/sheet-dado.png differ
diff --git a/Daemon Exilia/Imagens/sheet-linha-de-divisao.png b/Daemon Exilia/Imagens/sheet-linha-de-divisao.png
new file mode 100644
index 0000000000..86b06531ef
Binary files /dev/null and b/Daemon Exilia/Imagens/sheet-linha-de-divisao.png differ
diff --git a/Daemon Exilia/Imagens/sheet.image.png b/Daemon Exilia/Imagens/sheet.image.png
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/Daemon Exilia/Imagens/sheet.image.png
@@ -0,0 +1 @@
+
diff --git a/Daemon Exilia/Imagens/sheet.logo-exilia.png b/Daemon Exilia/Imagens/sheet.logo-exilia.png
new file mode 100644
index 0000000000..01de51d74e
Binary files /dev/null and b/Daemon Exilia/Imagens/sheet.logo-exilia.png differ
diff --git a/Daemon Exilia/read.me.txt b/Daemon Exilia/read.me.txt
new file mode 100644
index 0000000000..9bc51a913b
--- /dev/null
+++ b/Daemon Exilia/read.me.txt
@@ -0,0 +1,5 @@
+Este é o site oficial da editoda do sistema Daemon. Aqui vc pode encontrar um netbook com as regras oficiais do sistema.
+
+This is the official website of the Daemon system editor. Here you can find a netbook with the official rules of the system.
+
+https://www.daemon.com.br/home/
\ No newline at end of file
diff --git a/Daemon Exilia/sheet.json b/Daemon Exilia/sheet.json
new file mode 100644
index 0000000000..4d26daf6fd
--- /dev/null
+++ b/Daemon Exilia/sheet.json
@@ -0,0 +1,9 @@
+{
+ "html": "Exilia.html",
+ "css": "Exilia.css",
+ "author": "Luviants",
+ "roll20userid": 1653262,
+ "preview": "Exilia.png",
+ "instructions": "This is a new character sheet for custom Daemon system, a Brazilian OGL system.",
+ "legacy": true
+}
\ No newline at end of file
diff --git a/Das_Schwarze_Auge_5/translations/fr.json b/Das_Schwarze_Auge_5/translations/fr.json
index bd0bb0275a..5ae43f8c06 100644
--- a/Das_Schwarze_Auge_5/translations/fr.json
+++ b/Das_Schwarze_Auge_5/translations/fr.json
@@ -1131,7 +1131,7 @@
"Herunterstoßen-Regel": "\n \t\t\t\t\t\t\t\t\tRègle : Si le héros réussit une attaque avec un malus de 4 et que son adversaire ne parvient pas à se défendre, ce dernier subit le minimum de dégâts de l'arme (comme un 1 sur le dé de PI, bonus en fonction du seuil de dégâts de l'arme) et est sur le point de tomber de sa monture. Il doit immédiatement passer une épreuve d'équitation (manœuvre de combat) avec un malus de 2, si le cavalier rate son épreuve il tombe de sa monture et subit des dégâts de chute (voir règles page 340). \n\t\t\t\t\t\t\t\t\tMalus : -4 \n\t\t\t\t\t\t\t\t\tTechniques de combat : Armes d'hast \n\t\t\t\t\t\t\t\t\tPublication : VR02 - Aventurian Compendium I p. 153",
"Herunterstoßen": "Mise à terre",
"Klammergriff-Regel": "\n \t\t\t\t\t\t\t\t\tRègle : L'être doit réussir une AT avec son appendice (tentacule, bras, corps, etc.). Si l'adversaire ne réussit pas a se défendre, l'attaquant le tient fermement. Tant que l'adversaire est tenu, il souffre des statuts immobilisé et cloué sur place . Après le prochain AS, la créature n'a plus besoin de lancer d'AT, mais provoque des BL en serrant égaux aux PI de l'attaque. Ou bien, la créature peut utiliser 1 action pour soulever la victime à sa bouche. Dans l'AS suivant, la créature peut mordre si elle a une attaque de morsure. Cette attaque de morsure réussit contre un adversaire retenu. La défense de l'attaquant tombe à 0 pour le reste de l'AS dans lequel l'enserrement a lieu, la pince ne peut être utilisée que contre des adversaires de plus petite taille. Pour pouvoir se détacher de l'enserrement, un test comparatif réussi de tour de force (tirer & arracher) est nécessaire. Au moyen d'une action gratuite, la créature qui enserre peut lâcher le joueur qu'il tient. Si la créature qui enserre a soulevé sa victime, il tombe et subit le statut à terre , à moins qu'il ne réussisse un test de maîtrise corporelle (manœuvre de combat) . L'attaque subit un malus de 4. .\n\t\t\t\t\t\t\t\t\tMalus : -4 \n\t\t\t\t\t\t\t\t\tPublication : VS01 - Bestiaire aventurien I p. 9",
- "Klammerangriff": "Attaque de saisie",
+ "Klammerangriff": "Étreinte",
"Klingensturm-Regel": "\n \t\t\t\t\t\t\t\t\tRègle : L'aventurier est capable de lancer deux attaques simples en 1 action. Les deux attaques sont subissent un malus de 2 chacune. La deuxième attaque reçoit une pénalité de -2 PI. Cependant, le nombre minimum de PI est toujours d'au moins 1. Les attaques peuvent être dirigées contre différentes cibles se trouvant à distance d'attaque. Si une tempête de lames est combinée avec une manœuvre de base, elle doit être identique pour les deux attaques. Si le héros échoue pendant la première AT, la deuxième AT n'a pas lieu. La manœuvre de tempête de lames ne peut être exécutée avec un bouclier, une arme de parade ou une autre arme à une main. Le bonus de la CS combat à une main peut être utilisé lorsque vous utilisez la tempête de lames. .\n\t\t\t\t\t\t\t\t\tMalus : -2 \n\t\t\t\t\t\t\t\t\tTechniques de combat : Dagues, Armes d'escrime, Épées, Haches et masses \n\t\t\t\t\t\t\t\t\tPublication : VR02 - Aventurian Compendium I p. 154",
"Klingensturm": "Tempête de lames",
"1-Angriff": "1. Attaque",
diff --git a/Deadlands Classic/deadlandsclassic.html b/Deadlands Classic/deadlandsclassic.html
index 521e9911a8..49775057c3 100644
--- a/Deadlands Classic/deadlandsclassic.html
+++ b/Deadlands Classic/deadlandsclassic.html
@@ -307,6 +307,24 @@
+
+
Combat Initiative
+
+
+
+
+
+
General Perception
+
+
+
+
+
@@ -886,7 +904,7 @@
-
+
@@ -904,7 +922,7 @@
-
+
@@ -922,7 +940,7 @@
-
+
@@ -1033,7 +1051,7 @@
-
+
@@ -1123,7 +1141,7 @@
@@ -1504,7 +1522,7 @@
Range
Trait
TN
- Trait
+ Hand
Notes
@@ -1513,9 +1531,9 @@
-
-
-
>
+
+
+
@@ -1532,7 +1550,7 @@
Edges
-
+
@@ -1544,7 +1562,7 @@
Hindrances
-
+
@@ -1558,7 +1576,7 @@
Equipment
-
+
@@ -1567,7 +1585,7 @@
Money
-
+
@@ -1578,7 +1596,7 @@
Your Worst Nightmare
-
+
@@ -1587,7 +1605,7 @@
Character Notes
-
+
diff --git a/Deathwatch/translations/es.json b/Deathwatch/translations/es.json
index 85a409b4f1..0b8c16357c 100644
--- a/Deathwatch/translations/es.json
+++ b/Deathwatch/translations/es.json
@@ -1,199 +1,199 @@
{
- "CharacterName": "Character Name",
- "Chapter": "Chapter",
- "ChapterDemeanour": "Chapter Demeanour",
- "Speciality": "Speciality",
- "Rank": "Rank",
- "Fame": "Fame",
- "PowerArmourHistory": "Power Armour History",
- "PlayerName": "Player Name",
- "Gender": "Gender",
- "Age": "Age",
- "Build": "Build",
- "Complexion": "Complexion",
- "Hair": "Hair",
- "PersonalDemeanour": "Personal Demeanour",
- "PastEvent": "Past Event",
- "Description": "Description",
- "Characteristics": "Characteristics",
- "WeaponSkill": "Weapon Skill",
- "WeaponSkill-abbr": "WS",
- "WeaponSkill-abbrP": "(WS)",
- "BallisticSkill": "Ballistic Skill",
- "BallisticSkill-abbr": "BS",
- "BallisticSkill-abbrP": "(BS)",
- "Strength": "Strength",
- "Strength-abbr": "S",
- "Strength-abbrP": "(S)",
- "Toughness": "Toughness",
+ "CharacterName": "Nombre del PJ",
+ "Chapter": "Capítulo",
+ "ChapterDemeanour": "Actitud del Capítulo",
+ "Speciality": "Especialidad",
+ "Rank": "Rango",
+ "Fame": "Fama",
+ "PowerArmourHistory": "Servoarmadura",
+ "PlayerName": "Jugador",
+ "Gender": "Género",
+ "Age": "Edad",
+ "Build": "Alto",
+ "Complexion": "Complexión",
+ "Hair": "Pelo",
+ "PersonalDemeanour": "Actitud",
+ "PastEvent": "Pasado",
+ "Description": "Descripción",
+ "Characteristics": "Características",
+ "WeaponSkill": "Hab. Armas",
+ "WeaponSkill-abbr": "HA",
+ "WeaponSkill-abbrP": "(HA)",
+ "BallisticSkill": "Hab. Proy.",
+ "BallisticSkill-abbr": "HP",
+ "BallisticSkill-abbrP": "(HP)",
+ "Strength": "Fuerza",
+ "Strength-abbr": "F",
+ "Strength-abbrP": "(F)",
+ "Toughness": "Resistencia",
"Toughness-abbr": "T",
- "Toughness-abbrP": "(T)",
- "Agility": "Agility",
+ "Toughness-abbrP": "(R)",
+ "Agility": "Agilidad",
"Agility-abbr": "Ag",
"Agility-abbrP": "(Ag)",
- "Intelligence": "Intelligence",
+ "Intelligence": "Inteligencia",
"Intelligence-abbr": "Int",
"Intelligence-abbrP": "(Int)",
- "Perception": "Perception",
+ "Perception": "Percepción",
"Perception-abbr": "Per",
"Perception-abbrP": "(Per)",
- "Willpower": "Willpower",
- "Willpower-abbr": "WP",
- "Willpower-abbrP": "(WP)",
- "Fellowship": "Fellowship",
- "Fellowship-abbr": "Fel",
- "Fellowship-abbrP": "(Fel)",
- "None0": "None (0)",
- "Simple5": "Simple (+5)",
- "Intermediate10": "Intermediate (+10)",
- "Trained15": "Trained (+15)",
- "Expert20": "Expert (+20)",
- "Expert25": "Expert (+25)",
- "Experience": "Experience",
- "XPtoSpend": "XP to Spend",
- "TotalXPSpent": "Total XP Spent",
- "FatePoints": "Fate Points",
- "FPThreshold": "Threshold",
- "FPCurrent": "Current",
- "Insanity": "Insanity",
- "MentalDisorders": "Mental Disorders",
- "Corruption": "Corruption",
- "Malignancies": "Malignancies",
- "Mutations": "Mutations",
- "PrimarchsCurse": "Primarch's Curse",
- "Skills": "Skills",
- "Acrobatics": "Acrobatics",
- "Awareness": "Awareness",
- "Blather": "Blather",
- "Carouse": "Carouse",
- "Charm": "Charm",
- "ChemUse": "Chem-Use",
- "Climb": "Climb",
- "Command": "Command",
- "Concealment": "Concealment",
- "Contortionist": "Contortionist",
- "Deceive": "Deceive",
- "Demolition": "Demolition",
- "Disguise": "Disguise",
- "Dodge": "Dodge",
- "Evaluate": "Evaluate",
- "Gamble": "Gamble",
- "Inquiry": "Inquiry",
- "Interrogation": "Interrogation",
- "Intimidate": "Intimidate",
- "Invocation": "Invocation",
- "Literacy": "Literacy",
- "Logic": "Logic",
+ "Willpower": "Voluntad",
+ "Willpower-abbr": "V",
+ "Willpower-abbrP": "(V)",
+ "Fellowship": "Empatía",
+ "Fellowship-abbr": "Em",
+ "Fellowship-abbrP": "(Em)",
+ "None0": "Nada (0)",
+ "Simple5": "Sencillo (+5)",
+ "Intermediate10": "Intermedio (+10)",
+ "Trained15": "Entrenado (+15)",
+ "Expert20": "Experto (+20)",
+ "Expert25": "Experto (+25)",
+ "Experience": "Experiencia",
+ "XPtoSpend": "PX a Gastar",
+ "TotalXPSpent": "Total PX",
+ "FatePoints": "Puntos de Destino",
+ "FPThreshold": "Umbral",
+ "FPCurrent": "Actual",
+ "Insanity": "Locura",
+ "MentalDisorders": "Trastornos Mentales",
+ "Corruption": "Corrupción",
+ "Malignancies": "Malignidad",
+ "Mutations": "Mutaciones",
+ "PrimarchsCurse": "Maldición del Primarca",
+ "Skills": "Habilidades",
+ "Acrobatics": "Acrobacias",
+ "Awareness": "Percepción",
+ "Blather": "Charlatanería",
+ "Carouse": "Aguante",
+ "Charm": "Carisma",
+ "ChemUse": "Comp. Química",
+ "Climb": "Trepar",
+ "Command": "Mando",
+ "Concealment": "Esconderse",
+ "Contortionist": "Contorsion",
+ "Deceive": "Engañar",
+ "Demolition": "Demoliciones",
+ "Disguise": "Disfraz",
+ "Dodge": "Esquivar",
+ "Evaluate": "Tasar",
+ "Gamble": "Jugar",
+ "Inquiry": "Indagar",
+ "Interrogation": "Interrogación",
+ "Intimidate": "Intimidar",
+ "Invocation": "Invocación",
+ "Literacy": "Leer/Escribir",
+ "Logic": "Lógica",
"Medicae": "Medicae",
- "Psyniscience": "Psyniscience",
- "Scrutiny": "Scrutiny",
- "Search": "Search",
- "Security": "Security",
- "Shadowing": "Shadowing",
- "SilentMove": "Silent Move",
- "SleightOfHand": "Sleight of Hand",
- "Survival": "Survival",
- "Swim": "Swim",
- "TechUse": "Tech-Use",
- "Tracking": "Tracking",
- "Wrangling": "Wrangling",
- "OtherSkill": "Other Skill",
- "Ciphers": "Ciphers",
- "Drive": "Drive",
- "SpeakLanguage": "Speak Language",
- "Navigation": "Navigation",
- "Performer": "Performer",
- "Pilot": "Pilot",
- "Tactics": "Tactics",
- "Trade": "Trade",
- "Lore": "Lore",
- "LoreCommon": "Common",
- "LoreScholastic": "Scholastic",
- "LoreForbidden": "Forbidden",
+ "Psyniscience": "Psinisciencia",
+ "Scrutiny": "Escrutinio",
+ "Search": "Buscar",
+ "Security": "Seguridad",
+ "Shadowing": "Seguimiento",
+ "SilentMove": "Mov. Silencioso",
+ "SleightOfHand": "Trucos de manos",
+ "Survival": "Supervivencia",
+ "Swim": "Nadar",
+ "TechUse": "Comp. Tecno",
+ "Tracking": "Rastrear",
+ "Wrangling": "Trato Animal",
+ "OtherSkill": "Otro",
+ "Ciphers": "Cifrado",
+ "Drive": "Conducir",
+ "SpeakLanguage": "Hablar Idioma",
+ "Navigation": "Navegación",
+ "Performer": "Interpretar",
+ "Pilot": "Pilotaje",
+ "Tactics": "Táctica",
+ "Trade": "Comercio",
+ "Lore": "Saber",
+ "LoreCommon": "Común",
+ "LoreScholastic": "Scholástica",
+ "LoreForbidden": "Prohibido",
"Aptitudes": "Aptitudes",
- "MeleeWeapons": "Melee Weapons",
- "WName": "Name",
- "WClass": "Class",
- "WDamage": "Damage",
- "WType": "Type",
+ "MeleeWeapons": "Armas CaC",
+ "WName": "Nombre",
+ "WClass": "Clase",
+ "WDamage": "Daño",
+ "WType": "Tipo",
"WPen": "Pen",
- "Damage": "Damage",
- "WSpecial": "Special",
- "WHit": "Hit",
- "StrengthBonus-abbr": "SB",
- "UnnaturalStrengthBonus-abbr": "Unn. SB",
- "PowerArmorStrengthBonus-abbr": "PA SB",
- "MWRelevantBonus": "rel. Bonus",
- "Movement": "Movement",
- "HalfMove": "Half Move",
- "FullMove": "Full Move",
- "Charge": "Charge",
- "Run": "Run",
- "Fatigue": "Fatigue",
- "Threshold": "Threshold",
- "Current": "Current",
+ "Damage": "Daño",
+ "WSpecial": "Especial",
+ "WHit": "Golpe",
+ "StrengthBonus-abbr": "BF",
+ "UnnaturalStrengthBonus-abbr": "Inn. BF",
+ "PowerArmorStrengthBonus-abbr": "SA BF",
+ "MWRelevantBonus": "Bono",
+ "Movement": "Movimiento",
+ "HalfMove": "Mov. Parcial",
+ "FullMove": "Completo",
+ "Charge": "Carga",
+ "Run": "Correr",
+ "Fatigue": "Fatiga",
+ "Threshold": "Umbral",
+ "Current": "Actual",
"Misc": "Misc",
- "ArmournDefence": "Armour & Defence",
- "Head": "Head",
- "ArmRight": "AR",
- "Body": "Body",
- "ArmLeft": "AL",
- "LegRight": "LR",
- "LegLeft": "LL",
- "Wounds": "Wounds",
+ "ArmournDefence": "Armadura y Defensa",
+ "Head": "Cabeza",
+ "ArmRight": "BD",
+ "Body": "Cuerpo",
+ "ArmLeft": "BI",
+ "LegRight": "PD",
+ "LegLeft": "PI",
+ "Wounds": "Heridas",
"WoundsTotal": "Total",
- "WoundsCurrent": "Current",
- "CriticalDamage": "Critical Damage",
- "Conditions": "Conditions",
- "SpecialAbilities": "Special Abilities",
- "Talents": "Talents",
- "Traits": "Traits",
- "RangedWeapons": "Ranged Weapons",
- "WRange": "Range",
- "WRateOfFire": "RoF",
- "WClip": "Clip",
- "WReload": "Reload",
- "SignatureGear": "Signature Gear",
- "Requisition": "Requisition",
- "RequisitionedGear": "Requisitioned Gear",
- "MaxCarryWT": "Max Carry WT (SB+TB)",
- "CurrentWeight": "Current",
- "PsychicPowers": "Psychic Powers",
- "PsyRating": "Psy Rating",
- "MiscellaneousSkills": "Miscellaneous Skills",
- "OtherSkills": "Other",
- "ExpandedSkills": "Expanded Skills",
- "ExperiencePoints": "Experience Points",
- "AdvancementsTaken": "Advancements Taken",
- "SoloModeAbilities": "Solo Mode Abilities",
+ "WoundsCurrent": "Actual",
+ "CriticalDamage": "Daño crítico",
+ "Conditions": "Condiciones",
+ "SpecialAbilities": "Habilidades especiales",
+ "Talents": "Talentos",
+ "Traits": "Rasgos",
+ "RangedWeapons": "Armas a distancia",
+ "WRange": "Alcance",
+ "WRateOfFire": "CdF",
+ "WClip": "Balas",
+ "WReload": "Recarga",
+ "SignatureGear": "Equipo personal",
+ "Requisition": "Solicitud",
+ "RequisitionedGear": "Equipo Solicitado",
+ "MaxCarryWT": "Peso Máximo PM (BF+BR)",
+ "CurrentWeight": "Actual",
+ "PsychicPowers": "Poderes Psíquicos",
+ "PsyRating": "Factor Psíquico",
+ "MiscellaneousSkills": "Habilidades Varias",
+ "OtherSkills": "Otros",
+ "ExpandedSkills": "Habilidades Avanzadas",
+ "ExperiencePoints": "Puntos de experiencia",
+ "AdvancementsTaken": "Avances tomados",
+ "SoloModeAbilities": "Habilidades Modo Solitario",
"Cohesion": "Cohesion",
"CohesionTotal": "Total",
- "CohesionCurrent": "Current",
- "SquadModeAbilities": "Squad Mode Abilities",
- "CharacteristicsnSkills": "Characteristics & Skills",
- "WeaponnTalents": "Weapon & Talents",
- "OtherSkillsTitle": "Other Skills",
- "Abilities": "Abilities",
- "RelevantStrengthBonusDamage": "Relevant Strength Bonus added to damage from this weapon",
- "UnnaturalStrengthBonus": "Strength Bonus with unnatural Strength taken into account",
- "PowerArmorStrengthBonus": "Astartes Power Armour Enhanced Strength Bonus",
- "UseSB": "Use the Strength Bonus for this weapon?",
- "PowerArmorMovementBonus": "Astartes Power Armour Movement Bonus",
- "Unknown": "Unknown",
- "Basic": "Basic",
- "BasicKnowledge": "Basic",
- "Group": "Group",
- "Advanced": "Advanced",
- "Trained": "Trained",
+ "CohesionCurrent": "Actual",
+ "SquadModeAbilities": "Habilidades Modo Escuadra",
+ "CharacteristicsnSkills": "Caracs. y Habilidades",
+ "WeaponnTalents": "Armas y Talentos",
+ "OtherSkillsTitle": "Otras Habilidades",
+ "Abilities": "Habilidades",
+ "RelevantStrengthBonusDamage": "El BF añadido al daño de esta arma",
+ "UnnaturalStrengthBonus": "Bonificador de Fuerza con Fuerza innatural se tiene en cuenta",
+ "PowerArmorStrengthBonus": "Bonificador de Fuerza mejorado de Servoarmadura Astartes",
+ "UseSB": "¿Usar el BF para esta arma?",
+ "PowerArmorMovementBonus": "Bono de Movimiento de la Servoarmadura Astartes",
+ "Unknown": "Descon.",
+ "Basic": "Base",
+ "BasicKnowledge": "Cono.Base",
+ "Group": "Grupo",
+ "Advanced": "Avanzado",
+ "Trained": "Entrenada",
"Plus10": "+10%",
"Plus20": "+20%",
- "basic-skills-list": "Awareness,Carouse,Charm,Climb,Command,Concealment,Contortionist,Deceive,Disguise,Dodge,Evaluate,Gamble,Inquiry,Intimidate,Logic,Scrutiny,Search,SilentMove,Swim",
- "advanced-skills-list": "Acrobatics,Blather,ChemUse,Demolition,Interrogation,Invocation,Literacy,Medicae,Psyniscience,Security,Shadowing,SleightOfHand,Survival,TechUse,Tracking,Wrangling",
- "group-skills-list": "Ciphers,Drive,Lore,LoreCommon,LoreScholastic,LoreForbidden,Navigation,Performer,Pilot,SpeakLanguage,Tactics,Trade",
- "UnnaturalMultiplier": "Put your unnatural characteristic multiplier in this box (not the characteristic bonus)",
- "DegreesOfSuccess": "Degree(s) of success",
- "MeleeAttack": "Melee Attack",
- "RangedAttack": "Ranged Attack",
- "Penetration": "Penetration",
- "HideLogMessage": "Tick me to hide this message >>"
+ "basic-skills-list": "Perspicacia,Aguante,Carisma,Trepar,Mando,Esconderse,Contorsionismo,Engañar,Disfraz,Esquivar,Tasar,Jugar,Indagar,Intimidar,Lógica,Escrutinio,Buscar,MovSilencioso,Nadar",
+ "advanced-skills-list": "Acrobacias,Charlatanería,CompetenciaQuimica,Demoliciones,Interrogación,Invocación,Leer/Escribir,Medicae,Psiniscencia,Seguridad,Seguimiento,TrucodeManos,Supervivencia,CompetenciaTecnológica,Rastrear,TratoAnimal",
+ "group-skills-list": "Cifrar,Conducir,Saber,SaberComún,SaberScholastica,SaberProhibido,Navegación,Interpretar,Pilotar,HablarIdioma,Tácticas,Comercio",
+ "UnnaturalMultiplier": "Pon tu multiplicador de característica innatural en esta casilla (no el bono de característica)",
+ "DegreesOfSuccess": "Nivel de Éxito",
+ "MeleeAttack": "Ataque Cuerpo a Cuerpo",
+ "RangedAttack": "Ataque a Distancia",
+ "Penetration": "Penetración",
+ "HideLogMessage": "Pulsa aquí para esconder este mensaje"
}
\ No newline at end of file
diff --git a/Delta Green 2/deltagreen.css b/Delta Green 2/deltagreen.css
index c4e25b43a7..d970943f5b 100644
--- a/Delta Green 2/deltagreen.css
+++ b/Delta Green 2/deltagreen.css
@@ -763,6 +763,73 @@ div.sheet-npc div.sheet-section-body div.sheet-notes div.sheet-section {
/* PC SHEET
============================= */
+/* SUMMARY UPDATE */
+div.sheet-datahide {
+ display: none;
+}
+
+div[data-groupname=repeating_summary].repcontrol {
+ display: none;
+}
+
+div.sheet-summary {
+ position: absolute;
+ bottom: 40px;
+ right: 10px;
+ display: none;
+ z-index: 1000;
+ background: white;
+ border: 0.01em solid black;
+ width: 30%;
+ min-height: 20%;
+ overflow-y: scroll;
+}
+
+.sheet-section-summary {
+ grid-column-gap: 0.2em;
+ grid-row-gap: 0.2em;
+ grid-template-columns: 4fr 1fr 1fr 1fr;
+ display: grid;
+ justify-items: start;
+}
+
+div.sheet-updateinfo {
+ position: relative;
+}
+div.sheet-updateinfo input[type=checkbox] {
+ opacity: 0;
+ width: 16px;
+ height: 16px;
+ position: relative;
+ top: 5px;
+ left: 6px;
+ margin: -10px;
+ cursor: pointer;
+ z-index: 1;
+}
+div.sheet-updateinfo input[type=checkbox] + span::before {
+ margin-right: 4px;
+ line-height: 14px;
+ text-align: center;
+ display: inline-block;
+ vertical-align: middle;
+ content: "?";
+ font-weight: bold;
+ color: black;
+ width: 14px;
+ height: 14px;
+ font-size: 12px;
+}
+div.sheet-updateinfo input[type=checkbox]:checked ~ div.sheet-summary {
+ display: grid;
+}
+div.sheet-updateinfo input[type=checkbox]:checked + span::before {
+ content: "?";
+ font-weight: bold;
+ color: gray;
+}
+
+/* MAIN SHEET */
div.sheet-pc {
grid-column-gap: 0.2em;
grid-row-gap: 0.2em;
diff --git a/Delta Green 2/deltagreen.css.map b/Delta Green 2/deltagreen.css.map
index f6786b066b..0c2d4fb46d 100644
--- a/Delta Green 2/deltagreen.css.map
+++ b/Delta Green 2/deltagreen.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["src/scss/_globals.scss","src/scss/_variables.scss","src/scss/_mixins.scss","src/scss/_repcontrol.scss","src/scss/_rolltemplate.scss","deltagreen.scss","src/scss/_switch.scss","src/scss/_pc.scss","src/scss/_section_personal_data.scss"],"names":[],"mappings":"AAAA;AAAA;AAEI;EACI;EACA;;;AAGJ;EACI;EACA;;AAGI;EACI;;AAGJ;EAGI,OCdA;EDeA;;AAGJ;EAEI,YCjBA;EDmBI;EACA;EACA;EACA;EACA;EACA;EAEJ;EACA;;AAGJ;EACI,YC5BA;;AD8BA;EACI,kBChCJ;EDiCI,OCtCJ;;AD0CH;EACG,YCxCA;;AD0CA;EACI,kBC5CJ;ED6CI,OC/CJ;;ADoDR;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;EACA;;AACA;EEtDJ;EACA;EACA;EFsDQ;EACA;;AAIR;EACI;EACA;EACA;;AAIA;EAEI;EACA;EACA;EACA,OCzFA;ED0FA;EACA;;AAEA;EACI,YC5FJ;;ADiGR;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA,OC9GI;ED+GJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,YC7HA;;;AECf;EACC;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;;AAGD;AAAA;EAEC;EACA,OFxBa;EEyBb;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAGD;EACC;EACA;;AAGD;AAAA;AAAA;AAAA;EAIC,YF1Ca;;AE6Cd;AAAA;AAAA;AAAA;EAIC,OFlDa;;;AEsDf;EAAgD;;;AAEhD;EACC;;AAEA;AAAA;EAEC;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAEA;EACa;;;AAKf;EACC;;;ACpFF;AAAA;AAGI;AAEI;AAAA;;AAEA;EACI;EACA;EACA;EACA;AAEA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGI;;AAGJ;EACI,OHlBA;;AGqBJ;EACI;EACA;EACA;EACA;EACA;;AAIJ;EACI,kBH/BA;EGgCA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,OHzCJ;EG0CI;EACA;;AAGJ;EACI,OHzCJ;EG0CI;;AAKJ;EACI,kBHtDJ;EGuDI;;AAEA;EAAoB,kBHxDxB;;AG0DI;EACI;EACA;EACA,OH/DR;EGgEQ;EAEI;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACI,OH7EZ;EG8EY;EACA;EACA;EACA;;AAGJ;EAEI,OHtFZ;EGuFY;;;AASxB;AAEI;AAAA;;AAEA;EACI;EACA;EACA;EACA;AAEA;AAAA;;AAEA;AAAA;AAAA;EAGI;;AAGJ;EACI,OHnHA;;AGsHJ;EACI;EACA;EACA;EACA;EACA;;AAIJ;EACI,kBHhIA;EGiIA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,OH1IJ;EG2II;EACA;;AAGJ;EACI,OH1IJ;EG2II;;AAKJ;EACI,kBHvJJ;EGwJI;;AAEA;EAAoB,kBHzJxB;;AG2JI;EACI;EACA;EACA,OHhKR;EGiKQ;EAEI;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACI,OH9KZ;EG+KY;EACA;EACA;EACA;;AAGJ;EAEI,OHvLZ;EGwLY;;;ACpK5B;AAAA;AAEI;EACI;;;AAGJ;AAAA;EAEI;;;AAGH;AAAA;AAIC;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AAKH;AAAA;AAED;AAAA;EAEI;EACA;;;AAGR;AAAA;ACrDA;AACA;EACE;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE,kBLnCc;;;AKsChB;EACE;;;AAGF;EACE;EACA;EACA;;;ADKF;AAAA;AAEI;EHxDI,kBDMQ;EIoDR;EACA,OJ1DQ;;;AI6DhB;AAAA;AAEI;EACI;;;AAOI;EHpEJ;;AGuEI;EHvEJ;;AGoEI;EHpEJ;;AGuEI;EHvEJ;;AGoEI;EHpEJ;;AGuEI;EHvEJ;;;AG6ER;AAAA;AAEI;EACI;EACA;EHrFA;;AGwFA;EACI;;AAGJ;EACI;EACA;EACA;;AAGJ;EH9FA;EGgGI;;AAGJ;EHnGA;;AGuGA;EHvGA;;AG2GA;EH3GA;;AG+GA;EACI,kBJpHI;EIqHJ;EACA,OJrHI;EIsHJ;EACA;;AAGJ;EACI,OJ3HI;EI4HJ;;AAEA;EACG;EH5HP;;AGgII;EACG;EHjIP;;;AGuIR;AAAA;AAEI;EAAgB;;;AAChB;EAAuB;;;AACvB;EHnII,YGmIgC;;;AACpC;EAAqB;;;AACrB;EAAe;;;AACf;EAAoB;;;AACpB;EAAgB;;;AAChB;EAAc;;;AACd;EAAyB;;;AAC5B;EAAa;;;AACV;EACI,OJxJQ;EIyJR;;;AAGJ;AAAA;EAEI;EACA;;;AAGR;AAAA;AAGQ;EACI;EACA;;;AAIZ;AAAA;AAGI;AAAA;EAEI;;AAIA;EACI,OJrLI;EIsLJ;EACA;;AAIR;EACK;EACA;EACA;AA0CD;AAAA;AAwCA;AAAA;AAQA;AAAA;AAcA;AAAA;AAmBA;AAAA;;AAzHA;EAAK;;AAEL;EACI;EACA;;AAGJ;EACI;EACA;;AAEC;EAEG,OJ5MA;;AIgNR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIR;EACI;EACA;;AAGJ;AAAA;EAEI;;AAKJ;EHtOA;;AGuOA;EHvOA;;AGwOA;EHxOA;;AGyOA;EHzOA;;AG0OA;EH1OA;;AG2OA;EH3OA;;AG4OA;EH5OA;;AG6OA;EH7OA;;AG+ON;EH/OM;EGiPL;;AACG;EACG;EACA;;AAEH;EHtPE;;AGuPF;EACG;EACA;EACA;;AAEH;EACG;EACA;;AAGA;EACG,OJtQI;EIuQJ;EACA;EACA;EACA;EACA;;AAOJ;EH9QA;;AG+QA;EH/QA;EGiRI;;AAKJ;EHtRA;;AGuRA;EACI;EACA;;AAEA;AAAA;EAEI;EACA;;AAMR;EHpSA;;AGqSA;EACI;EACA;;AAEA;EACI;;AAIJ;AAAA;EAEG;EACA;;AAMP;EHvTA;;AGwTA;EACI;EACA;;AAEA;AAAA;EAEI;EACA;;;AAMhB;AAAA;AE7UG;EACK;EACA;EACA;AA4CA;AAAA;AAUA;AAAA;AAwEA;AAAA;AA8CA;AAAA;AAiFA;AAAA;AAYA;AAAA;AA4BA;AAAA;AAwCA;AAAA;AAUA;AAAA;;AArVA;EACI,ONDI;EMEJ;EACA;EACA;;AAIA;EAEI;;AAIR;ELfA;EAIA;EKcG;EACA;EACN;;AAGG;AAAA;ELvBA;;AK4BA;EACI;;AAIA;EACI;;AAGJ;EACI;;AAOR;EACI;AClDZ;AAAA;;AAIQ;EAAyB;;AAAzB;EAAyB;;AAAzB;EAAyB;;AAG7B;EAEI;;AAGA;EAAqB;;AACrB;EAAwB;;AAExB;EAAsB;;AAGtB;EAAqB;;AACrB;EAAwB;;AAG5B;EACI;;AAGA;EAAoB;;AACpB;EAAwB;;AACxB;EAAqC;;AAGrC;EAAqB;;AACrB;EAAwB;;AACxB;EAAqC;;AAGrC;EAAqB;;AACrB;EAAwB;;ADiBpB;EAAqB;;AAKzB;ELnDA;;AKsDI;EACI;;AAEJ;AAAA;EAEI;;AAEA;AAAA;EAAO;;AAGX;EACI;EACA;EACA;;AAIJ;EACI;;AAEA;EAAsB;;AACtB;EAAsB;;AAGlB;EACI,kBN5ER;EM6EQ;;AAMZ;EACI;;AACA;EACI;;AACA;EAAsB;;AACtB;EACI;;AAIR;EACG;;AAGH;EACI;;AAEA;EACI,kBNrGR;;AM2GJ;EACI;AACA;;AACA;AACE;EACE;EACf;;AAOG;EL3HA;AK6HI;AAAA;;AAEA;EACI;;AAEJ;EACI;;AAIA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGI;EACI;;AAMhB;EACI;EACA;;AAEA;EAAK;;AAMb;EACI;;AAEA;EACI;;AAGI;EACI;;AADJ;EACI;;AADJ;EACI;;AAIR;EACI;;AAEA;EAEI;;AAGJ;EAAsB;;AAEtB;EACI;EACA;;AAEA;EACI;EACA;EACA;;AAGJ;EAAmC;;AAInC;EAAmB;;AAEnB;EACI;EACA;;AAIR;EACI;EACA;;AAGJ;EAA2B;;AAE3B;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AACA;EAAyB;;AAGrB;EACI;;AAIR;EACI;;AAKZ;EAA+B;;AAMvC;EACI;;AAEA;EAAK;;AACL;EAAQ;;AAER;EAAoB;;AAMxB;EACI;;AAEA;EACI;;AAIA;EAAmB;;AACnB;EAAsB;;AAKlB;EACI;;AAIR;EACI;;AAQZ;EACI;;AAEA;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EACI;;AAMA;EACI;;AAMhB;EACI;;AAOR;EACI;EACA;;AAEA;EAAK;;AACL;EAAQ;;AAKZ;EACI;EACA;EACA;;AAEA;EACI;;AAEA;EACI,ONjWJ;EMkWI;EACA;;AAGJ;EACI,ONjWJ;EMkWI;EACA;;;AAKnB;AACA;EACC;;;AFnCF;AAAA;AAEI;EACI;EACA;;;AAGR;AAAA;AAEI;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGR;AAAA;AAEA;AAAA;EAEI;EACA;;;AAEJ;EACI;;;AAIJ;EAA4E;;;AAC5E;EAA4E","file":"deltagreen.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["src/scss/_globals.scss","src/scss/_variables.scss","src/scss/_mixins.scss","src/scss/_repcontrol.scss","src/scss/_rolltemplate.scss","deltagreen.scss","src/scss/_switch.scss","src/scss/_pc.scss","src/scss/_section_personal_data.scss"],"names":[],"mappings":"AAAA;AAAA;AAEI;EACI;EACA;;;AAGJ;EACI;EACA;;AAGI;EACI;;AAGJ;EAGI,OCdA;EDeA;;AAGJ;EAEI,YCjBA;EDmBI;EACA;EACA;EACA;EACA;EACA;EAEJ;EACA;;AAGJ;EACI,YC5BA;;AD8BA;EACI,kBChCJ;EDiCI,OCtCJ;;AD0CH;EACG,YCxCA;;AD0CA;EACI,kBC5CJ;ED6CI,OC/CJ;;ADoDR;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;EACA;;AACA;EEtDJ;EACA;EACA;EFsDQ;EACA;;AAIR;EACI;EACA;EACA;;AAIA;EAEI;EACA;EACA;EACA,OCzFA;ED0FA;EACA;;AAEA;EACI,YC5FJ;;ADiGR;EACI;EACA;;AAGJ;EACI;;AAGJ;EACI;EACA,OC9GI;ED+GJ;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACI,YC7HA;;;AECf;EACC;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;;AAGD;AAAA;EAEC;EACA,OFxBa;EEyBb;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAGD;EACC;EACA;;AAGD;AAAA;AAAA;AAAA;EAIC,YF1Ca;;AE6Cd;AAAA;AAAA;AAAA;EAIC,OFlDa;;;AEsDf;EAAgD;;;AAEhD;EACC;;AAEA;AAAA;EAEC;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAEA;EACa;;;AAKf;EACC;;;ACpFF;AAAA;AAGI;AAEI;AAAA;;AAEA;EACI;EACA;EACA;EACA;AAEA;AAAA;;AAEA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAGI;;AAGJ;EACI,OHlBA;;AGqBJ;EACI;EACA;EACA;EACA;EACA;;AAIJ;EACI,kBH/BA;EGgCA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,OHzCJ;EG0CI;EACA;;AAGJ;EACI,OHzCJ;EG0CI;;AAKJ;EACI,kBHtDJ;EGuDI;;AAEA;EAAoB,kBHxDxB;;AG0DI;EACI;EACA;EACA,OH/DR;EGgEQ;EAEI;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACI,OH7EZ;EG8EY;EACA;EACA;EACA;;AAGJ;EAEI,OHtFZ;EGuFY;;;AASxB;AAEI;AAAA;;AAEA;EACI;EACA;EACA;EACA;AAEA;AAAA;;AAEA;AAAA;AAAA;EAGI;;AAGJ;EACI,OHnHA;;AGsHJ;EACI;EACA;EACA;EACA;EACA;;AAIJ;EACI,kBHhIA;EGiIA;EACA;EACA;;AAEA;EACI;EACA;;AAGJ;EACI,OH1IJ;EG2II;EACA;;AAGJ;EACI,OH1IJ;EG2II;;AAKJ;EACI,kBHvJJ;EGwJI;;AAEA;EAAoB,kBHzJxB;;AG2JI;EACI;EACA;EACA,OHhKR;EGiKQ;EAEI;EACA;EACA;EACA;EACA;EACA;;AAKJ;EACI,OH9KZ;EG+KY;EACA;EACA;EACA;;AAGJ;EAEI,OHvLZ;EGwLY;;;ACpK5B;AAAA;AAEI;EACI;;;AAGJ;AAAA;EAEI;;;AAGH;AAAA;AAIC;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AADF;EACE;;;AAKH;AAAA;AAED;AAAA;EAEI;EACA;;;AAGR;AAAA;ACrDA;AACA;EACE;EACA;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;;;AAGF;AACA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGF;EACE,kBLnCc;;;AKsChB;EACE;;;AAGF;EACE;EACA;EACA;;;ADKF;AAAA;AAEI;EHxDI,kBDMQ;EIoDR;EACA,OJ1DQ;;;AI6DhB;AAAA;AAEI;EACI;;;AAOI;EHpEJ;;AGuEI;EHvEJ;;AGoEI;EHpEJ;;AGuEI;EHvEJ;;AGoEI;EHpEJ;;AGuEI;EHvEJ;;;AG6ER;AAAA;AAEI;EACI;EACA;EHrFA;;AGwFA;EACI;;AAGJ;EACI;EACA;EACA;;AAGJ;EH9FA;EGgGI;;AAGJ;EHnGA;;AGuGA;EHvGA;;AG2GA;EH3GA;;AG+GA;EACI,kBJpHI;EIqHJ;EACA,OJrHI;EIsHJ;EACA;;AAGJ;EACI,OJ3HI;EI4HJ;;AAEA;EACG;EH5HP;;AGgII;EACG;EHjIP;;;AGuIR;AAAA;AAEI;EAAgB;;;AAChB;EAAuB;;;AACvB;EHnII,YGmIgC;;;AACpC;EAAqB;;;AACrB;EAAe;;;AACf;EAAoB;;;AACpB;EAAgB;;;AAChB;EAAc;;;AACd;EAAyB;;;AAC5B;EAAa;;;AACV;EACI,OJxJQ;EIyJR;;;AAGJ;AAAA;EAEI;EACA;;;AAGR;AAAA;AAGQ;EACI;EACA;;;AAIZ;AAAA;AAGI;AAAA;EAEI;;AAIA;EACI,OJrLI;EIsLJ;EACA;;AAIR;EACK;EACA;EACA;AA0CD;AAAA;AAwCA;AAAA;AAQA;AAAA;AAcA;AAAA;AAmBA;AAAA;;AAzHA;EAAK;;AAEL;EACI;EACA;;AAGJ;EACI;EACA;;AAEC;EAEG,OJ5MA;;AIgNR;EACI;;AAEA;EACI;;AAGJ;EACI;EACA;;AAIR;EACI;EACA;;AAGJ;AAAA;EAEI;;AAKJ;EHtOA;;AGuOA;EHvOA;;AGwOA;EHxOA;;AGyOA;EHzOA;;AG0OA;EH1OA;;AG2OA;EH3OA;;AG4OA;EH5OA;;AG6OA;EH7OA;;AG+ON;EH/OM;EGiPL;;AACG;EACG;EACA;;AAEH;EHtPE;;AGuPF;EACG;EACA;EACA;;AAEH;EACG;EACA;;AAGA;EACG,OJtQI;EIuQJ;EACA;EACA;EACA;EACA;;AAOJ;EH9QA;;AG+QA;EH/QA;EGiRI;;AAKJ;EHtRA;;AGuRA;EACI;EACA;;AAEA;AAAA;EAEI;EACA;;AAMR;EHpSA;;AGqSA;EACI;EACA;;AAEA;EACI;;AAIJ;AAAA;EAEG;EACA;;AAMP;EHvTA;;AGwTA;EACI;EACA;;AAEA;AAAA;EAEI;EACA;;;AAMhB;AAAA;AE7UG;AAEA;EAAmB;;;AACnB;EACM;;;AAEN;EACM;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGN;EACG;EACA;EACA;EACA;EACA;;;AAEH;EACK;;AACA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;EACI;;AAEJ;EACI;EACA;EACA;;;AAMb;AAEA;EACK;EACA;EACA;AA4CA;AAAA;AAUA;AAAA;AAwEA;AAAA;AA8CA;AAAA;AAiFA;AAAA;AAYA;AAAA;AA4BA;AAAA;AAwCA;AAAA;AAUA;AAAA;;AArVA;EACI,ONlEI;EMmEJ;EACA;EACA;;AAIA;EAEI;;AAIR;ELhFA;EAIA;EK+EG;EACA;EACN;;AAGG;AAAA;ELxFA;;AK6FA;EACI;;AAIA;EACI;;AAGJ;EACI;;AAOR;EACI;ACnHZ;AAAA;;AAIQ;EAAyB;;AAAzB;EAAyB;;AAAzB;EAAyB;;AAG7B;EAEI;;AAGA;EAAqB;;AACrB;EAAwB;;AAExB;EAAsB;;AAGtB;EAAqB;;AACrB;EAAwB;;AAG5B;EACI;;AAGA;EAAoB;;AACpB;EAAwB;;AACxB;EAAqC;;AAGrC;EAAqB;;AACrB;EAAwB;;AACxB;EAAqC;;AAGrC;EAAqB;;AACrB;EAAwB;;ADkFpB;EAAqB;;AAKzB;ELpHA;;AKuHI;EACI;;AAEJ;AAAA;EAEI;;AAEA;AAAA;EAAO;;AAGX;EACI;EACA;EACA;;AAIJ;EACI;;AAEA;EAAsB;;AACtB;EAAsB;;AAGlB;EACI,kBN7IR;EM8IQ;;AAMZ;EACI;;AACA;EACI;;AACA;EAAsB;;AACtB;EACI;;AAIR;EACG;;AAGH;EACI;;AAEA;EACI,kBNtKR;;AM4KJ;EACI;AACA;;AACA;AACE;EACE;EACf;;AAOG;EL5LA;AK8LI;AAAA;;AAEA;EACI;;AAEJ;EACI;;AAIA;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;EACA;;AAGI;EACI;;AAMhB;EACI;EACA;;AAEA;EAAK;;AAMb;EACI;;AAEA;EACI;;AAGI;EACI;;AADJ;EACI;;AADJ;EACI;;AAIR;EACI;;AAEA;EAEI;;AAGJ;EAAsB;;AAEtB;EACI;EACA;;AAEA;EACI;EACA;EACA;;AAGJ;EAAmC;;AAInC;EAAmB;;AAEnB;EACI;EACA;;AAIR;EACI;EACA;;AAGJ;EAA2B;;AAE3B;EACI;EACA;EACA;EACA;;AAGJ;EACI;EACA;;AACA;EAAyB;;AAGrB;EACI;;AAIR;EACI;;AAKZ;EAA+B;;AAMvC;EACI;;AAEA;EAAK;;AACL;EAAQ;;AAER;EAAoB;;AAMxB;EACI;;AAEA;EACI;;AAIA;EAAmB;;AACnB;EAAsB;;AAKlB;EACI;;AAIR;EACI;;AAQZ;EACI;;AAEA;EACI;;AAEA;EACI;EACA;;AAGJ;EACI;;AAEA;EACI;;AAGJ;EACI;;AAMA;EACI;;AAMhB;EACI;;AAOR;EACI;EACA;;AAEA;EAAK;;AACL;EAAQ;;AAKZ;EACI;EACA;EACA;;AAEA;EACI;;AAEA;EACI,ONlaJ;EMmaI;EACA;;AAGJ;EACI,ONlaJ;EMmaI;EACA;;;AAKnB;AACA;EACC;;;AFpGF;AAAA;AAEI;EACI;EACA;;;AAGR;AAAA;AAEI;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGR;AAAA;AAEA;AAAA;EAEI;EACA;;;AAEJ;EACI;;;AAIJ;EAA4E;;;AAC5E;EAA4E","file":"deltagreen.css"}
\ No newline at end of file
diff --git a/Delta Green 2/deltagreen.html b/Delta Green 2/deltagreen.html
index 9581d124a2..f9e1032412 100644
--- a/Delta Green 2/deltagreen.html
+++ b/Delta Green 2/deltagreen.html
@@ -11,6 +11,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
GM Whisper
@@ -195,7 +238,7 @@
k
-
+
@@ -1057,10 +1100,16 @@
-
Check a box when you attempt to use a skill and fail. After the session, add 1d4 to each checked skill and erase all checks.
+
@@ -1151,7 +1200,7 @@
k
-
+
@@ -3643,6 +3692,7 @@ on('sheet:opened change:repeating_skills remove:repeating_skills', () => {
});
});
+
// levelup character
on("clicked:levelup", () =>{
let update={};
@@ -3650,32 +3700,61 @@ on("clicked:levelup", () =>{
let len=copyarray.length; // length of the original copyarray
let getarray=[]; // used only to update the values
let summary={}; // information in the log for the users
- let var_rnd=0; // random variable of 1d4-1
- //console.dir(copyarray);
+ let var_rnd=0; // random variable of 1d4
+ let block_to_insert ;
+ let container_block ;
+ let newrowid;
+ let newrowattrs = {};
+ let oldval=0;
+ let newval=0;
+ let name;
+
+ //console.dir(copyarray);
//getSectionIDs('repeating_skills', (idarray) => {
// for (i=0;i
{
+ console.dir(copyarray);
+ getSectionIDs("repeating_summary", function(idarray) {
+ for(var i=0; i < idarray.length; i++) {
+ removeRepeatingRow("repeating_summary_" + idarray[i]);
+ }
+ });
+
+
+ copyarray.forEach((sk,idx)=>{
//console.log(idx);
if (idx{
+ getAttrs([`${sk}`,`${sk}_name`,`${sk}_fail`],(val)=>{
getarray.push(`${sk}`);
//console.log(val[`${sk}_fail`]);
// console.log(`${sk}`);
if (val[`${sk}_fail`]=='on'){ //if the checkbox is checked
- var_rnd=Math.ceil(Math.random() * 4); // generate a random number for each checked value (less number generated)
+ var_rnd=Math.ceil(Math.random() * 4); // generate a random number for each checked value (less number generated)
//console.log(`${idx}`);
+ oldval=(parseInt(val[`${sk}`])||0);
+ newval=oldval+var_rnd;
+ name=val[`${sk}_name`];
summary[`${sk}`]=var_rnd; // how much the skill has changed 0-3
- update[`${sk}`]=(parseInt(val[`${sk}`])||0)+var_rnd; // new value of the skill
+ update[`${sk}`]=newval; // new value of the skill
update[`${sk}_fail`]='off'; // uncheck checkbox
+
+ //block_to_insert = document.createElement( 'div' );
+ //block_to_insert.innerHTML = 'This demo DIV block was inserted into the page using JavaScript.' ;
+
+ //container_block = document.getElementById( 'summary' );
+ //container_block.appendChild( block_to_insert );
+ newrowid = generateRowID();
+ newrowattrs['repeating_summary_' + newrowid + '_skillname'] = name;
+ newrowattrs['repeating_summary_' + newrowid + '_oldval'] = oldval;
+ newrowattrs['repeating_summary_' + newrowid + '_newval'] = newval;
+
}
});
} else { // if the idx>=len it means I an in the repeating skill array part
- getAttrs([`${sk}_rank`,`${sk}_fail`],(val)=>{
+ getAttrs([`${sk}_name`,`${sk}_rank`,`${sk}_fail`],(val)=>{
getarray.push(`${sk}_rank`);
//console.log(val[`${sk}_fail`]);
// console.log(`${sk}`);
@@ -3683,17 +3762,29 @@ on("clicked:levelup", () =>{
var_rnd=Math.ceil(Math.random() * 4); // generate a random number for each checked value (less number generated)
//console.log(`${idx}`);
summary[`${idx-len}_rank`]=var_rnd; // since the repeating skill don't have a name, they are identified by number 0-N
- update[`${sk}_rank`]=(parseInt(val[`${sk}_rank`])||0)+var_rnd;
+ //
+ oldval=(parseInt(val[`${sk}_rank`])||0);
+ newval=oldval+var_rnd;
+ name=val[`${sk}_name`];
+ //
+ update[`${sk}_rank`]=(parseInt(val[`${sk}_rank`])||0)+var_rnd;
update[`${sk}_fail`]='off';
+ newrowid = generateRowID();
+ newrowattrs['repeating_summary_' + newrowid + '_skillname'] = name;
+ newrowattrs['repeating_summary_' + newrowid + '_oldval'] = oldval;
+ newrowattrs['repeating_summary_' + newrowid + '_newval'] = newval;
}
});
}
});
//console.log(getarray);
+ console.log(newrowattrs); // summary in console for the user
+ //setAttrs(newrowattrs);
console.log(summary); // summary in console for the user
getAttrs(getarray,()=>{ // update fields
setAttributes(update,false);
+ setAttributes(newrowattrs,false);
});
//console.dir(update);
});
-
+
\ No newline at end of file
diff --git a/Delta Green 2/deltagreen.pug b/Delta Green 2/deltagreen.pug
index 801043b0cb..97f861815c 100644
--- a/Delta Green 2/deltagreen.pug
+++ b/Delta Green 2/deltagreen.pug
@@ -15,6 +15,51 @@ input.display_string(name='attr_toggles' type='hidden' value='')
//TABS & LOGO
// =============================
+.datahide
+ input(data-i18n-value='accounting' name='attr_accounting_name' value='accounting')
+ input(data-i18n-value='alertness' name='attr_alertness_name' value='alertness')
+ input(data-i18n-value='anthropology' name='attr_anthropology_name' value='anthropology')
+ input(data-i18n-value='archeology' name='attr_archeology_name' value='archeology')
+ input(data-i18n-value='art' name='attr_art_name' value='art')
+ input(data-i18n-value='artillery' name='attr_artillery_name' value='artillery')
+ input(data-i18n-value='athletics' name='attr_athletics_name' value='athletics')
+ input(data-i18n-value='bureaucracy' name='attr_bureaucracy_name' value='bureaucracy')
+ input(data-i18n-value='computer science' name='attr_computer_science_name' value='computer science')
+ input(data-i18n-value='craft' name='attr_craft_name' value='craft')
+ input(data-i18n-value='criminology' name='attr_criminology_name' value='criminology')
+ input(data-i18n-value='demolitions' name='attr_demolitions_name' value='demolitions')
+ input(data-i18n-value='disguise' name='attr_disguise_name' value='disguise')
+ input(data-i18n-value='dodge' name='attr_dodge_name' value='dodge')
+ input(data-i18n-value='drive' name='attr_drive_name' value='drive')
+ input(data-i18n-value='firearms' name='attr_firearms_name' value='firearms')
+ input(data-i18n-value='first aid' name='attr_first_aid_name' value='first aid')
+ input(data-i18n-value='forensics' name='attr_forensics_name' value='forensics')
+ input(data-i18n-value='heavy machinery' name='attr_heavy_machinery_name' value='heavy machinery')
+ input(data-i18n-value='heavy weapons' name='attr_heavy_weapons_name' value='heavy weapons')
+ input(data-i18n-value='history' name='attr_history_name' value='history')
+ input(data-i18n-value='humint' name='attr_humint_name' value='humint')
+ input(data-i18n-value='law' name='attr_law_name' value='law')
+ input(data-i18n-value='medicine' name='attr_medicine_name' value='medicine')
+ input(data-i18n-value='melee weapons' name='attr_melee_weapons_name' value='melee weapons')
+ input(data-i18n-value='military science' name='attr_military_science_name' value='military science')
+ input(data-i18n-value='navigate' name='attr_navigate_name' value='navigate')
+ input(data-i18n-value='occult' name='attr_occult_name' value='occult')
+ input(data-i18n-value='persuade' name='attr_persuade_name' value='persuade')
+ input(data-i18n-value='pharmacy' name='attr_pharmacy_name' value='pharmacy')
+ input(data-i18n-value='pilot' name='attr_pilot_name' value='pilot')
+ input(data-i18n-value='psychotherapy' name='attr_psychotherapy_name' value='psychotherapy')
+ input(data-i18n-value='ride' name='attr_ride_name' value='ride')
+ input(data-i18n-value='science' name='attr_science_name' value='science')
+ input(data-i18n-value='search' name='attr_search_name' value='search')
+ input(data-i18n-value='sigint' name='attr_sigint_name' value='sigint')
+ input(data-i18n-value='stealth' name='attr_stealth_name' value='stealth')
+ input(data-i18n-value='surgery' name='attr_surgery_name' value='surgery')
+ input(data-i18n-value='survival' name='attr_survival_name' value='survival')
+ input(data-i18n-value='swim' name='attr_swim_name' value='swim')
+ input(data-i18n-value='unarmed combat' name='attr_unarmed_combat_name' value='unarmed combat')
+
+
+
.tabs.grid
// Buttons to toggle on GM whisper
span(data-i18n-title='GM Whisper') GM Whisper
@@ -165,7 +210,7 @@ include src/pug/_objects.pug
button.dicefontd10(name='weapon' type='roll' title='weapon roll' value=attackRollValue) k
button.none(name='roll_damage' type='roll' value='@{gm_toggle} &{template:damage} {{header=@{weapons}}} {{subheader=@{damage}}} {{damage=[[@{damage}]]}} {{AP=[[@{armor_piercing}+0]]}}')
button.none(name='roll_lethality' type='roll' value='@{gm_toggle} &{template:lethality} {{header=@{weapons}}} {{subheader=@{lethality_percent}}}{{lethality_rating=[[@{lethality_percent}]]}} {{lethality=[[1d100]]}} {{AP=[[@{armor_piercing}+0]]}}')
- button.none(name='roll_damage_critical' type='roll' value='@{gm_toggle} &{template:damage} {{header=@{weapons}}} {{subheader=@{damage}}} {{damage=[[@{damage}*2]]}} {{AP=[[@{armor_piercing}+0]]}}')
+ button.none(name='roll_damage_critical' type='roll' value='@{gm_toggle} &{template:damage} {{header=@{weapons}}} {{subheader=@{damage}}} {{damage=[[(@{damage})*2]]}} {{AP=[[@{armor_piercing}+0]]}}')
button.none(name='roll_lethality_critical' type='roll' value='@{gm_toggle} &{template:lethality_critical} {{header=@{weapons}}} {{subheader=@{lethality_percent}}} {{lethality_rating=[[@{lethality_percent}*2]]}} {{lethality=[[1d100]]}} {{AP=[[@{armor_piercing}+0]]}}')
h1(data-i18n='other notes') other notes
diff --git a/Delta Green 2/src/pug/_pc.pug b/Delta Green 2/src/pug/_pc.pug
index 2c88a1e65b..f8860c096d 100644
--- a/Delta Green 2/src/pug/_pc.pug
+++ b/Delta Green 2/src/pug/_pc.pug
@@ -161,11 +161,19 @@
.vert-line
label(data-i18n-title='skill rank' title='skill rank')
input(data-i18n-placeholder='0' name='attr_rank' title='@{repeating_skills_${x}_rank}' placeholder='0' type='number' value='')
- .section-directions.center
+ .section-directions.center.updateinfo
span(data-i18n='Check a box when you attempt to use a skill and fail. After the session, add 1d4 to each checked skill and erase all checks.') Check a box when you attempt to use a skill and fail. After the session, add 1d4 to each checked skill and erase all checks.
button(name='act_levelup' type='action')
h3.aligned-center(data-i18n='Update' data-i18n-title='Update')= Update
-
+ input(type='checkbox')
+ span
+ .summary
+ fieldset.repeating_summary
+ .section-summary
+ span( name='attr_skillname')
+ span(style='color:red;' name='attr_oldval')
+ span.slash →
+ span(style='color:green;' name='attr_newval')
//INJURIES
.grid.header-body.injuries.border
.section-header
@@ -221,7 +229,7 @@
button.dicefontd10(name='weapon' type='roll' title='weapon roll' value=weaponRollValue) k
button.none(name='roll_damage' type='roll' value='@{gm_toggle} &{template:damage} {{header=@{weapons}}} {{subheader=@{damage}}} {{damage=[[@{damage}]]}} {{AP=[[@{armor_piercing}+0]]}}')
button.none(name='roll_lethality' type='roll' value='@{gm_toggle} &{template:lethality} {{header=@{weapons}}} {{subheader=@{lethality_percent}}}{{lethality_rating=[[@{lethality_percent}]]}} {{lethality=[[1d100]]}} {{AP=[[@{armor_piercing}+0]]}}')
- button.none(name='roll_damage_critical' type='roll' value='@{gm_toggle} &{template:damage} {{header=@{weapons}}} {{subheader=@{damage}}} {{damage=[[@{damage}*2]]}} {{AP=[[@{armor_piercing}+0]]}}')
+ button.none(name='roll_damage_critical' type='roll' value='@{gm_toggle} &{template:damage} {{header=@{weapons}}} {{subheader=@{damage}}} {{damage=[[(@{damage})*2]]}} {{AP=[[@{armor_piercing}+0]]}}')
button.none(name='roll_lethality_critical' type='roll' value='@{gm_toggle} &{template:lethality_critical} {{header=@{weapons}}} {{subheader=@{lethality_percent}}} {{lethality_rating=[[@{lethality_percent}*2]]}} {{lethality=[[1d100]]}} {{AP=[[@{armor_piercing}+0]]}}')
//REMARKS
diff --git a/Delta Green 2/src/pug/sheetworkers.js b/Delta Green 2/src/pug/sheetworkers.js
index fa4a4547e6..8a0ebe32cf 100644
--- a/Delta Green 2/src/pug/sheetworkers.js
+++ b/Delta Green 2/src/pug/sheetworkers.js
@@ -304,6 +304,7 @@ on('sheet:opened change:repeating_skills remove:repeating_skills', () => {
});
});
+
// levelup character
on("clicked:levelup", () =>{
let update={};
@@ -311,51 +312,90 @@ on("clicked:levelup", () =>{
let len=copyarray.length; // length of the original copyarray
let getarray=[]; // used only to update the values
let summary={}; // information in the log for the users
- let var_rnd=0; // random variable of 1d4-1
- //console.dir(copyarray);
+ let var_rnd=0; // random variable of 1d4
+ let block_to_insert ;
+ let container_block ;
+ let newrowid;
+ let newrowattrs = {};
+ let oldval=0;
+ let newval=0;
+ let name;
+
+ //console.dir(copyarray);
//getSectionIDs('repeating_skills', (idarray) => {
// for (i=0;i{
+ console.dir(copyarray);
+ getSectionIDs("repeating_summary", function(idarray) {
+ for(var i=0; i < idarray.length; i++) {
+ removeRepeatingRow("repeating_summary_" + idarray[i]);
+ }
+ });
+
+
+ copyarray.forEach((sk,idx)=>{
//console.log(idx);
if (idx{
+ getAttrs([`${sk}`,`${sk}_name`,`${sk}_fail`],(val)=>{
getarray.push(`${sk}`);
//console.log(val[`${sk}_fail`]);
// console.log(`${sk}`);
if (val[`${sk}_fail`]=='on'){ //if the checkbox is checked
- //var_rnd=Math.floor(Math.random() * 4); // generate a random number for each checked value (less number generated)
- var_rnd=Math.ceil(Math.random() * 4); // generate a random number for each checked value (less number generated)
+ var_rnd=Math.ceil(Math.random() * 4); // generate a random number for each checked value (less number generated)
//console.log(`${idx}`);
+ oldval=(parseInt(val[`${sk}`])||0);
+ newval=oldval+var_rnd;
+ name=val[`${sk}_name`];
summary[`${sk}`]=var_rnd; // how much the skill has changed 0-3
- update[`${sk}`]=(parseInt(val[`${sk}`])||0)+var_rnd; // new value of the skill
+ update[`${sk}`]=newval; // new value of the skill
update[`${sk}_fail`]='off'; // uncheck checkbox
+
+ //block_to_insert = document.createElement( 'div' );
+ //block_to_insert.innerHTML = 'This demo DIV block was inserted into the page using JavaScript.' ;
+
+ //container_block = document.getElementById( 'summary' );
+ //container_block.appendChild( block_to_insert );
+ newrowid = generateRowID();
+ newrowattrs['repeating_summary_' + newrowid + '_skillname'] = name;
+ newrowattrs['repeating_summary_' + newrowid + '_oldval'] = oldval;
+ newrowattrs['repeating_summary_' + newrowid + '_newval'] = newval;
+
}
});
} else { // if the idx>=len it means I an in the repeating skill array part
- getAttrs([`${sk}_rank`,`${sk}_fail`],(val)=>{
+ getAttrs([`${sk}_name`,`${sk}_rank`,`${sk}_fail`],(val)=>{
getarray.push(`${sk}_rank`);
//console.log(val[`${sk}_fail`]);
// console.log(`${sk}`);
if (val[`${sk}_fail`]=='on'){
- //var_rnd=Math.floor(Math.random() * 4); // generate a random number for each checked value (less number generated)
var_rnd=Math.ceil(Math.random() * 4); // generate a random number for each checked value (less number generated)
//console.log(`${idx}`);
summary[`${idx-len}_rank`]=var_rnd; // since the repeating skill don't have a name, they are identified by number 0-N
- update[`${sk}_rank`]=(parseInt(val[`${sk}_rank`])||0)+var_rnd;
+ //
+ oldval=(parseInt(val[`${sk}_rank`])||0);
+ newval=oldval+var_rnd;
+ name=val[`${sk}_name`];
+ //
+ update[`${sk}_rank`]=(parseInt(val[`${sk}_rank`])||0)+var_rnd;
update[`${sk}_fail`]='off';
+ newrowid = generateRowID();
+ newrowattrs['repeating_summary_' + newrowid + '_skillname'] = name;
+ newrowattrs['repeating_summary_' + newrowid + '_oldval'] = oldval;
+ newrowattrs['repeating_summary_' + newrowid + '_newval'] = newval;
}
});
}
});
//console.log(getarray);
+ console.log(newrowattrs); // summary in console for the user
+ //setAttrs(newrowattrs);
console.log(summary); // summary in console for the user
getAttrs(getarray,()=>{ // update fields
setAttributes(update,false);
+ setAttributes(newrowattrs,false);
});
//console.dir(update);
-});
+});
\ No newline at end of file
diff --git a/Delta Green 2/src/scss/_pc.scss b/Delta Green 2/src/scss/_pc.scss
index 4415ae2faa..71a6ca0497 100644
--- a/Delta Green 2/src/scss/_pc.scss
+++ b/Delta Green 2/src/scss/_pc.scss
@@ -1,3 +1,68 @@
+ /* SUMMARY UPDATE */
+
+ div.sheet-datahide{display:none;}
+ div[data-groupname='repeating_summary'].repcontrol{
+ display: none;
+ }
+ div.sheet-summary{
+ position:absolute;
+ bottom:40px;
+ right: 10px;
+ display:none;
+ z-index: 1000;
+ background: white;
+ border: 0.01em solid black;
+ width:30%;
+ min-height:20%;
+ overflow-y:scroll;
+
+ }
+ .sheet-section-summary{
+ grid-column-gap: 0.2em;
+ grid-row-gap: 0.2em;
+ grid-template-columns: 4fr 1fr 1fr 1fr;
+ display:grid;
+ justify-items: start;
+ }
+ div.sheet-updateinfo{
+ position: relative;
+ input[type='checkbox']{
+ opacity: 0;
+ width: 16px;
+ height: 16px;
+ position: relative;
+ top: 5px;
+ left: 6px;
+ margin: -10px;
+ cursor: pointer;
+ z-index: 1;
+ &+ span::before{
+ margin-right: 4px;
+ line-height: 14px;
+ text-align: center;
+ display: inline-block;
+ vertical-align: middle;
+ content: "?";
+ font-weight: bold;
+ color:black;
+ width: 14px;
+ height: 14px;
+ font-size: 12px;
+ }
+ &:checked ~ div.sheet-summary{
+ display:grid;
+ }
+ &:checked + span::before{
+ content: "?";
+ font-weight: bold;
+ color: gray;
+ }
+ }
+ }
+
+
+ /* MAIN SHEET */
+
div.sheet-pc {
grid-column-gap: 0.2em;
grid-row-gap: 0.2em;
diff --git a/Demon Gate Scripted/Circle.png b/Demon Gate Scripted/Circle.png
new file mode 100644
index 0000000000..b850d1114b
Binary files /dev/null and b/Demon Gate Scripted/Circle.png differ
diff --git a/Demon Gate Scripted/DemonGateLogo.png b/Demon Gate Scripted/DemonGateLogo.png
new file mode 100644
index 0000000000..1959fd2f9a
Binary files /dev/null and b/Demon Gate Scripted/DemonGateLogo.png differ
diff --git a/Demon Gate Scripted/Demon_Gate_Scripted.css b/Demon Gate Scripted/Demon_Gate_Scripted.css
index fe839ce8db..cd03358816 100644
--- a/Demon Gate Scripted/Demon_Gate_Scripted.css
+++ b/Demon Gate Scripted/Demon_Gate_Scripted.css
@@ -1,257 +1,206 @@
-input[type=number]
-{
- -moz-appearance: textfield;
+input[type=number] {
+ -moz-appearance: textfield;
}
-.charsheet
-{
- background: url("https://media.discordapp.net/attachments/657398293906718751/702758048615235635/old-2012064.jpg");
+.charsheet {
+ background: url("https://raw.githubusercontent.com/Roll20/roll20-character-sheets/master/Demon%20Gate%20Scripted/Paper.jpg");
}
-.charsheet td.sheet-imgbg
-{
- background: url("https://media.discordapp.net/attachments/670160303626911764/723246241055506500/Circle.png");
- background-repeat: no-repeat;
- background-size: contain;
- background-position: center;
-}
-
-.charsheet td.sheet-tabletitle
-{
- font-size: 1.5em;
- color: #ffffff;
- text-align: center;
- background-color: #948a54;
-}
-
-.charsheet td.sheet-tabletitlesmall
-{
- font-size: 1em;
- font-weight: bold;
- text-align: center;
- background-color: #c4bc96;
-}
-
-.charsheet td.sheet-attname
-{
- font-weight: bold;
+.charsheet td.sheet-attname {
+ font-weight: bold;
text-align: left;
background-color: #ddd9c3;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
padding-left: 8px;
}
-.charsheet td.sheet-skillname
-{
- font-size: 0.7em;
- font-weight: bold;
- text-align: left;
+.charsheet td.sheet-skillname {
background-color: #ddd9c3;
+ font-size: 0.9em;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
padding-left: 8px;
+ padding-right: 8px;
}
-.charsheet td.sheet-smallname
-{
- font-size: 0.7em;
- font-weight: bold;
+.charsheet td.sheet-smallname {
+ font-weight: bold;
text-align: center;
- background-color: #ffffff;
- border-style: solid;
- border-color: #948a54;
- border-width: 1px;
+ border: 0;
+ border-radius: 0;
}
-.charsheet td.sheet-skillhead
-{
- font-size: 0.7em;
- font-weight: bold;
+.charsheet td.sheet-skillhead {
+ font-size: 0.7em;
+ font-weight: bold;
text-align: center;
background-color: #ddd9c3;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
}
-.charsheet td.sheet-skillstat
-{
+.charsheet td.sheet-skillstat {
text-align: center;
- background-color: #ffffff;
- border-style: solid;
- border-color: #948a54;
+ border-style: solid;
+ border-color: #c4bc96;
border-width: 1px;
}
-.charsheet select.sheet-skilldesc
-{
- font-size: 0.7em;
- width: 5em;
- height: 2.2em;
+.charsheet select.sheet-skilldesc {
+ font-size: 0.7em;
+ width: 5em;
+ height: 2.2em;
}
-.charsheet select.sheet-skilldesclong
-{
- font-size: 0.7em;
- width: 8em;
- height: 2.2em;
+.charsheet select.sheet-skilldesclong {
+ width: 6em;
+ margin: 0;
+ border: 0;
+ border-radius: 0;
}
-.charsheet select.sheet-skilldesclonger
-{
- font-size: 0.7em;
- width: 12em;
- height: 2.2em;
+.charsheet select.sheet-skilldesclonger {
+ font-size: 0.7em;
+ width: 12em;
+ height: 2.2em;
}
-.charsheet td.sheet-attstat
-{
+.charsheet td.sheet-attstat {
background-color: #ddd9c3;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
}
-.charsheet td.sheet-attstatsmall
-{
- font-size: 0.7em;
- font-weight: bold;
+.charsheet td.sheet-attstatsmall {
+ font-size: 0.7em;
+ font-weight: bold;
background-color: #ddd9c3;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
}
-.charsheet td.sheet-descname
-{
+.charsheet td.sheet-descname {
text-align: left;
background-color: #ffffff;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
padding-left: 20px;
}
-.charsheet td.sheet-descstat
-{
+.charsheet td.sheet-descstat,
+.charsheet td.sheet-descstat-narrow {
background-color: #ffffff;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
}
-.charsheet td.sheet-descstatsmall
-{
- font-size: 0.7em;
+.charsheet td.sheet-descstatsmall {
+ font-size: 0.7em;
background-color: #ffffff;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
}
-.charsheet input.sheet-attfield
-{
+.charsheet input.sheet-attfield {
font-size: 1em;
width: 2em;
text-align: center;
}
-.charsheet input.sheet-skillfield
-{
+.charsheet input.sheet-skillfield {
width: 2em;
text-align: center;
}
-.charsheet input.sheet-negfield
-{
+.charsheet input[type="number"].sheet-desctotalfield {
font-size: 1em;
width: 2em;
text-align: center;
font-weight: bold;
- background-color: #0f0f0f;
- color: #ffffff;
+ font-size: 16px;
+ color: dimgray;
+ background-color: #e0e0e0;
+ border: 0;
+ border-radius: 0;
}
-.charsheet input.sheet-desctotalfield
-{
- font-size: 1em;
- width: 2em;
+.charsheet input[type="number"].sheet-totalfield,
+.charsheet input[type="text"].sheet-totalfield {
text-align: center;
font-weight: bold;
- color: red;
- background-color: #dddddd;
+ font-size: 16px;
+ height: 30px;
+ color: dimgray;
+ background-color: #e0e0e0;
+ border: 0;
+ border-radius: 0;
+ width: 100%;
}
-.charsheet input.sheet-skilltotalfield
-{
- width: 2em;
- text-align: center;
- font-weight: bold;
- color: red;
- background-color: #dddddd;
-}
-
-.charsheet input.sheet-attrankfield
-{
+.charsheet input.sheet-attrankfield {
font-size: 1em;
width: 2em;
text-align: center;
font-weight: bold;
color: blue;
- background-color: #dddddd;
+ background-color: #e0e0e0;
}
-.charsheet input.sheet-longtext
-{
+.charsheet input.sheet-longtext {
width: 12em;
text-align: center;
}
-.charsheet input.sheet-autofield
-{
+.charsheet input.sheet-autofield,
+.charsheet input.sheet-autofield-wide{
font-size: 1em;
- width: 2em;
text-align: center;
font-weight: bold;
- background-color: #dddddd;
+ background-color: #e0e0e0;
}
-.charsheet input.sheet-autofieldsmall
-{
+.charsheet input.sheet-autofield {
+ width: 2em;
+}
+
+.charsheet input.sheet-autofieldsmall {
font-size: 0.7em;
width: 2em;
text-align: center;
font-weight: bold;
- background-color: #dddddd;
+ background-color: #e0e0e0;
}
-.charsheet textarea.sheet-smalltextarea
-{
- font-size:0.7em;
- width: 40em;
- height: 2.5em;
+.charsheet textarea.sheet-smalltextarea {
+ font-size: 0.7em;
+ width: 40em;
+ height: 2.5em;
}
-.charsheet td.sheet-descstat1
-{
+.charsheet td.sheet-descstat1 {
background-color: #ffffff;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
}
-.charsheet td.sheet-skillstat1
-{
+.charsheet td.sheet-skillstat1 {
text-align: center;
background-color: #ffffff;
border-style: solid;
- border-color: #948a54;
+ border-color: #c4bc96;
border-width: 1px;
}
@@ -274,97 +223,71 @@ input[type=number]
-.charsheet input.sheet-short
-{
- font-size: 1.5em;
+.charsheet input.sheet-short {
+ font-size: 1.5em;
text-align: center;
}
-.charsheet input.sheet-long
-{
+.charsheet input.sheet-long {
width: 10em;
text-align: center;
}
-.charsheet input.sheet-gpxpfield
-{
+.charsheet input.sheet-gpxpfield {
font-weight: bold;
width: 6em;
text-align: center;
}
-.charsheet input.sheet-atkfield
-{
+.charsheet input.sheet-atkfield {
font-size: 0.6em;
text-align: center;
}
-.charsheet tr.sheet-blankrow
-{
+.charsheet tr.sheet-blankrow {
height: 20px !important;
}
-.charsheet tr.sheet-blankrowsmall
-{
- height: 2px !important;
-}
-
-.charsheet td.sheet-blankcol
-{
+.charsheet td.sheet-blankcol {
width: 20px !important;
}
-.charsheet td.sheet-blankcols
-{
+.charsheet td.sheet-blankcols {
width: 100px !important;
}
-.charsheet td.sheet-smaller
-{
+.charsheet td.sheet-smaller {
font-size: 0.8em;
}
-.charsheet td.sheet-shrink
-{
+.charsheet td.sheet-shrink {
font-size: 0.5em;
text-align: center;
}
-.charsheet td.sheet-header
-{
- font-size: 2em;
- text-align: center;
- font-weight: bold;
-}
-
-.charsheet input.sheet-atktotalfield
-{
+.charsheet input.sheet-atktotalfield {
font-size: 0.6em;
text-align: center;
color: red
}
-.charsheet table.sheet-large
-{
+.charsheet table.sheet-large {
font-size: 1.5em;
}
-.charsheet table.sheet-adjfield
-{
+.charsheet table.sheet-adjfield {
font-size: 1em;
font-weight: bold;
text-align: center;
}
-.charsheet input.sheet-adjvalue
-{
+.charsheet input.sheet-adjvalue {
font-size: 1em;
font-weight: bold;
text-align: center;
}
-.charsheet input.sheet-adjvalueblue
-{
+.charsheet input.sheet-adjvalueblue {
font-size: 1em;
font-weight: bold;
text-align: center;
@@ -372,116 +295,691 @@ input[type=number]
background-color: gray;
}
-.charsheet input.sheet-redadjvalue
-{
+.charsheet input.sheet-redadjvalue {
font-size: 1em;
font-weight: bold;
text-align: center;
color: red;
}
-.charsheet input.sheet-adjvaluetotal
-{
+.charsheet input.sheet-adjvaluetotal {
font-size: 1em;
font-weight: bold;
text-align: center;
color: red;
}
-.charsheet textarea.sheet-knowdesc
-{
- font-size:0.8em;
- width: 50em;
- height: 1.7em;
+.charsheet textarea.sheet-knowdesc {
+ font-size: 0.8em;
+ width: 50em;
+ height: 1.7em;
}
-.charsheet textarea.sheet-skilldesc
-{
- font-size:0.8em;
- width: 25em;
- height: 5em;
+.charsheet textarea.sheet-skilldesc {
+ font-size: 0.8em;
+ width: 25em;
+ height: 5em;
}
-.charsheet textarea.sheet-spelldesc
-{
- font-size:0.8em;
- width: 30em;
- height: 3em;
+.charsheet textarea.sheet-spelldesc {
+ font-size: 0.8em;
+ width: 30em;
+ height: 3em;
}
-.charsheet button.sheet-valuebutton:before
-{
- content: "" !important;
+.charsheet button.sheet-valuebutton:before {
+ content: "" !important;
}
-.charsheet button.sheet-valuebutton
-{
- border: none;
- padding: 0px;
- font-weight: bold;
+.charsheet button.sheet-valuebutton {
+ border: none;
+ padding: 0px;
+ font-weight: bold;
}
.charsheet input[type=number]::-webkit-inner-spin-button,
-.charsheet input[type=number]::-webkit-outer-spin-button
-{
- -webkit-appearance: none;
- margin: 0;
+.charsheet input[type=number]::-webkit-outer-spin-button {
+ -webkit-appearance: none;
+ margin: 0;
}
-.charsheet div[class^="sheet-section"]
-{
+.charsheet div[class^="sheet-section"] {
display: none;
}
-.charsheet input.sheet-tab
-{
- width: 100px;
- height: 40px;
- cursor: pointer;
+
+
+
+/* ************************************************************************************************************************************************ */
+/* Colours */
+/* ************************************************************************************************************************************************ */
+/*
+#948a54 (mid brown) - table borders, headings of older parts of the sheet
+#ddd9c3 (beige) - header cells, active tab button
+#b6ad7c (darker beige) - inactive tab buttons
+#f6f5ef (pale beige) - input control backgrounds
+#e0e0e0 (light grey) - read-only cell background
+
+#c4bc96 (slightly darker beige) - tab button borders
+*/
+
+
+/* ************************************************************************************************************************************************ */
+/* Headings */
+/* ************************************************************************************************************************************************ */
+
+h1, h2, h3 {
+ width: 100%;
+ text-align: center;
+}
+
+h2, h3 {
+ color: maroon;
+ background-color: #ddd9c3;
+ font-weight: normal;
+ font-size: 16px;
+ height: 28px;
+ line-height: 28px;
+}
+
+h1 {
+ height: 40px;
+ line-height: 40px;
+ color: #ddd9c3;
+ background-color: #590902;
+ border: 2px solid #590902;
+ border-radius: 4px;
+ font-size: 20px;
+}
+
+h2 {
+ padding-top: 2px;
+ padding-bottom: 2px;
+}
+
+h3 {
+ text-align: left;
+}
+
+
+/* ************************************************************************************************************************************************ */
+/* Entry controls */
+/* ************************************************************************************************************************************************ */
+input,
+select,
+textarea,
+.sheet-input-like,
+.sheet-input-like-no-padding {
+ background-color: #f6f5ef;
+}
+
+.sheet-input-like {
+ padding-left: 4px;
+}
+
+.sheet-read-only-field,
+td input:read-only {
+ color: lightslategray;
+ background-color: #e0e0e0;
+}
+
+button.sheet-button,
+button.btn {
+ border: 2px solid maroon;
+ border-radius: 4px;
+ color: maroon;
+ text-shadow: none;
+}
+
+button.sheet-button {
+ background: transparent;
+}
+
+button.btn {
+ background: #ddd9c3;
+}
+
+
+button.sheet-button[type=roll]:before {
+ content: "";
+}
+
+button.sheet-button-small {
+ height: 20px;
+}
+
+button.sheet-button-small[type=roll] {
+ font-size: 11px;
+}
+
+.sheet-tall-control,
+input.sheet-tall-control {
+ height: 36px;
+ line-height: 36px;
+ font-size: 16px;
+}
+
+/* ************************************************************************************************************************************************ */
+/* Expand/collapse (custom checkbox plus hiding a section)*/
+/* ************************************************************************************************************************************************ */
+
+/* Hide the browser's default checkbox */
+input.sheet-expand-collapse-checkbox {
+ position: absolute;
+ opacity: 0;
+ cursor: pointer;
+ height: 18px;
+}
+
+/* Show the checkmark when checked */
+input.sheet-expand-collapse-checkbox:checked~.sheet-expand-collapse-symbol:after {
+ display: block;
+ content: "⯆";
+ font-size: 18px;
+}
+
+/* Style the checkmark/indicator */
+input.sheet-expand-collapse-checkbox~.sheet-expand-collapse-symbol:after {
+ display: block;
+ content: "⯈";
+ font-size: 18px;
+}
+
+input[type="checkbox"].sheet-expand-collapse-checkbox~.sheet-collapsible {
+ display: none;
+}
+
+input[type="checkbox"].sheet-expand-collapse-checkbox:checked~.sheet-collapsible {
+ display: block;
+}
+
+
+/* ************************************************************************************************************************************************ */
+/* Tab buttons */
+/* ************************************************************************************************************************************************ */
+
+.charsheet input.sheet-tab {
+ width: 90px;
+ height: 40px;
+ cursor: pointer;
position: relative;
opacity: 0;
z-index: 9999;
}
-.charsheet span.sheet-tab
-{
+.charsheet span.sheet-tab {
text-align: center;
- display: inline-block;
- font-size: 13px;
- background: #c4bc96;
- color: black;
- font-weight: bold;
+ display: inline-block;
+ font-size: 14px;
+ line-height: 28px;
+ color: maroon;
+ border: 2px solid maroon;
border-radius: 4px;
-
- width: 100px;
- height: 20px;
- cursor: pointer;
+ background: #b6ad7c;
+ width: 90px;
+ height: 28px;
+ cursor: pointer;
position: relative;
vertical-align: middle;
- margin-left: -101px;
+ margin-left: -91px;
}
-.charsheet input.sheet-tab1:checked ~ div.sheet-section-core,
-.charsheet input.sheet-tab2:checked ~ div.sheet-section-skills,
-.charsheet input.sheet-tab3:checked ~ div.sheet-section-combat,
-.charsheet input.sheet-tab4:checked ~ div.sheet-section-gear,
-.charsheet input.sheet-tab5:checked ~ div.sheet-section-mystic,
-.charsheet input.sheet-tab6:checked ~ div.sheet-section-abilities,
-.charsheet input.sheet-tab7:checked ~ div.sheet-section-reputation,
-{
+.charsheet input.sheet-tab1:checked~div.sheet-section-core,
+.charsheet input.sheet-tab2:checked~div.sheet-section-skills,
+.charsheet input.sheet-tab3:checked~div.sheet-section-combat,
+.charsheet input.sheet-tab4:checked~div.sheet-section-gear,
+.charsheet input.sheet-tab5:checked~div.sheet-section-mystic,
+.charsheet input.sheet-tab6:checked~div.sheet-section-abilities,
+.charsheet input.sheet-tab7:checked~div.sheet-section-reputation,
+.charsheet input.sheet-tab8:checked~div.sheet-section-notes {
display: block;
}
-.charsheet input.sheet-tab1:checked + span.sheet-tab1,
-.charsheet input.sheet-tab2:checked + span.sheet-tab2,
-.charsheet input.sheet-tab3:checked + span.sheet-tab3,
-.charsheet input.sheet-tab4:checked + span.sheet-tab4,
-.charsheet input.sheet-tab5:checked + span.sheet-tab5,
-.charsheet input.sheet-tab6:checked + span.sheet-tab6,
-.charsheet input.sheet-tab7:checked + span.sheet-tab7
+.charsheet input.sheet-tab:checked+span {
+ background: #ddd9c3;
+}
+
+
+/* ************************************************************************************************************************************************ */
+/* Flexbox columns */
+/* ************************************************************************************************************************************************ */
+.sheet-flex-section {
+ margin-top: 20px;
+ margin-left: -10px;
+ margin-right: -10px;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-between;
+}
+
+.sheet-column-fixed {
+ flex-grow: 0;
+ margin: 10px;
+}
+
+.sheet-column-grow {
+ flex-grow: 1;
+ margin: 10px;
+}
+
+.sheet-column-prominent-stat {
+ flex-grow: 0;
+ width: 120px;
+ margin: 10px;
+}
+
+.sheet-flex-form-container {
+ display: flex;
+ flex-wrap: nowrap;
+ justify-content: space-between;
+}
+
+.sheet-flex-form-grow {
+ flex-grow: 1;
+}
+
+.sheet-flex-form-fixed {
+ flex-grow: 0;
+ padding-left: 2px;
+ padding-right: 2px;
+}
+
+
+/* ************************************************************************************************************************************************ */
+/* Tables */
+/* ************************************************************************************************************************************************ */
+
+table.sheet-wide-table,
+table.sheet-wide-table-auto {
+ width: 100%;
+ border: 2px solid #948a54;
+ background-color: #ddd9c3;
+}
+
+table.sheet-wide-table-auto {
+ table-layout: auto;
+}
+
+
+
+/* ************************************************************************************************************************************************ */
+/* Top section of first sheet */
+/* ************************************************************************************************************************************************ */
+.sheet-demon-gate-logo {
+ height: 116px;
+}
+
+.sheet-column-prominent-stat td input[type=number] {
+ width: 100%;
+ text-align: center;
+}
+
+.sheet-wide-table th,
+.sheet-wide-table-auto th {
+ padding-left: 10px;
+ padding-right: 10px;
+ max-width: max-content;
+ white-space: nowrap;
+ font-size: 11px;
+ font-weight: bold;
+ color: dimgray;
+ background-color: #ddd9c3;
+}
+
+.sheet-wide-table th,
+.sheet-wide-table td,
+.sheet-wide-table-auto th,
+.sheet-wide-table-auto td {
+ border: 1px solid #c4bc96;
+}
+
+.sheet-wide-table-auto th,
+.sheet-wide-table-auto td {
+ height: 28px;
+}
+
+.sheet-wide-table input,
+.sheet-wide-table select,
+.sheet-wide-table-auto input,
+.sheet-wide-table-auto select {
+ margin: 0;
+}
+
+.sheet-input-wide {
+ min-width: 12em;
+}
+
+.sheet-wide-table td input[type=number],
+.sheet-wide-table td input[type=text],
+.sheet-wide-table-auto td input[type=number],
+.sheet-wide-table-auto td input[type=text],
+.sheet-input-full {
+ width: 100%;
+ border: 0;
+ border-radius: 0;
+}
+
+.sheet-wide-table-auto td input {
+ height: 28px;
+ line-height: 28px;
+}
+
+.sheet-wide-table td input[type=number],
+.sheet-wide-table-auto td input[type=number] {
+ min-width: 2.2em;
+ text-align: center;
+}
+
+.sheet-empty-cell {
+ background-color: #ddd9c3;
+}
+
+.sheet-input-narrow {
+ width: 5em;
+ min-width: 5em;
+ max-width: 5em;
+}
+
+.sheet-input-like-no-padding input.sheet-input-narrow{
+ max-width: 7.5em;
+}
+
+.sheet-wide-table-auto td input.sheet-prominent-label,
+.sheet-wide-table-auto td input.sheet-prominent-field {
+ height: 56px;
+}
+
+td input[type=text].sheet-dice-field
{
- background: #948a54;
- color: black;
- border-radius: 4px;
- height: 20px;
+ min-width: 12em;
+ text-align: center;
+}
+
+td input[type=text].sheet-text-centred
+{
+ text-align: center;
+}
+
+td input.sheet-prominent-field {
+ font-size: 20px;
+ text-align: center;
+}
+
+.sheet-vertical-margin {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+
+.sheet-vertical-margin-moderate {
+ margin-top: 20px;
+ margin-bottom: 20px;
+}
+
+.sheet-wide-table-auto td input.sheet-input-split {
+ width: 40%;
+ min-width: 1.1em;
+}
+
+td .sheet-input-spacer {
+ min-width: 1.1em;
+ text-align: center;
+}
+
+
+/* ************************************************************************************************************************************************ */
+/* HP, Mana etc. */
+.sheet-flex-section-centre {
+ margin-left: -10px;
+ margin-right: -10px;
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: space-around;
+}
+
+.sheet-wide-table-auto td input.sheet-extra-prominent-field {
+ font-size: 36px;
+ height: 84px;
+ text-align: center;
+}
+
+td.sheet-small-text {
+ font-size: 0.7em;
+ text-align: center;
+ background-color: #f6f5ef;
+}
+
+th.sheet-small-text {
+ font-size: 0.8em;
+ font-weight: bold;
+ text-align: center;
+ background-color: #ddd9c3;
+}
+
+td.sheet-cell-narrow {
+ max-width: 50px;
+}
+
+/* ************************************************************************************************************************************************ */
+/** Gradient colours for physical and mental conditions */
+
+tr td.sheet-physical-condition-0,
+tr td.sheet-mental-condition-0 {
+ background-color: white;
+}
+
+tr td.sheet-physical-condition-1 {
+ background-color: #ffcccc;
+}
+
+tr td.sheet-physical-condition-2 {
+ background-color: #ff9999;
+}
+
+tr td.sheet-physical-condition-3 {
+ background-color: #ff6666;
+}
+
+tr td.sheet-physical-condition-4 {
+ background-color: #ff3333;
+}
+
+tr td.sheet-physical-condition-5 {
+ background-color: #cc0000;
+}
+
+tr td.sheet-physical-condition-6 {
+ background-color: #800000;
+}
+
+tr td.sheet-mental-condition-1 {
+ background-color: #cce0ff;
+}
+
+tr td.sheet-mental-condition-2 {
+ background-color: #80b3ff;
+}
+
+tr td.sheet-mental-condition-3 {
+ background-color: #4d94ff;
+}
+
+tr td.sheet-mental-condition-4 {
+ background-color: #0066ff;
+}
+
+tr td.sheet-mental-condition-5 {
+ background-color: #0047b3;
+}
+
+tr td.sheet-mental-condition-6 {
+ background-color: #003380;
+}
+
+/* ************************************************************************************************************************************************ */
+/* Skills tab
+/* ************************************************************************************************************************************************ */
+
+.sheet-top-margin {
+ margin-top: 40px;
+}
+
+/* Designed to spill over on to the expand/collapse element below */
+.sheet-table-header-collapse {
+ height: 5px;
+ line-height: 28px;
+ margin-top: 20px;
+ padding: 0;
+}
+
+.sheet-collapsible table {
+ width: 100%;
+ border: 2px solid #948a54;
+}
+
+th.sheet-skillhead {
+ height: auto;
+}
+
+input.sheet-skillfield,
+input.sheet-skillname-input {
+ border: 0;
+ border-radius: 0;
+}
+
+td.sheet-descstat-narrow input[type=number] {
+ min-width: 1em;
+ width: 100%;
+}
+
+td.sheet-descstat,
+td.sheet-descstat-narrow,
+input.sheet-skillname-input {
+ background-color: #f6f5ef;
+}
+
+td.sheet-skillstat {
+ background-color: #e0e0e0;
+ color: gray;
+}
+
+input.sheet-skillname-input {
+ width: 100%;
+ min-width: 10em;
+}
+
+.charsheet select.sheet-skilldescshort {
+ width: 4.2em;
+ margin: 0;
+ border: 0;
+ border-radius: 0;
+}
+
+
+/* ************************************************************************************************************************************************ */
+/* Abilities and notes tabs
+/* ************************************************************************************************************************************************ */
+.sheet-subsection-header,
+.sheet-subsection-header-wide {
+ width: 100%;
+ height: 36px;
+ line-height: 36px;
+ color: dimgray;
+ background-color: #ddd9c3;
+ text-align: center;
+ font-size: 16px;
+}
+
+.sheet-subsection-header-wide {
+ min-width: 15em;
+ border: 2px solid #c4c1b2;
+ margin-bottom: 5px;
+}
+
+textarea.sheet-text-area-full,
+textarea.sheet-text-area-large,
+textarea.sheet-standalone-textarea {
+ box-sizing: border-box;
+ resize: none;
+ width: 100%;
+ margin-bottom: 0;
+ margin-left: 0;
+ margin-right: 0;
+}
+
+textarea.sheet-text-area-full {
+ margin-left: 0;
+ margin-right: 0;
+ border-radius: 0;
+ height: 150px;
+}
+
+textarea.sheet-text-area-large {
+ margin-top: 0;
+ border: 0;
+ border-radius: 0;
+ height: 300px;
+}
+
+.sheet-repeating-section {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ background-color: #f6f5ef;
+ border: 2px solid #948a54;
+}
+
+/* This could probably be added to h2 (and maybe h1?) with a bit of reorg */
+.sheet-spacer-top-margin {
+ margin-top: 20px;
+}
+
+h1.sheet-spacer-top-margin {
+ margin-top: 40px;
+}
+
+.sheet-standalone-textarea {
+ margin-top: 20px;
+ border: 2px solid #948a54;
+ border-radius: 0;
+ height: 150px;
+}
+
+/* TODO: This is a hack - sorting out heading spacing properly and removing it from flex sections should allow this to be removed */
+.sheet-remove-margin-bottom {
+ margin-bottom: -10px;
+}
+
+
+
+/* ************************************************************************************************************************************************ */
+/* Mysic tab
+/* ************************************************************************************************************************************************ */
+
+.sheet-spiritual-influence-wrapper {
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+}
+
+.sheet-spiritual-influence-image {
+ background: url("https://raw.githubusercontent.com/Roll20/roll20-character-sheets/master/Demon%20Gate%20Scripted/Circle.png");
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center;
+ height: 271px;
+ width: 288px;
+ display: flex;
+ flex-flow: column nowrap;
+ align-items: center;
+ justify-content: center;
+}
+
+.sheet-spiritual-influence-image input.sheet-spiritual-influence {
+ width: 2.2em;
+ font-size: 18px;
+ text-align: center;
+ border-radius: 20px;
+ height: 40px;
+ line-height: 40px;
+ padding: 0;
+ border: 2px solid maroon;
}
diff --git a/Demon Gate Scripted/Demon_Gate_Scripted.html b/Demon Gate Scripted/Demon_Gate_Scripted.html
index 955d14db70..4abbc91be6 100644
--- a/Demon Gate Scripted/Demon_Gate_Scripted.html
+++ b/Demon Gate Scripted/Demon_Gate_Scripted.html
@@ -1,5 +1,4 @@
+
+
-
-
Attributes
-
-
Skills
-
-
Combat
-
-
Gear
-
-
Mystic
-
-
Abilities
-
-
Reputation
-
-
-
-
-
-
-
-
-
-
-
-
- Combat Skills
-
-
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Frenzy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Character Skills
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Character Skills
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+ Initiative
+
+
+
+ Initiative
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Weapons
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Armor
+
+
+
+
+
+
Valuables
+
+
+
+
+
+
+
+
Equipment
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
Equipment (Backpack)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Armor
-
-
- Slot
- Name
- SHP
- Cover
-
-
- Shield
-
-
-
-
-
-
-
-
-
- Slot
- Name
- Durability
- Armor Rating
-
-
- Helmet
-
-
-
-
-
-
-
-
- Amulet
-
-
-
-
-
-
-
-
- Cloak
-
-
-
-
-
-
-
-
- Pauldrons
-
-
-
-
-
-
-
-
- Clothing
-
-
-
-
-
-
-
-
- Torso
-
-
-
-
-
-
-
-
- Bracers
-
-
-
-
-
-
-
-
- Gloves
-
-
-
-
-
-
-
-
- Belt
-
-
-
-
-
-
-
-
- Greaves
-
-
-
-
-
-
-
-
- Boots
-
-
-
-
-
-
-
-
- Ring
-
-
-
-
-
-
-
-
- Ring
-
-
-
-
-
-
-
-
- Other
-
-
-
-
-
-
-
-
- Other
-
-
-
-
-
-
-
-
-
- Money
-
-
-
- Type
- Amount
-
-
-
- Mertacullum
-
-
-
-
-
- Gold Talons
-
-
-
-
-
- Silver (shillings)
-
-
-
-
-
- Copper (crets)
-
-
-
-
-
- Bones (bits)
-
-
-
-
-
- Misc / Other
-
-
-
-
-
-
- Equipment (Belt)
-
-
- Name
- Amount
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Equipment (Backpack)
-
-
-
+
+
+
-
-
-
- Transportation
-
-
-
+
+
+
+
+
+ Transportation
+
+
+
-
-
-
- Hideouts
-
-
-
+
+
+ Other
+
+ Hideouts
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Religion
+
+
+
+
+
+
+
Spiritual Influence
+
+
+
+
+
+
+
+
+ Roll Spiritual Influence
+
+
+
+
+
+
+
Spells
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Chi Abilities
-
-
- Name
- Rating
- Drain
- Description
-
-
-
-
-
-
-
-
- Alchemical Formulae
-
-
- Item
- Ingredients Necessary
- Units Harvested
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Traits
-
-
- Name
- Description
-
-
-
-
-
-
- Talents
-
-
- Name
- Description
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ Chi Abilities
+
+
+
+
+
+
+
+
+
+ Name
+ Rating
+ Drain
+ Description
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Alchemical Formulae
+
+
+
+
+
+
+
+
+
+ Item
+ Ingredients Necessary
+ Units Harvested
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Racial Abilities
+
+
+
+
+
+
+
+
+
+
+
+
Class Abilities
+
+
+
+
+
+
+
+
-
-
-
-
-
- Reputation
-
- Known Characters
-
-
-
-
-
- Total Rep Pts
-
-
-
-
-
- Honor
-
-
-
-
-
- Location
- Amt
-
-
-
-
-
-
-
-
-
-
- Glory
-
- %
-
-
-
- Corruption
-
-
-
-
-
- Location
- Amt
-
-
-
-
-
-
-
-
-
-
- Name
- Rank
-
-
-
-
-
-
-
+
+
+
+
+
+
Known Characters
+
+
+
+ Name
+ Rank
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Demon Gate Scripted/Paper.jpg b/Demon Gate Scripted/Paper.jpg
new file mode 100644
index 0000000000..e1fd212118
Binary files /dev/null and b/Demon Gate Scripted/Paper.jpg differ
diff --git a/Die_Schwarze_Katze/sheet.json b/Die_Schwarze_Katze/sheet.json
index 70ea5fdbeb..34f65fea46 100644
--- a/Die_Schwarze_Katze/sheet.json
+++ b/Die_Schwarze_Katze/sheet.json
@@ -1,8 +1,9 @@
{
- "html": "Die_Schwarze_Katze.html",
- "css": "Die_Schwarze_Katze.css",
- "authors": "Jakob Kneissl, Mira Singer",
- "roll20userid": "5972116",
- "preview": "Die_Schwarze_Katze_Preview.png",
- "instructions": "# Die Schwarze Katze Sheet v1.0.0 \r [Link zum Regelwerk](https://ulisses-spiele.de/spielsysteme/dsk/)"
-}
+ "html": "Die_Schwarze_Katze.html",
+ "css": "Die_Schwarze_Katze.css",
+ "authors": "Jakob Kneissl, Mira Singer",
+ "roll20userid": "5972116",
+ "preview": "Die_Schwarze_Katze_Preview.png",
+ "instructions": "# Die Schwarze Katze Sheet v1.0.0 \r [Link zum Regelwerk](https://ulisses-spiele.de/spielsysteme/dsk/)",
+ "legacy": true
+}
\ No newline at end of file
diff --git a/DnD_Original_DnD/translations/pl.json b/DnD_Original_DnD/translations/pl.json
index 834fdab67b..10856291a0 100644
--- a/DnD_Original_DnD/translations/pl.json
+++ b/DnD_Original_DnD/translations/pl.json
@@ -1,47 +1,47 @@
{
"name-u": "Nazwa",
"player-u": "Gracz",
- "race-u": "Race",
- "class-u": "Class",
+ "race-u": "Rasa",
+ "class-u": "Klasa",
"levelTitle-u": "(level title)",
"alignment-u": "Alignment",
"score-u": "Score",
- "bounusesAndPenalties-u": "Bonuses and Penalties",
- "ac-u": "AC",
+ "bounusesAndPenalties-u": "Premie i Kary",
+ "ac-u": "KP",
"level-u": "Poziom",
- "str-u": "Str.",
- "hp-u": "HP",
- "maxhp-u": "Max HP",
- "xp-u": "XP",
+ "str-u": "Sił.",
+ "hp-u": "PW",
+ "maxhp-u": "Max PW",
+ "xp-u": "PD",
"int-u": "Int.",
"hd-u": "HD",
"xpBonus-u": "XP +/-",
- "wis-u": "Wis.",
+ "wis-u": "Mdr.",
"fightingCapability-u": "Fighting Capability",
- "con-u": "Con.",
- "dex-u": "Dex.",
+ "con-u": "Kon.",
+ "dex-u": "Zr.",
"findSecretPassage-u": "Find Secret Passage",
- "chr-u": "Chr.",
+ "chr-u": "Cha.",
"openDoor-u": "Open Door",
- "listen-u": "Listen",
+ "listen-u": "Nasłuchiwanie",
"lowScoreAverageHigh-u": "(Low score is 3–8, Average is 9–12, High is 13–18)",
- "languages-u": "Languages",
- "saves-u": "Saves:",
+ "languages-u": "Języki",
+ "saves-u": "Rzuty obronne:",
"rayPoison-u": "Ray/Poison",
- "wand-u": "Wand",
+ "wand-u": "Różdżka",
"stone-u": "Stone",
"breath-u": "Breath",
"stavesSpells-u": "Staves/Spells",
"toHitAC-u": "To Hit AC:",
"misc-u": "Misc.:",
- "equipment-u": "Equipment",
+ "equipment-u": "Ekwipunek",
"treasure-u": "Treasure",
"spellsMagic-u": "Spells/Magic",
"coin-u": "Coin",
- "platinum-u": "Platinum",
+ "platinum-u": "Platyna",
"gold-u": "Gold",
- "silver-u": "Silver",
- "copper-u": "Copper",
+ "silver-u": "Złoto",
+ "copper-u": "Miedź",
"electrum-u": "Electrum",
"encumberanceMovement-u": "Encumbrance/Movement",
"relative-u": "Relative"
diff --git a/Dragon Ball Universe/DragonBallV2.html b/Dragon Ball Universe/DragonBallV2.html
index 5f486e02ab..42708a1e81 100644
--- a/Dragon Ball Universe/DragonBallV2.html
+++ b/Dragon Ball Universe/DragonBallV2.html
@@ -378,7 +378,7 @@
Pilot (Agi):
Profession (Sch):
Science (Sch):
- Stealth (Agi):
+ Stealth (Agi):
Survival (Ins):
Thievery (Agi):
Use Magic (Spi):
diff --git a/Dragon Ball Universe/sheet.json b/Dragon Ball Universe/sheet.json
index da5eb8d7e2..3adae257ac 100644
--- a/Dragon Ball Universe/sheet.json
+++ b/Dragon Ball Universe/sheet.json
@@ -1,10 +1,11 @@
{
- "html": "DragonBallV2.html",
- "css": "DragonBallV2.css",
- "authors": "Oboe",
- "preview": "Attributes.PNG",
- "patreon": "https://www.patreon.com/m/DBUTTRPG",
- "roll20userid": "1106259",
- "instructions": "Dragon Ball Universe character sheet. For more info, checkout the discord (https://discord.gg/5jzgP7S) or the separate github (https://github.com/Oboe831/DragonBallRedux)",
- "website": "https://dbu-rpg.com/"
+ "html": "DragonBallV2.html",
+ "css": "DragonBallV2.css",
+ "authors": "Oboe",
+ "preview": "Attributes.PNG",
+ "patreon": "https://www.patreon.com/m/DBUTTRPG",
+ "roll20userid": "1106259",
+ "instructions": "Dragon Ball Universe character sheet. For more info, checkout the discord (https://discord.gg/5jzgP7S) or the separate github (https://github.com/Oboe831/DragonBallRedux)",
+ "website": "https://dbu-rpg.com/",
+ "legacy": true
}
\ No newline at end of file
diff --git a/Duels of Dreams - DODAS/DODAS.css b/Duels of Dreams - DODAS/DODAS.css
new file mode 100644
index 0000000000..8e6e47cad8
--- /dev/null
+++ b/Duels of Dreams - DODAS/DODAS.css
@@ -0,0 +1,828 @@
+@import url('https://fonts.googleapis.com/css?family=Girassol&display=swap');
+
+html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+}
+
+
+/* HTML5 display-role reset for older browsers */
+
+article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
+ display: block;
+}
+
+body {
+ line-height: 1;
+ background-color: #C5C3B6
+}
+
+ol, ul {
+ list-style: none;
+}
+
+blockquote, q {
+ quotes: none;
+}
+
+blockquote:before, blockquote:after, q:before, q:after {
+ content: '';
+ content: none;
+}
+
+table {
+ border-spacing: 0;
+ border-radius: 5px;
+ border-style: solid;
+ border: none;
+ border-color: #352719;
+ background-color: #DBD8CA;
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ font-style: italic;
+}
+
+
+/* END CSS STYLING RESET PAGE
+-------------------------------------------
+*/
+
+
+
+
+
+
+
+.charsheet {
+ background: #C5C3B6;
+}
+
+td {
+ background: #F2F2F2;
+ padding: 0in .5pt 0in .5pt;
+ height: 9.8pt;
+}
+
+input {
+ width: 100%;
+ font-weight: 800;
+ background: #352719;
+ background-color: #F9F9F9;
+ text-align: center;
+ font-style: normal;
+}
+
+
+
+
+
+/* TABS */
+
+
+div.sheet-tabbuttoncontainer {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ width: 470px;
+ margin-left: 5px;
+
+}
+
+button[type="action"].sheet-tabbutton {
+
+ font-family: 'Girassol';
+ font-size: 80%;
+ height: 12pt;
+ width: 75pt;
+
+ background-color: black;
+ color: white;
+
+ border: 1px solid gray;
+ border-radius: 80px;
+
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 1px 1px 8px 1px rgba(53, 39, 25, 0.45);
+}
+
+/*Configure the tab buttons*/
+.sheet-all,
+.sheet-combat,
+.sheet-skillsandpoints, .sheet-spells {
+ display: none;
+}
+
+/* show the selected tab */
+.sheet-tabstoggle[value="all"] ~ div.sheet-all,
+.sheet-tabstoggle[value="combat"] ~ div.sheet-combat,
+.sheet-tabstoggle[value="skillsandpoints"] ~ div.sheet-skillsandpoints,
+.sheet-tabstoggle[value="spells"] ~ div.sheet-spells {
+ display: block;
+}
+
+
+
+
+
+/* LAYOUT */
+
+div.sheet-dodaslayout {
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+
+
+}
+
+div.sheet-ATRTable, div.sheet-weapontable, div.sheet-armor, div.sheet-spelltable {
+ margin-top: 5px;
+ margin-bottom: 5px;
+ margin-left: 5px;
+
+}
+
+
+
+/* ATTRIBUTE TABLE */
+
+button[type="roll"].sheet-attributerollbutton{
+ background: none;
+ outline-color: transparent;
+ border-style: none;
+ font-weight: 200;
+ font-size: 100%;
+ padding: 0px 0px 0px 0px;
+ font-family: 'Girassol';
+ cursor: pointer;
+ text-shadow: none;
+ color: #292929;
+}
+
+button[type="roll"].sheet-derivedattributerollbutton{
+ background: none;
+ outline-color: transparent;
+ border-style: none;
+ color: white;
+ font-weight: 200;
+ font-size: 100%;
+ padding: 0px 0px 0px 0px;
+ cursor: pointer;
+ text-shadow: none;
+}
+
+
+
+div.sheet-ATRTable {
+ display: grid;
+ background-color: gray;
+ width: 185pt;
+ height: 120pt;
+ /* from style reset */
+ border-style: solid;
+ border: none;
+ border-color: #352719;
+ background-color: #DBD8CA;
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+
+}
+
+
+div.sheet-ATRTableHeader {
+ display: grid;
+ font-family: 'Girassol';
+ grid-template-columns: 60pt 60pt 60pt;
+ font-size: 115%;
+ /*padding: .1em;*/
+ text-align: center;
+ font-style: italic;
+}
+
+
+div.sheet-ATRTableRow {
+ display: grid;
+ grid-template-columns: repeat(6, 30pt);
+ font-size: 100%;
+ text-align: center;
+}
+
+
+
+
+div.sheet-ATRLetter {
+ background-color: #DBD8CA;
+ font-family: 'Girassol';
+ font-style: normal;
+padding: .3em;
+color: #292929;
+
+ /*
+ text-align: center;
+ font-size: 110%;
+ padding: .3em;
+ text-align: center
+ */
+}
+
+div.sheet-ATRNumber {
+ background-color: #DBD8CA;
+ text-align: center;
+}
+
+div.sheet-derivedATRLetter {
+
+ font-family: 'Girassol';
+ font-style: normal;
+ font-size: 100%;
+ background-color: #352719;
+ color: white;
+
+ text-align: center;
+padding: .4em;
+}
+
+/*WEAPON TABLE*/
+
+div.sheet-weapontable {
+ font-family: 'Girassol';
+ width: 1fr;
+ padding: 0;
+ column-gap: 0;
+ padding: 0in 1.5pt 0in 1.5pt;
+ font-size: 7.0pt;
+
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+}
+
+div.sheet-weapontable span {
+ display: grid;
+ align-items: center; /* new */
+ justify-items: center; /* new */
+
+}
+
+div.sheet-wptrow2 span {
+ display: flex;
+ align-items: flex-end;
+ justify-content: center;
+}
+
+div.sheet-wptrow1 {
+ display: grid;
+ grid-template-columns: 60pt 25pt 25pt 25pt 40pt 25pt 25pt 24pt 24pt 22pt 34pt 30pt 20pt 20pt ;
+ column-gap: 0;
+ background-color: none;
+ height: 16pt;
+
+}
+
+div.sheet-wptrow2 {
+ display: grid;
+ grid-template-columns: 60pt 25pt 25pt 25pt 20pt 20pt 50pt 24pt 24pt 22pt 104pt ;
+ column-gap: 0;
+ background-color: gray;
+
+}
+
+.sheet-wptrangedc, .sheet-rollplus, .sheet-wptSkrm, .sheet-wpttoprowAP, .sheet-wtMod, .sheet-wtA {
+ background-color: white;
+ color: black;
+}
+
+.sheet-wtweapon, .sheet-cptoprow, .sheet-wtTotal, .sheet-wtDm, .sheet-wtOther {
+ background-color: black;
+ color: white;
+}
+
+.sheet-wtSkrmD, .sheet-wptSkrm, .sheet-wpttoprowcut, .sheet-wpttoprowthrust, .sheet-wtRange, .sheet-wpttoprowparry, .sheet-wpttoprowdodge, .sheet-pp, .sheet-wtRange, .sheet-wtHand, .sheet-wtD, .sheet-wtSkrmDef, .sheet-wtBlock {
+ color: black;
+ background-color: #D8D8D8;
+}
+
+.sheet-wptrangedc {
+ display: grid;
+ align-self: center;
+
+}
+
+.sheet-wpttoprowcut, .sheet-wpttoprowthrust, .sheet-wtRange, .sheet-wtHand, .sheet-wtA, .sheet-wtD, .sheet-wrSkrmDef {
+ border: 1px solid #A4A4A4;
+}
+
+.sheet-wpttoprowdodge {
+ border-left: 1px solid #A4A4A4;
+}
+
+.sheet-wpttoprowAP, .sheet-wtMod {
+ border-left: 1px solid #D8D8D8;
+ border-right: 1px solid #D8D8D8;
+}
+
+
+
+
+ /*repeating inputer*/
+
+div.sheet-wptfillrepeating,
+div.sheet-wptfillrepeating input[type="text"] {
+ display: grid;
+ grid-template-columns: 60pt 25pt 25pt 25pt 20pt 20pt 25pt 25pt 24pt 24pt 22pt 1fr 20pt;
+ height: 12.8pt;
+ font-size: 8.0pt;
+ width: 100%;
+ color: black;
+}
+
+input[name="attr_cptotal"]{
+
+background-color: #EAEAEA;
+}
+
+
+
+/* ARMOR TABLE */
+
+div.sheet-armor {
+ display: grid;
+ /*
+ font-style: normal;
+ */
+ font-family: 'Girassol';
+ width: 440pt;
+ padding: 0;
+ column-gap: 0;
+ padding: 0in 1.5pt 0in 1.5pt;
+ font-size: 8.0pt;
+
+
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+
+}
+
+div.sheet-toprow {
+ display: grid;
+ grid-template-columns: 100pt 72pt 20pt 72pt;
+ column-gap: 0;
+ height: 12.8pt;
+ font-size: 8.0pt;
+}
+
+span.sheet-atTopAvEquip {
+ background-color: #EAEAEA;
+ color: black;
+ font-weight: 900;
+ border-bottom: 1px solid #BCBCBC;
+}
+ /*cpbc DR total*/
+span.sheet-atP, span.sheet-atB, span.sheet-atC, span.sheet-atE {
+ background-color: #EAEAEA;
+ color: black;
+ font-weight: 900;
+ border-bottom: 1px solid #BCBCBC;
+}
+
+span.sheet-atDRTotal {
+ background-color: black;
+ color: white;
+}
+
+span.sheet-attc, span.sheet-attp, span.sheet-attb, span.sheet-atte {
+ background-color: black;
+ color: white;
+}
+
+span.sheet-atTopWeapon, span.sheet-atTopBD {
+ background-color: none;
+}
+
+ /* second row stuff */
+div.sheet-armorsecondrow {
+ display: grid;
+ grid-template-columns: 100pt 18pt 18pt 18pt 18pt 20pt 18pt 18pt 18pt 18pt 30pt 30pt 110pt;
+ column-gap: 0;
+ color: #292929;
+
+}
+ /* repeating inputs */
+div.sheet-armor-fillinrepeating,
+div.sheet-armor-fillinrepeating input[type="text"] {
+ display: grid;
+ grid-template-columns: 100pt 18pt 18pt 18pt 18pt 20pt 18pt 18pt 18pt 18pt 30pt 30pt 110pt;
+ height: 14pt;
+ font-size: 8.0pt;
+ width: 100%;
+ color: black;
+}
+
+input[name="attr_damagereduction"], input[name="attr_attP"],
+input[name="attr_attB"], input[name="attr_attE"]{
+
+background-color: #EAEAEA;
+}
+
+ /*some styling */
+div.sheet-armorsecondrow span, div.sheet-toprow span {
+ display: flex;
+ align-items: flex-end;
+ justify-content: center;
+}
+
+span.sheet-atArmor, span.sheet-atDR {
+ font-weight: 900;
+ background: black;
+ color: #ffffff;
+
+}
+
+span.sheet-atLocation, span.sheet-atAPM, span.sheet-atStealth, span.sheet-atOther {
+ background-color: #DBDBDB;
+
+}
+
+span.sheet-atStealth {
+ border-right: 1px solid #BCBCBC;
+ border-left: 1px solid #BCBCBC;
+}
+
+span.sheet-atBD {
+ background-color: #D6BEA3;
+ color: black;
+ font-weight: 600;
+ border-bottom: 1px solid #BCBCBC;
+ border-left: 1px solid black;
+ border-right: 1px solid black;
+ border-top: 1px solid black;
+}
+
+span.sheet-atAPM {
+ background-color: white;
+ color: black;
+
+ border-right: 1px solid #BCBCBC;
+ border-left: 1px solid #BCBCBC;
+}
+
+
+
+
+/* SPELLS TABLE */
+
+div.sheet-spelltable {
+ display: grid;
+ font-family: 'Girassol';
+ width: 1fr;
+ padding: 0;
+ column-gap: 0;
+ font-size: 8.0pt;
+ color: black;
+
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+
+
+}
+
+div.sheet-spelltable span {
+ display: grid;
+ align-items: center;
+ justify-items: center;
+}
+
+div.sheet-strow {
+ display: grid;
+ grid-template-columns: 80pt 25pt 32pt 40pt 40pt 40pt 25pt 25pt 25pt 20pt 270pt ;
+ column-gap: 0;
+ background-color: #D8D8D8;
+}
+
+.sheet-stspells, .sheet-stLVL, .sheet-stCP, .sheet-stRoll, .sheet-stOpp, .sheet-stArea, .sheet-stDuration, .sheet-stRange, .sheet-stDescription {
+
+ border: 1px solid #A4A4A4;
+}
+
+.sheet-stRollbutton, .sheet-stLVL, .sheet-stspells, .sheet-stCP, .sheet-stRoll {
+ background-color: black;
+ color: white;
+
+}
+
+.sheet-stArea, .sheet-stDuration, .sheet-stRange, .sheet-stDescription {
+ background-color: white;
+}
+
+.sheet-stLVL, .sheet-stRoll {
+ background-color: gray;
+}
+
+div.sheet-strepeating,
+div.sheet-strepeating input[type="text"] {
+ display: grid;
+ grid-template-columns: 80pt 25pt 32pt 40pt 40pt 40pt 25pt 25pt 25pt 20pt 270pt ;
+ height: 12.8pt;
+ font-size: 8.0pt;
+ width: 100%;
+ padding: 0;
+ color: black;
+}
+
+input[name="attr_spelllevel"], input[name="attr_spellskill"],
+input[name="attr_strcp"] {
+
+background-color: #EAEAEA;
+}
+
+div.sheet-strepeating input[name="attr_spelldescription"] {
+ text-align: left;
+ padding: 0pt 4pt;
+}
+
+
+
+
+
+/* SKILLS AND ABILITIES */
+
+div.sheet-skilltable {
+ font-family: 'Girassol';
+ width: 446pt;
+ padding: 0;
+ column-gap: 0;
+ padding: 0in 1.5pt 0in 1.5pt;
+ font-size: 8.0pt;
+ margin-top: 5px;
+ color: black;
+
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+
+
+}
+
+
+div.sheet-skilltablerow span, div.sheet-skilltablerow2 span {
+
+ display: grid;
+ align-items: center; /* new */
+ justify-items: center;
+
+}
+
+
+div.sheet-skilltablerow {
+ display: grid;
+ grid-template-columns: 24pt 24pt 70pt 100pt 24pt 48pt 24pt 88pt 26pt 20pt;
+
+
+}
+
+div.sheet-skilltablerow2 {
+ display: grid;
+ grid-template-columns: 24pt 24pt 70pt 20pt 20pt 20pt 20pt 20pt 24pt 24pt 24pt 24pt 22pt 22pt 22pt 22pt 26pt 20pt;
+}
+
+.sheet-str1Above, .sheet-str1RelevantAttributes, .sheet-str2Tier, .sheet-str2Cost, .sheet-str2AboveSub, .sheet-str2Sub, .sheet-str2Roll {
+ background-color: #cfcfcf;
+}
+
+.sheet-str2Roll, .sheet-str1Skillsand, .sheet-str2Abilities, .sheet-str2Total {
+ background-color: black;
+ color: white;
+}
+
+.sheet-str1TiersbyCost, .sheet-str27, .sheet-str24, .sheet-str22, .sheet-str21, .sheet-str2star, .sheet-str2ATR1, .sheet-str2Mod1, .sheet-str2ATR2, .sheet-str2Mod2 {
+ background-color: #bababa;
+}
+
+.sheet-str1Synergy, .sheet-str2Bonus, .sheet-str2Self {
+ background-color: #575757;
+ color: white;
+}
+
+.sheet-str1RelevantAttributes, .sheet-str2Tier, .sheet-str2Cost, .sheet-str1TiersbyCost, .sheet-str27, .sheet-str24, .sheet-str22, .sheet-str21, .sheet-str2star, .sheet-str2ATR1, .sheet-str2Mod1, .sheet-str2ATR2, .sheet-str2Mod2, .sheet-str2Bonus, .sheet-str2Self {
+ border: 1px solid gray;
+}
+
+div.sheet-skillsfillrepeating,
+div.sheet-skillsfillrepeating input[type="text"] {
+ display: grid;
+ grid-template-columns: 24pt 24pt 70pt 20pt 20pt 20pt 20pt 20pt 24pt 24pt 24pt 24pt 22pt 22pt 22pt 22pt 26pt 20pt;
+ height: 12.8pt;
+ font-size: 8.0pt;
+ width: 100%;
+ color: black;
+}
+
+.sheet-str2Roll {
+ border-left: 1px solid #d1d1d1;
+}
+
+/*
+.sheet-str2Total {
+ border-right: 1px solid white;
+}
+*/
+
+input[name="attr_tierabovesub"], input[name="attr_synergybonus"], input[name="attr_synergyself"], input[name="attr_group"] {
+ background-color: #f2f2f2;
+}
+input[name="attr_skilltotal"] {
+ background-color: #EAEAEA;
+}
+
+
+/* POINT BUY TOTALS TABLE */
+
+div.sheet-pointbuytable {
+ font-family: 'Girassol';
+ width: 314pt;
+ height: 107pt;
+
+ margin-top: 12px;
+ margin-left: 5px;
+ padding: 0;
+ column-gap: 0;
+ padding: 0in 1.5pt 0in 1.5pt;
+ font-size: 8.0pt;
+ background-color: #404040;
+
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+
+}
+
+div.sheet-pointbuytabletitlerow {
+ height: 17pt;
+}
+
+div.sheet-pointbuytabletitlerow, div.sheet-pointbuytabletotalrow {
+ background-color: black;
+ color: white;
+}
+
+div.sheet-pointbuytabletitlerow span {
+ border: 1px solid gray;
+}
+
+div.sheet-pointbuytabletitlerow, div.sheet-pointbuytablerow, div.sheet-pointbuytabletotalrow {
+ display: grid;
+ grid-template-columns: 70pt 26pt 220pt;
+
+}
+
+
+div.sheet-pointbuytabletitlerow span, div.sheet-pointbuytablerow span, div.sheet-pointbuytabletotalrow span {
+ display: grid;
+ align-items: center;
+ justify-items: center;
+}
+
+div.sheet-pointbuytablerow {
+ color: white;
+}
+
+.sheet-pbtpointsspent {
+ font-size: 10pt;
+}
+
+div.sheet-pointbuytable input[type="text"] {
+ height: 12.8pt;
+ font-size: 8.0pt;
+ width: 100%;
+
+
+}
+
+
+
+
+/* SPELL BUILDER */
+
+div.sheet-spellbuilder {
+ font-family: 'Girassol';
+ width: 1fr;
+ padding: 0;
+ column-gap: 0;
+ padding: 0in 1.5pt 0in 1.5pt;
+ font-size: 8.0pt;
+ background-color: none;
+ margin-top: 12px;
+ margin-left: 5px;
+
+ -webkit-box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+ box-shadow: 2px 2px 11px 3px rgba(53, 39, 25, 0.45);
+
+}
+
+div.sheet-spellbuilder span {
+ display: grid;
+ align-items: center;
+ justify-items: right;
+ padding: 0px 4px 0px 0px;
+}
+
+ /*rows*/
+div.sheet-sbtitlerow {
+ display: grid;
+ grid-template-columns: 60pt repeat(4, 90pt 20pt);
+}
+
+div.sheet-sbrowcorespell, div.sheet-sbrowdamage, div.sheet-sbrowspelltype, div.sheet-sbrowarea, div.sheet-sbrowduration, div.sheet-sbrowrange, div.sheet-sbrowmodifiers, div.sheet-sbmodifiersfill {
+ display: grid;
+ grid-template-columns: 60pt repeat(4, 90pt 20pt);
+}
+
+
+div.sheet-spellbuilder input[type="text"] {
+ font-family: 'Girassol';
+ height: 12.8pt;
+ font-size: 8.0pt;
+ width: 100%;
+ color: black;
+}
+
+input[name="attr_spellbuildername1"], input[name="attr_spellbuildername2"],
+input[name="attr_spellbuildername3"],
+input[name="attr_spellbuildername4"],
+input[name="attr_spellbuilderlvl1"],
+input[name="attr_spellbuilderlvl2"],
+input[name="attr_spellbuilderlvl3"],
+input[name="attr_spellbuilderlvl4"], .sheet-sbcorespell {
+ background-color: #404040;
+ color: blue;
+}
+
+div.sheet-sbtitlerow input[type="text"] {
+ color: white;
+}
+
+
+input[name="attr_sbcorespell1"], input[name="attr_sbcorelvl1"],
+input[name="attr_sbcorespell2"],
+input[name="attr_sbcorelvl2"],
+input[name="attr_sbcorespell3"],
+input[name="attr_sbcorelvl3"],
+input[name="attr_sbcorespell4"],
+input[name="attr_sbcorelvl4"], .sheet-sbcorespell, input[name="attr_sbmodifiers1"], input[name="attr_sbmodifierslvl1"],
+input[name="attr_sbmodifiers2"],
+input[name="attr_sbmodifierslvl2"],
+input[name="attr_sbmodifiers3"],
+input[name="attr_sbmodifierslvl3"],
+input[name="attr_sbmodifiers4"],
+input[name="attr_sbmodifierslvl4"] {
+ background-color: #dbdbdb;
+ color: black;
+}
+
+div.sheet-sbmodifiersfill input[name="attr_sbmodifierleft"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifiertext1"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifier1"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifiertext2"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifier2"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifiertext3"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifier3"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifiertext4"],
+div.sheet-sbmodifiersfill input[name="attr_sbmodifier4"] {
+ background-color: #dbdbdb;
+ color: black;
+}
+
+
+
+.sheet-sbdamage, .sheet-sbspelltype, .sheet-sbmodifiers {
+ background-color: gray;
+}
+
+.sheet-sbarea, .sheet-sbduration, .sheet-sbrange {
+ color: black;
+ background-color: white;
+}
+
+.sheet-sbdamage, .sheet-sbspelltype, .sheet-sbmodifiers {
+ color: black;
+ background-color: #dbdbdb;
+}
+
+.sheet-sbnameandlevel {
+ color: white;
+ background-color: black;
+}
+
+
+
+
+
+/*roll buttons*/
+
+button[type=roll].sheet-derivedattributerollbutton::before {
+ content: '';
+}
+
+button[type=roll].sheet-attributerollbutton::before {
+ content: '';
+}
diff --git a/Duels of Dreams - DODAS/DODAS.html b/Duels of Dreams - DODAS/DODAS.html
new file mode 100644
index 0000000000..66e28e90e3
--- /dev/null
+++ b/Duels of Dreams - DODAS/DODAS.html
@@ -0,0 +1,1233 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ STR
+
+
+
+
+
+
+ WP
+
+
+
+
+
+
+ AP
+
+
+
+
+
+
+
+
+
+
+
+ AGI
+
+
+
+
+
+
+
+ WIT
+
+
+
+
+
+
+
+ REF
+
+
+
+
+
+
+
+
+
+
+ TGH
+
+
+
+
+
+
+ PER
+
+
+
+
+
+
+ KND
+
+
+
+
+
+
+
+
+ SZ
+
+
+
+
+
+
+ IN
+
+
+
+
+
+
+ KO
+
+
+
+
+
+
+
+
+
+ PW
+
+
+
+
+
+
+ BD
+
+
+
+
+
+ Move
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ STR
+
+
+
+
+
+
+ WP
+
+
+
+
+
+
+ AP
+
+
+
+
+
+
+
+
+
+
+
+ AGI
+
+
+
+
+
+
+
+ WIT
+
+
+
+
+
+
+
+ REF
+
+
+
+
+
+
+
+
+
+
+ TGH
+
+
+
+
+
+
+ PER
+
+
+
+
+
+
+ KND
+
+
+
+
+
+
+
+
+ SZ
+
+
+
+
+
+
+ IN
+
+
+
+
+
+
+ KO
+
+
+
+
+
+
+
+
+
+ PW
+
+
+
+
+
+
+ BD
+
+
+
+
+
+ Move
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Duels of Dreams - DODAS/DODAS.png b/Duels of Dreams - DODAS/DODAS.png
new file mode 100644
index 0000000000..76c750a77e
Binary files /dev/null and b/Duels of Dreams - DODAS/DODAS.png differ
diff --git a/Duels of Dreams - DODAS/sheet.json b/Duels of Dreams - DODAS/sheet.json
new file mode 100644
index 0000000000..5e59ca9270
--- /dev/null
+++ b/Duels of Dreams - DODAS/sheet.json
@@ -0,0 +1,9 @@
+{
+ "html": "DODAS.html",
+ "css": "DODAS.css",
+ "authors": "Daniel Shinabarger",
+ "roll20userid": "224840",
+ "preview": "DODAS.png",
+ "instructions": "Current sheet for 'Duals of Dreams' or DODAS. A combat driven rpg system. Actively playtesting. Game rules can be found here: https://www.dropbox.com/sh/rwwt8dp5cn57w18/AAD_IIAmucETRSDesDOo_MO6a?dl=0 .",
+ "legacy": true
+}
diff --git a/Elric/translations/fr.json b/Elric/translations/fr.json
index 6e1949d08b..45506b460e 100644
--- a/Elric/translations/fr.json
+++ b/Elric/translations/fr.json
@@ -1,8 +1,8 @@
{
- "h2hFumble1": "Slip or trip over rocks, etc .- lose next parry; your foe may disengage.Slip or trip over rocks, etc. lose next parry; your foe may disengage.",
- "h2hFumble2": "Slip or trip on a corpse or other obstacle -lose next attack; your opponent may disengage.",
- "h2hFumble3": "Slip or trip in a pool of blood or water or other hazard:- lose next parry and attack;your enemy may disengage.",
- "h2hFumble4": "Sweat in eyes -parry, dodge,or move only for the next 1D3 combat rounds; your foe may disengage.",
+ "h2hFumble1": " Glisser ou trébucher sur les rochers, etc : - perdre la prochaine parade ; votre adversaire peut se désengager.",
+ "h2hFumble2": "Glisser ou trébucher sur un cadavre ou un autre obstacle : - perdre la prochaine attaque ; votre adversaire peut se désengager.",
+ "h2hFumble3": " Glisser ou trébucher dans une flaque de sang ou d'eau ou autre danger : - perdre la prochaine parade et attaquer; votre ennemi peut se désengager.",
+ "h2hFumble4": "Sueur dans les yeux : - parer, esquiver ou se déplacer seulement pour les 1D3 prochains rounds de combat; votre adversaire peut se désengager.",
"h2hFumble5": "Shield strap breaks -halve your shield parry percentage until repaired. lnapplicable to a demon shield.",
"h2hFumble6": "Distracted -automatic miss on your next attack, in whatever round it occurs.",
"h2hFumble7": "Drop weapon -it's at your feet and costs 5 DEX-ranks to recover. Your enemy may disengage. lgnore this fumble if you parry with a shield.",
@@ -104,8 +104,8 @@
"H-to-H-Fumbles": "H-to-H Fumbles",
"Hands": "Poings",
"Hand-To-Hand-Weapons": "Hand To Hand Weapons",
- "Helmet-off": "Helmet off:",
- "Helmet-on": "Helmet on:",
+ "Helmet-off": "Casque non porté :",
+ "Helmet-on": "Casque porté :",
"Hit-points": "Points de vie",
"Hit-Points-Damage": "Hit Points & Damage",
"HP": "PV",
@@ -132,12 +132,12 @@
"Missile-Weapon": "Missile-Weapon",
"Missile-Weapons": "Missile Weapons",
"Moderate": "Modéré",
- "Modifier": "Modifier",
+ "Modifier": "Modificateur",
"Mod": "Mod.",
"MOV": "MOUV",
"MP": "PM",
"MP-Cost": "Coût en PM",
- "MP-Storage": "MP Storage",
+ "MP-Storage": "Stockage de PM",
"Need": "Need",
"Name": "Nom",
"No": "Non",
@@ -157,7 +157,7 @@
"Saddle-Horse": "Saddle Horse",
"Shield": "Bouclier",
"Short": "Courte",
- "Sight": "Sight",
+ "Sight": "Vue",
"SIZ": "TAI",
"Skill": "Compétence",
"Skills": "Compétences",
@@ -167,23 +167,23 @@
"Self": "Soi-même",
"Spells": "Sorts",
"Spell-Name": "Nom du Sort",
- "Spells-Runes": "Spells & Runes",
- "Summoning-Fumble": "Summoning Fumble",
+ "Spells-Runes": "Sorts & Runes",
+ "Summoning-Fumble": "Maladresse d'invocation",
"summonFumble1": "Violent explosion in octagon deafens those nearby for 1D10 hours, and creates a powerful stench",
"summonFumble2": "Demon appears as desired, but performs the opposite to each given command.",
"summonFumble3": "Demon appears as wanted in octagon, but it is not bound by the octagon. It immediately attacks the Summoner.",
"summonFumble4": "The interior of the octagon is replaced permanently by a well filled with stars; no air escapes, but things thrown down this well fall forever, and occasionally horrible things appear up out of it.",
- "summonFumble5": "An average bal'boost appears outside the octagon; it attacks until it has killed or captured someone, then returns to its home plane",
- "summonFumble6": "Summoner disappears, drawn to a random continent from where he or she must get home alone. Roll 1D6: 1,2 Western continent; 3,4 Southern continent; 5,6 Northern continent. Gamemaster chooses the nation.",
- "summonFumble7": "Chaotic corruption: one of the summoner's limbs is replaced with one from another mammal, a gigantic insect, an arthropod. Lose 1D10 APP as well.",
- "summonFumble8": "Astral corruption: summoner's player must move 1D6 points from POW to one other summoner characteristic.",
- "summonFumble9": "Mental corruption: summoner's player must move 1D6 points from INT to one other summoner characteristic.",
- "summonFumble10": "Demon appears normally and behaves as expected, except that it occupies five places in memory (not one), cannot die at the summoner's behest, and cannot be dismissed.",
- "summonFumble11": "Summoner and bystanders disappear, all drawn to the city of Ameeron on the other side of the Shade Gate, or as the gamemaster chooses. See Elric of Melniboné for more about Ameeron.",
- "summonFumble12": "Quaolnargn (or an identical sibling, or some equivalent horror) appears.",
+ "summonFumble5": "Un Bal'boost moyen apparaît en dehors de l'octogone ; il attaque jusqu'à ce qu'il ait tué ou capturé quelqu'un, puis retourne à son plan d'origine",
+ "summonFumble6": "L'invocateur disparaît, attiré vers un continent aléatoire d'où il doit rentrer seul chez lui. Jet 1D6 : 1,2 continent occidental ; 3,4 continent méridional ; 5,6 continent septentrional. Le maître du jeu choisit la nation.",
+ "summonFumble7": "Corruption chaotique : un des membres de l'invocateur est remplacé par celui d'un autre mammifère, d'un insecte gigantesque, d'un arthropode. Perdez également 1D10 APP.",
+ "summonFumble8": "Corruption astrale : le joueur de l'invocateur doit transférer 1D6 points de POU à une autre caractéristique de l'invocateur.",
+ "summonFumble9": "Corruption mentale : le joueur de l'invocateur doit transférer 1D6 points de INT vers une autre caractéristique de l'invocateur.",
+ "summonFumble10": "Le démon apparaît normalement et se comporte comme prévu, sauf qu'il occupe cinq places dans la mémoire (pas une seule), ne peut pas mourir à la demande de l'invocateur et ne peut pas être renvoyé.",
+ "summonFumble11": "L'invocateur et les témoins disparaissent, tous attirés par la ville d'Ameeron de l'autre côté de la Porte de l'Ombre, ou selon le choix du maître du jeu. Voir Elric de Melniboné pour en savoir plus sur Ameeron.",
+ "summonFumble12": "Quaolnargn (ou un frère ou une sœur identique, ou une horreur équivalente) apparaît.",
"summonFumble13": "Un Seigneur du Chaos apparaît.",
- "summonFumble14": "Summoner turns inside out. All skills fall to base chance. His or her disgusting body continues to function normally, though it terrifies onlookers. APP is zero.",
- "Summoning-Roll": "Summoning Roll",
+ "summonFumble14": "L'invocateur est à l'envers. Toutes les compétences relèvent du hasard. Son corps dégoûtant continue de fonctionner normalement, même s'il terrifie les gens qui le regardent. L'APP est à zéro.",
+ "Summoning-Roll": "Jet d'invocation",
"STR": "FOR",
"Title": "Titre",
"Title-Nickname": "Titre/Surnom",
@@ -195,7 +195,7 @@
"Turn": "Tour",
"Turn-Order": "Turn Order",
"unconsciousnes": "Inconscience",
- "Use-mount-damage-bonus": " *Use mount's damage bonus",
+ "Use-mount-damage-bonus": " *utilise le bonus de dégâts de la monture",
"Wealth": "Richesse",
"Weapon": "Arme",
"Weapons": "Armes",
diff --git a/Esper_Genesis_5E/EG_Sheet.css b/Esper_Genesis_5E/EG_Sheet.css
index 56fecf0f73..9cf2953619 100644
--- a/Esper_Genesis_5E/EG_Sheet.css
+++ b/Esper_Genesis_5E/EG_Sheet.css
@@ -61,7 +61,7 @@ input[type=radio].sheet-npc-button + span {
.sheet-advantagetoggle {
position: absolute;
top: 92px;
- left: 570px;
+ left: 440px;
z-index: 1;
}
.sheet-advantagetoggle input[type=radio] {
@@ -122,7 +122,7 @@ input[type=radio].sheet-tab-button:checked + span, .sheet-advantagetoggle input[
}
.sheet-whispertoggle {
- left: 270px;
+ left: 150px;
}
.sheet-advantagetoggle.sheet-whispertoggle input.sheet-toggle-right {
@@ -185,10 +185,6 @@ input[type=radio].sheet-tab-button:checked + span, .sheet-advantagetoggle input[
.sheet-npc_toggle[value="1"] + .sheet-npcspellcastingflag[value="1"] ~ .sheet-pc .sheet-page.sheet-spells .sheet-body {
visibility: visible;
}
-.sheet-npc_toggle[value="1"] + .sheet-npcspellcastingflag[value="1"] ~ .sheet-pc .sheet-page.sheet-spells .sheet-body .sheet-col {
- display: block;
-}
-
.sheet-hidden, .sheet-options .sheet-row.sheet-hidden {
display: none;
}
@@ -1364,6 +1360,24 @@ button[type=roll] * {
.charsheet .sheet-spells .sheet-details span[name=attr_spelldescription] {
white-space: pre-line;
}
+.charsheet .sheet-spells .sheet-details > .sheet-italics span:nth-last-child(3) {
+ display: inline-block;
+ width: 120px;
+ text-align: left;
+ text-transform: lowercase;
+}
+.charsheet .sheet-spells .sheet-details > .sheet-italics span:nth-last-child(3)::first-letter {
+ text-transform: uppercase;
+}
+.charsheet .sheet-spells .sheet-details > .sheet-italics span:not(:first-child) {
+ margin-left: 3px;
+}
+.charsheet .sheet-spells .sheet-details span[data-i18n=concentration] {
+ margin-left: -3px;
+}
+.charsheet .sheet-spells .sheet-details span[data-i18n=concentration]:after {
+ content: ", ";
+}
.repcontainer .sheet-spell .sheet-details-flag:not(:checked) ~ .sheet-wrapper {
display: none;
@@ -1410,6 +1424,7 @@ button[type=roll] * {
}
.sheet-spell .sheet-details span.sheet-bold {
font-weight: bold;
+ margin-right: 3px;
}
.sheet-spell .sheet-details .sheet-italics {
font-style: italic;
@@ -2488,6 +2503,9 @@ span.sheet-spellritual, span.sheet-spellconcentration {
.sheet-npc .sheet-display .sheet-red input, .sheet-npc .sheet-display .sheet-red span {
color: #245485;
}
+.sheet-npc .sheet-display .sheet-red input:first-child, .sheet-npc .sheet-display .sheet-red span:first-child {
+ margin-right: 3px;
+}
.sheet-npc .sheet-npc_options {
border-bottom: 2px dashed gold;
}
@@ -2588,6 +2606,9 @@ span.sheet-spellritual, span.sheet-spellconcentration {
.sheet-npc .sheet-display .sheet-parens:before {
content: "(";
}
+.sheet-npc .sheet-display .sheet-parens.sheet-xp:before {
+ content: " (";
+}
.sheet-npc .sheet-display .sheet-parens:after {
content: ")";
}
@@ -3785,6 +3806,9 @@ span.sheet-spellritual, span.sheet-spellconcentration {
.sheet-charmancer .sheet-topbar div.sheet-meta-info-container span, .sheet-charmancer .sheet-leveler-topbar div.sheet-meta-info-container span {
font-size: 1.2em;
}
+.sheet-charmancer .sheet-choice {
+ display: none !important;
+}
.sheet-charmancer .sheet-topbar div.sheet-meta-info-container span.sheet-choice, .sheet-charmancer .sheet-leveler-topbar div.sheet-meta-info-container span.sheet-choice {
display: none;
}
@@ -4028,6 +4052,172 @@ span.sheet-spellritual, span.sheet-spellconcentration {
.sheet-charmancer .sheet-gold_option input[type=number] {
width: 4.5em;
}
+.sheet-charmancer .sheet-customize-origin {
+ box-sizing: border-box;
+ padding-right: 40px;
+ position: relative;
+ width: 100%;
+ display: none;
+}
+.sheet-charmancer .sheet-customize-origin label span {
+ display: block;
+}
+.sheet-charmancer .sheet-customize-origin label span:last-child {
+ font-weight: normal;
+ width: calc(100% + 40px);
+}
+.sheet-charmancer .sheet-customize-origin .sheet-toggle {
+ box-sizing: border-box;
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 40px;
+ height: 20px;
+ overflow: hidden;
+ border-radius: 10px;
+ border: 1px solid #CCC;
+}
+.sheet-charmancer .sheet-customize-origin .sheet-toggle input {
+ width: 100%;
+ height: 100%;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+ outline: none;
+}
+.sheet-charmancer .sheet-customize-origin .sheet-toggle input:checked {
+ background: #c43c41;
+}
+.sheet-charmancer .sheet-customize-origin .sheet-toggle .sheet-knob {
+ width: 20px;
+ height: 20px;
+ background: #CCC;
+ position: absolute;
+ top: -1px;
+ left: -1px;
+ border-radius: 10px;
+ pointer-events: none;
+}
+.sheet-charmancer .sheet-customize-origin .sheet-toggle input:checked + .sheet-knob {
+ right: -1px;
+ left: auto;
+}
+.sheet-charmancer input[value="1"] + .sheet-customize-origin {
+ display: block;
+}
+.sheet-charmancer span.sheet-tasha + select {
+ margin-bottom: 10px;
+}
+.sheet-charmancer input[value="1"] + span.sheet-tasha:after {
+ content: " (+1):";
+}
+.sheet-charmancer input[value="2"] + span.sheet-tasha:after {
+ content: " (+2):";
+}
+.sheet-charmancer input[value="3"] + span.sheet-tasha:after {
+ content: " (+3):";
+}
+.sheet-charmancer input[value="4"] + span.sheet-tasha:after {
+ content: " (+4):";
+}
+.sheet-charmancer input[value="5"] + span.sheet-tasha:after {
+ content: " (+5):";
+}
+.sheet-charmancer input[value="6"] + span.sheet-tasha:after {
+ content: " (+6):";
+}
+.sheet-charmancer input[value="7"] + span.sheet-tasha:after {
+ content: " (+7):";
+}
+.sheet-charmancer input[value="8"] + span.sheet-tasha:after {
+ content: " (+8):";
+}
+.sheet-charmancer input[value="9"] + span.sheet-tasha:after {
+ content: " (+9):";
+}
+.sheet-charmancer input[value="10"] + span.sheet-tasha:after {
+ content: " (+10):";
+}
+.sheet-charmancer input[value="11"] + span.sheet-tasha:after {
+ content: " (+11):";
+}
+.sheet-charmancer input[value="12"] + span.sheet-tasha:after {
+ content: " (+12):";
+}
+.sheet-charmancer input[value="13"] + span.sheet-tasha:after {
+ content: " (+13):";
+}
+.sheet-charmancer input[value="14"] + span.sheet-tasha:after {
+ content: " (+14):";
+}
+.sheet-charmancer input[value="15"] + span.sheet-tasha:after {
+ content: " (+15):";
+}
+.sheet-charmancer input[value="16"] + span.sheet-tasha:after {
+ content: " (+16):";
+}
+.sheet-charmancer input[value="17"] + span.sheet-tasha:after {
+ content: " (+17):";
+}
+.sheet-charmancer input[value="18"] + span.sheet-tasha:after {
+ content: " (+18):";
+}
+.sheet-charmancer input[value="19"] + span.sheet-tasha:after {
+ content: " (+19):";
+}
+.sheet-charmancer input[value="20"] + span.sheet-tasha:after {
+ content: " (+20):";
+}
+.sheet-charmancer .sheet-asi-row .sheet-asi {
+ border-width: 1px !important;
+}
+.sheet-charmancer .sheet-asi-row .sheet-switch ~ .sheet-switch-container .sheet-feat-tab {
+ pointer-events: all;
+}
+.sheet-charmancer .sheet-asi-row .sheet-asi, .sheet-charmancer .sheet-asi-row .sheet-feat {
+ display: none;
+}
+.sheet-charmancer .sheet-asi-row .sheet-switchval[value=asi] ~ .sheet-asi, .sheet-charmancer .sheet-asi-row .sheet-switchval[value=feat] ~ .sheet-feat {
+ display: block;
+ border-color: #888;
+ border-style: solid;
+ border-width: 0 1px 1px 1px;
+ border-radius: 0 0 4px 4px;
+ padding: 1em;
+}
+.sheet-charmancer .sheet-asi-row .sheet-switchval[value=asi] ~ .sheet-switch-container .sheet-asi-tab, .sheet-charmancer .sheet-asi-row .sheet-switchval[value=feat] ~ .sheet-switch-container .sheet-feat-tab {
+ border-bottom-width: 0;
+ background-color: white;
+}
+.sheet-charmancer .sheet-spinnerloader {
+ width: 40%;
+ padding-right: 13px;
+ height: 100px;
+ background-image: url("https://app.roll20.net/images/load.gif");
+ background-repeat: no-repeat;
+ background-position: center center;
+ display: inline-block;
+ box-sizing: border-box;
+ position: relative;
+}
+.sheet-charmancer .sheet-spinner-toggle {
+ display: none;
+}
+.sheet-charmancer .sheet-spinner-toggle:empty + .sheet-spinnerloader {
+ display: none;
+}
+.sheet-charmancer .sheet-spinner-toggle:empty ~ .sheet-choices {
+ display: block;
+}
+.sheet-charmancer .sheet-spinner-toggle ~ .sheet-choices {
+ display: none;
+}
.sheet-manver .sheet-yes_spells {
display: flex;
@@ -4431,7 +4621,7 @@ span.sheet-spellritual, span.sheet-spellconcentration {
border-color: #888;
border-style: solid;
border-radius: 4px 4px 0 0;
- border-width: 1px;
+ border-width: 1px 1px 0 1px;
background-color: #aaa;
padding: 0.25em 0.5em;
margin: 0;
@@ -5769,14 +5959,14 @@ div.sheet-charmancer.sheet-licensedsheet .sheet-logos {
flex-flow: column;
margin-bottom: 1em;
}
-div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ * .sheet-logos, div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ .sheet-logos {
+div.sheet-charmancer .sheet-logos, div.sheet-charmancer .sheet-logos {
display: flex;
width: 100%;
text-align: center;
flex-flow: column;
margin-bottom: 1em;
}
-div.sheet-charmancer.sheet-licensedsheet .sheet-charmancer-logo {
+div.sheet-charmancer .sheet-charmancer-logo {
margin: 0 auto;
background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/charactermancer-1.png");
background-position: center;
@@ -5786,7 +5976,7 @@ div.sheet-charmancer.sheet-licensedsheet .sheet-charmancer-logo {
width: 70%;
height: 5em;
}
-div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ * .sheet-charmancer-logo, div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ .sheet-charmancer-logo {
+div.sheet-charmancer .sheet-charmancer-logo, div.sheet-charmancer .sheet-charmancer-logo {
margin: 0 auto;
background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/charactermancer-1.png");
background-position: center;
@@ -5798,7 +5988,7 @@ div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ * .sheet-charman
}
div.sheet-charmancer.sheet-licensedsheet .sheet-compendium-logo {
margin: 0 auto;
- background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/DnDlogored.png");
+ background: url("https://raw.githubusercontent.com/skydawn1/esper_genesis/master/EG_Logo.png");
background-position: center;
background-size: contain;
background-repeat: no-repeat;
@@ -5806,9 +5996,9 @@ div.sheet-charmancer.sheet-licensedsheet .sheet-compendium-logo {
width: 50%;
height: 3em;
}
-div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ * .sheet-compendium-logo, div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ .sheet-compendium-logo {
+div.sheet-charmancer .sheet-compendium-logo, div.sheet-charmancer .sheet-compendium-logo {
margin: 0 auto;
- background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/DnDlogored.png");
+ background: url("https://raw.githubusercontent.com/skydawn1/esper_genesis/master/EG_Logo.png");
background-position: center;
background-size: contain;
background-repeat: no-repeat;
@@ -6651,7 +6841,7 @@ div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ * .sheet-summary
.charsheet .sheet-pc .sheet-pc-ship .sheet-weapon-systems .sheet-table-header {
grid-template-columns: 45px 1fr 60px 30px 50px 70px;
grid-gap: 2px;
- max-width: calc(50% - 10px);
+ max-width: calc(50% - 30px);
}
.charsheet .sheet-pc .sheet-pc-ship .sheet-weapon-systems .sheet-table-header span {
font-size: 11px;
@@ -6663,6 +6853,22 @@ div.sheet-charmancer div.sheet-licensedsheet-flag:not(:empty) ~ * .sheet-summary
}
.charsheet .sheet-pc .sheet-pc-ship .sheet-weapon-systems .repcontainer .repitem {
border-top: 2px solid #e2c285;
+ margin-right: 20px;
+}
+.charsheet .sheet-pc .sheet-pc-ship .sheet-weapon-systems .repcontainer .repitem button[type=roll] {
+ position: absolute;
+ top: 4px;
+ right: -20px;
+ background: none;
+ border: none;
+ color: black;
+ box-shadow: none;
+ margin: 0;
+ padding: 0;
+ font-weight: bold;
+}
+.charsheet .sheet-pc .sheet-pc-ship .sheet-weapon-systems .repcontainer .repitem button[type=roll]:hover {
+ color: #00ba73;
}
.charsheet .sheet-pc .sheet-pc-ship .sheet-weapon-systems .repcontainer .repitem .sheet-table-body {
grid-template-columns: 45px 1fr 60px 30px 50px 70px;
diff --git a/Esper_Genesis_5E/EG_Sheet.html b/Esper_Genesis_5E/EG_Sheet.html
index f01a01aada..c9f28ca621 100644
--- a/Esper_Genesis_5E/EG_Sheet.html
+++ b/Esper_Genesis_5E/EG_Sheet.html
@@ -5,6 +5,7 @@
+
@@ -360,7 +361,7 @@
-
+
@@ -432,7 +433,7 @@
-
+
@@ -751,6 +752,7 @@
Piloting Bonus
+
@@ -820,7 +822,7 @@
-
+
@@ -892,7 +894,7 @@
-
+
@@ -1771,7 +1773,7 @@
-
+
@@ -1803,9 +1805,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -1919,7 +1923,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -1943,7 +1951,7 @@
-
+
@@ -1976,9 +1984,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -2092,7 +2102,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -2116,7 +2130,7 @@
-
+
@@ -2149,9 +2163,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -2267,7 +2283,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -2293,7 +2313,7 @@
-
+
@@ -2326,9 +2346,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -2443,7 +2465,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -2467,7 +2493,7 @@
-
+
@@ -2500,9 +2526,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -2616,7 +2644,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -2640,7 +2672,7 @@
-
+
@@ -2673,9 +2705,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -2789,7 +2823,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -2815,7 +2853,7 @@
-
+
@@ -2848,9 +2886,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -2964,7 +3004,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -2988,7 +3032,7 @@
-
+
@@ -3021,9 +3065,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -3137,7 +3183,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -3162,7 +3212,7 @@
-
+
@@ -3195,9 +3245,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -3311,7 +3363,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -3335,7 +3391,7 @@
-
+
@@ -3368,9 +3424,11 @@
RANGE:
-
TARGET:
-
-
+
POINT COST:
@@ -3484,7 +3542,11 @@
Activation Time:
Point Cost:
Range:
-
Target:
+
Duration:
Concentration
@@ -4081,6 +4143,27 @@
GENERAL OPTIONS
+
@@ -4440,6 +4523,9 @@
+
+
+
@@ -4497,6 +4586,11 @@
How do you want to create this character?
-
-
-
-
Strength
- -
-
-
-
Dexterity
- -
-
-
-
Constitution
- -
-
-
-
Intelligence
- -
-
-
-
Wisdom
- -
-
-
-
Charisma
- -
-
-
-
- Hit Points :
- Suggested Abilities:
- Class Spellcasting Ability:
-
-
-
-
-
-
-
Strength
- -
-
-
-
Dexterity
- -
-
-
-
Constitution
- -
-
-
-
Intelligence
- -
-
-
-
Wisdom
- -
-
-
-
Charisma
- -
-
-
-
- Hit Points :
- Spellcasting DC:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Roll
- i
-
-
-
-
- Type:
-
-
- Weapon
- Armor
- Skill
- Tool
- Language
-
-
-
-
-
-
-
- Add another proficiency
-
-
-
-
-
-
-
-
-
-
- Add another feature
-
-
-
-
-
-
-
-
-
-
-
Removed spells will be marked with a r symbol so you can find it easily if you change your mind.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- i
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ability Score
-
-
-
- Feat
-
-
-
-
You can increase two of your abilities by 1, or one of your abilities by 2
-
-
-
-
lock
-
+
-
- +
- -
-
-
Strength
-
-
-
-
lock
-
+
-
- +
- -
-
-
Dexterity
-
-
-
-
lock
-
+
-
- +
- -
-
-
Constitution
-
-
-
-
lock
-
+
-
- +
- -
-
-
Intelligence
-
-
-
-
lock
-
+
-
- +
- -
-
-
Wisdom
-
-
-
-
lock
-
+
-
- +
- -
-
-
Charisma
-
-
-
-
-
- Choose
-
-
-
-
-
-
-
-
- Roll
- Average
-
-
-
-
-
-
-
-
-
-
Welcome to the Charactermancer!
-
The Charactermancer is step-by-step process that makes building a character simple and streamlined. Changes are saved as you progress, but have no fear. The character sheet is only updated when you have completed your review.
-
Your Compendium Awaits.
-
The Charactermancer currently supports Dungeons & Dragons 5th Edition SRD, Player's Handbook, and Guildmasters' Guide to Ravnica. You can add the Player's Handbook and Guildmasters' Guide to Ravnica to your compendium in the Marketplace, or the game owner can share their compendium with everyone in the game.
-
Get started by clicking "Next".
-
-
- OPT OUT
- Back to Top
- Next
-
-
-
Where would you like to go, traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Choose a race:
-
- Choose
- Custom
-
- i
-
-
- Custom Race Name:
-
-
-
-
-
-
- Alignment:
-
- Choose
- Lawful Good
- Neutral Good
- Chaotic Good
- Lawful Neutral
- Neutral
- Chaotic Neutral
- Lawful Evil
- Neutral Evil
- Chaotic Evil
-
-
-
-
-
Size:
-
-
- Choose
- Tiny
- Small
- Medium
- Large
- Huge
- Gargantuan
-
-
-
-
-
-
-
-
Subrace:
-
- Choose
- Custom
-
- i
-
-
- Custom Subrace Name:
-
-
-
-
-
-
-
- Innate Powers:
- Esper Ability:
-
- Choose
- Strength
- Dexterity
- Constitution
- Intelligence
- Wisdom
- Charisma
-
-
- Number of Primes:
-
-
- Powers List:
-
- Choose
- Adept
- Cybermancer
- Engineer
- Hunter
- Melder
- Sentinel
-
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard any choices made and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Choose a class:
-
- Choose
- Custom
-
- i
-
-
- Custom Class Name:
-
-
-
-
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Ability Score Method:
-
- Choose
- Custom
-
-
-
-
-
Select your choices:
-
Clear Assignment
-
-
-
Select your choices:
-
- (4d6, drop lowest)
- Clear Assignment
-
-
-
-
- We rolled your dice! Check the chat window to view your results in detail. Assign the results below to your preferred attributes:
-
-
-
-
Select your choices:
-
- Available Points:
- Clear Assignment
-
-
-
-
-
-
- Strength:
-
-
-
- Dexterity:
-
-
-
- Constitution:
-
-
-
- Intelligence:
-
-
-
- Wisdom:
-
-
-
- Charisma:
-
-
-
-
-
-
-
-
Input your scores:
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
Choose a Background :
-
- Choose
- Custom
-
-
-
- Name:
-
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- You have not yet selected a class.
-
-
- You have created a custom class; you can add equipment to the character sheet after you have finished the Charactermancer.
-
-
- Pick your equipment:
- Class : ( )
-
-
-
- How would you like to choose your equipment?
- Class : ( )
-
-
- Choose
- Class Equipment
- Starting Wealth (Core)
-
-
-
-
-
- Equipment from Class
- ( )
-
-
- Starting Cubil:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Choose
-
-
- Choose
-
-
-
-
-
- Choose
-
-
- Choose
-
-
-
-
-
- Choose
-
-
- Choose
-
-
-
-
-
- Choose
-
-
- Choose
-
-
-
- NO CLASS HAS BEEN SELECTED OR SELECTED CLASS DOES NOT HAVE STANDARD EQUIPMENT. CLASS EQUIPMENT CANNOT BE CHOSEN AT THIS TIME.
-
-
-
- You have not yet selected a background.
-
-
- Equipment from Background
- ( )
-
-
- You have chosen starting cubil and do not get equipment from your background.
-
-
-
-
-
-
-
-
-
- Choose
-
-
-
-
-
- Choose
-
-
-
-
-
- Choose
-
-
-
-
-
- Choose
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
Cosmic forces are a mystery to you.
-
Your character doesn't have spells at this level. Click "Next" to review your character!
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
A feat represents accomplishment, grit, determination, and expertise. It is the reward for hard work.
-
You really haven't done that much yet.
-
-
-
- Choose a feat:
-
- Choose
-
-
-
-
-
-
Prerequisite:
-
- Look carefully! Prerequisites are not checked automatically.
-
-
-
-
Ability Score Increase:
-
-
- Choose
-
-
-
-
-
-
Skill Proficiencies :
-
-
- Choose
-
-
- Choose
-
-
- Choose
-
-
- Choose
-
-
-
-
-
Weapon Proficiencies :
-
-
- Choose
-
-
- Choose
-
-
- Choose
-
-
- Choose
-
-
-
-
-
Armor Proficiencies :
-
-
- Choose
-
-
- Choose
-
-
- Choose
-
-
- Choose
-
-
-
-
-
-
Expertise
-
-
- Choose
- Custom
-
-
- Choose
- Custom
-
-
-
-
-
-
- Choose
- Custom
-
-
-
-
-
-
-
- Choose
- Custom
-
-
-
-
-
-
-
- Choose
- Custom
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
The only choice left is to press on or turn back. If you're editing an existing character, all your existing data will be lost into the void when you apply your changes.
-
-
Review your choices:
-
-
-
Race
-
-
-
- Return to:
- RACE
-
-
-
-
Class
-
-
-
- Return to:
- CLASS
-
-
-
-
Abilities
-
-
-
- Return to:
- ABILITIES
-
-
-
-
Background
-
-
-
- Return to:
- BACKGROUND
-
-
-
-
Equipment
-
-
-
- Return to:
- EQUIPMENT
-
-
-
-
Powers
-
-
-
- Return to:
- SPELLS
-
-
-
-
-
-
-
- Back
- Back to Top
- Apply Changes
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Save and Exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
Building your character...
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Welcome to the Charactermancer Level Up!
-
Look at you, with all that experience. Now it's time to claim your reward. You'll walk through the step-by-step process to make a few decisions, and your character will be at the next level in no time. Changes are saved as you move through the process, but if you change your mind, you'll need to revisit the steps and choices that come after.
-
Your Compendium Awaits.
-
The Charactermancer currently supports Dungeons & Dragons 5th Edition SRD, Player's Handbook, and Guildmasters' Guide to Ravnica. Xanathar's Guide to everything will be supported in the coming weeks. You can add the Player's Handbook and Guildmasters' Guide to Ravnica to your compendium in the Marketplace, or the game owner can share their compendium with everyone in the game.
-
Get started by clicking "Next".
-
- OPT OUT
- Back to Top
- Next
-
-
-
Where would you like to go, traveler?
-
Discard and exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CANCEL
-
-
-
-
Your existing class levels have been pre-populated for you. By default your primary class has been set to be increased by one level. You can change how many levels to increase below, as well as adding a new multiclass.
-
In each class section you'll have the option to take the average number of hit points or to roll randomly, choose class features for the levels you're advancing, and choose your subclass if appropriate.
-
-
-
-
-
-
-
-
- The Level Up tool does not support custom classes at this time.
-
-
-
-
HP
-
-
-
- Roll
-
-
- Average
-
-
9
-
-
-
-
Class Features:
-
i
-
-
-
-
-
- Choose
-
-
-
-
-
Subclass Features:
-
i
-
-
-
-
-
-
-
- Choose
-
-
-
-
-
-
-
-
-
-
HP
-
-
-
- Roll
-
-
- Average
-
-
9
-
-
-
-
Class Features:
-
i
-
-
-
-
-
- Choose
-
-
-
-
-
Subclass Features:
-
i
-
-
-
-
-
-
-
HP
-
-
-
- Roll
-
-
- Average
-
-
9
-
-
-
-
Class Features:
-
i
-
-
-
-
-
- Choose
-
-
-
-
-
Subclass Features:
-
i
-
-
-
-
-
-
-
- Choose
-
-
-
-
-
-
-
-
-
-
HP
-
-
-
- Roll
-
-
- Average
-
-
9
-
-
-
-
Class Features:
-
i
-
-
-
-
-
- Choose
-
-
-
-
-
Subclass Features:
-
i
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CANCEL
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
- CANCEL
-
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
- CANCEL
-
-
-
-
-
Listed here are the current spells your character already knows. If you gained access to more spells during your advancement you will be able to select them below. Check next to the spells you wish to learn. The Charactermancer will help you pick the right number of spells and from the correct list. If your class has the option to swap out spells, you can do so by unselecting currently known spells which will allow you to select new ones in their place.
-
-
-
-
-
-
- Back
- Back to Top
- Next
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- CANCEL
-
-
-
-
-
-
Powers
-
-
-
- Return to:
- SPELLS
-
-
-
- Back
- Back to Top
- Apply Changes
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
- CANCEL
-
-
-
-
-
-
-
-
- Back to Top
- Accept
-
-
-
Where would you like to go, Traveler?
-
Discard and exit
-
Continue Charactermancer
-
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
@@ -7118,11 +5249,6 @@
Range: {{range}}
{{/range}}
- {{#target}}
-
- Target: {{target}}
-
- {{/target}}
{{#pointcost}}
Point Cost: {{pointcost}}
@@ -7605,7 +5731,9376 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Esper_Genesis_5E/EG_Sheet.pug b/Esper_Genesis_5E/EG_Sheet.pug
index 137af841e7..cffbe6421b 100644
--- a/Esper_Genesis_5E/EG_Sheet.pug
+++ b/Esper_Genesis_5E/EG_Sheet.pug
@@ -1,5 +1,16 @@
- var imagePath = 'https://raw.githubusercontent.com/mperes/Esper-Images/main';
+-
+ const globalAttributesByCatagory = {
+ abilities: ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma'],
+ optionalAbilites: ['honor', 'sanity'],
+ alignments: ['Lawful Good', 'Neutral Good', 'Chaotic Good', 'Lawful Neutral', 'Neutral', 'Chaotic Neutral', 'Lawful Evil', 'Neutral Evil', 'Chaotic Evil'],
+ classes: ['artificer', 'bard', 'cleric', 'druid', 'paladin', 'ranger', 'sorcerer', 'warlock', 'wizard'],
+ sizes: ['Tiny', 'Small', 'Medium', 'Large', 'Huge', 'Gargantuan'],
+ diceSizes: ['d4', 'd6', 'd8', 'd10', 'd12']
+ };
+
+
include src/mixins/mixins.pug
input(name='attr_version' type='hidden' value!='3.0')
@@ -9,6 +20,7 @@ input.licensedsheet(name='attr_licensedsheet' type='hidden')
.licensecontainer.compendium-drop-target.monsters.ships(data-licensedsheet='attr_licensedsheet')
input.npc_toggle(name='attr_npc' type='hidden' value!='0')
+ input.npcspellcastingflag(name='attr_npcspellcastingflag' type='hidden' value!='0')
input.sheet-pc-type(name='attr_pc_sheet_type' type='hidden' value='pc')
input.npcspellcastingflag(name='attr_npcspellcastingflag' type='hidden')
input.toggleflag(name='attr_rtype' type='hidden')
@@ -57,6 +69,10 @@ input.licensedsheet(name='attr_licensedsheet' type='hidden')
.mancer_confirm
span(style='line-height: 25px' data-i18n='do_you_want_mancer') How do you want to create this character?
div(style='margin-top: 20px;')
+ //
+ div(style='position: relative; display: inline-block; width:130px;')
+ input.yes(type='checkbox' style='width:130px;' name='attr_mancer_confirm')
+ span.yes(style='width:130px;' data-i18n='mancer-confirm-yes') Use the Charactermancer
div(style='position: relative; display: inline-block; width:80px;')
input.yes(style='width:80px;' type='checkbox' name='attr_mancer_npc')
span.yes(style='width:80px;' data-i18n='npc-new') Create an NPC
@@ -64,12 +80,32 @@ input.licensedsheet(name='attr_licensedsheet' type='hidden')
input.yes(type='checkbox' style='width:90px;' name='attr_mancer_cancel')
span.yes(style='width:90px;' data-i18n='manual') Edit sheet direclty
-include src/charactermancer/repeating/repeating.html
-include src/charactermancer/l1/l1.html
-include src/charactermancer/lp/lp.html
-include src/hiddeninputs/hiddeninputs.pug
-
+//- ROLL TEMPLATES
include src/rolltemplates/rolltemplates.html
-script(type='text/worker')
- include sheetworkers.js
+//- CHARACTERMANCER REPEATING SECTIONS
+ include src/charactermancer/repeating/repeatingsections.html
+
+//- CHARACTERMANCER LEVEL 1
+ include src/charactermancer/l1/l1.pug
+
+//- CHARACTERMANCER LEVEL UP
+ include src/charactermancer/lp/lp.pug
+
+//- HIDDEN INPUTS
+include src/hiddeninputs/hiddeninputs.pug
+
+//- SHEET WORKERS
+script(type="text/worker")
+ include src/helpers/helperFunctions.js
+ include src/classes/SheetUtils/SheetUtils.js
+ include src/classes/FlagManager/FlagManager.js
+ include src/classes/SheetUpdater/SheetUpdater.js
+ include src/classes/DropClasses/DropClasses.js
+ include src/dragndrop/dropFunctions.js
+ include src/dragndrop/DragAndDrop.js
+ include src/charactermancer/l1/l1.js
+ include src/charactermancer/lp/lp.js
+
+ //include src/js/versioning.js
+ include sheetworkers.js
diff --git a/Esper_Genesis_5E/EG_Sheet.sass b/Esper_Genesis_5E/EG_Sheet.sass
index 03b6c2b67c..6ac492692a 100644
--- a/Esper_Genesis_5E/EG_Sheet.sass
+++ b/Esper_Genesis_5E/EG_Sheet.sass
@@ -60,7 +60,7 @@ input[type=radio]
.sheet-advantagetoggle
position: absolute
top: 92px
- left: 570px
+ left: 440px
z-index: 1
input[type=radio]
@@ -119,7 +119,7 @@ input[type=radio].sheet-tab-button:checked + span, .sheet-advantagetoggle input[
width: 110px
.sheet-whispertoggle
- left: 270px
+ left: 150px
.sheet-advantagetoggle.sheet-whispertoggle input
&.sheet-toggle-right
@@ -182,7 +182,7 @@ input[type=radio].sheet-tab-button:checked + span, .sheet-advantagetoggle input[
visibility: visible
.sheet-col
- display: block
+ //display: block
.sheet-hidden, .sheet-options .sheet-row.sheet-hidden
display: none
@@ -1317,11 +1317,29 @@ button[type=roll] *
position: relative
-.charsheet .sheet-spells .sheet-details span
- font-size: 12px
+.charsheet .sheet-spells .sheet-details
+ span
+ font-size: 12px
- &[name="attr_spelldescription"]
- white-space: pre-line
+ &[name="attr_spelldescription"]
+ white-space: pre-line
+
+ > .sheet-italics
+ span
+ &:nth-last-child(3)
+ display: inline-block
+ width: 120px
+ text-align: left
+ text-transform: lowercase
+ &::first-letter
+ text-transform: uppercase
+ &:not(:first-child)
+ margin-left: 3px
+
+ span[data-i18n="concentration"]
+ margin-left: -3px
+ &:after
+ content:', '
.repcontainer .sheet-spell .sheet-details-flag:not(:checked) ~ .sheet-wrapper
display: none
@@ -1371,6 +1389,7 @@ button[type=roll] *
&.sheet-bold
font-weight: bold
+ margin-right: 3px
.sheet-italics
font-style: italic
@@ -2399,6 +2418,8 @@ span
.sheet-display .sheet-red
input, span
color: #245485
+ &:first-child
+ margin-right: 3px
.sheet-npc_options
input
@@ -2507,6 +2528,9 @@ span
&:before
content: "("
+
+ &.sheet-xp:before
+ content: " ("
&:after
content: ")"
@@ -3691,6 +3715,8 @@ span
.sheet-topbar div.sheet-meta-info-container span, .sheet-leveler-topbar div.sheet-meta-info-container span
font-size: 1.2em
+ .sheet-choice
+ display: none!important
.sheet-topbar div.sheet-meta-info-container span.sheet-choice, .sheet-leveler-topbar div.sheet-meta-info-container span.sheet-choice
display: none
@@ -3955,6 +3981,120 @@ span
.sheet-gold_option input[type=number]
width: 4.5em
+
+ .sheet-customize-origin
+ box-sizing: border-box
+ padding-right: 40px
+ position: relative
+ width: 100%
+ display: none
+
+ label
+ span
+ display: block
+
+ &:first-child
+
+ &:last-child
+ font-weight: normal
+ width: calc(100% + 40px)
+
+ .sheet-toggle
+ box-sizing: border-box
+ position: absolute
+ top: 0
+ right: 0
+ width: 40px
+ height: 20px
+ overflow: hidden
+ border-radius: 10px
+ border: 1px solid #CCC
+
+ input
+ width: 100%
+ height: 100%
+ appearance: none
+ border: 0
+ padding: 0
+ margin: 0
+ position: absolute
+ top: 0
+ left: 0
+ outline: none
+
+ &:checked
+ background: #c43c41
+
+ .sheet-knob
+ width: 20px
+ height: 20px
+ background: #CCC
+ position: absolute
+ top: -1px
+ left: -1px
+ border-radius: 10px
+ pointer-events: none
+
+ input:checked + .sheet-knob
+ right: -1px
+ left: auto
+
+ input[value="1"] + .sheet-customize-origin
+ display: block
+
+ span.sheet-tasha + select
+ margin-bottom: 10px
+
+ @for $i from 1 through 20
+ input[value='#{$i}'] + span.sheet-tasha:after
+ content: " (+#{$i}):"
+
+ .sheet-asi-row
+ .sheet-asi
+ border-width: 1px!important
+
+ .sheet-switch ~ .sheet-switch-container .sheet-feat-tab
+ pointer-events: all
+
+ .sheet-asi, .sheet-feat
+ display: none
+
+ .sheet-switchval
+ &[value="asi"] ~ .sheet-asi, &[value="feat"] ~ .sheet-feat
+ display: block
+ border-color: #888
+ border-style: solid
+ border-width: 0 1px 1px 1px
+ border-radius: 0 0 4px 4px
+ padding: 1em
+
+ &[value="asi"] ~ .sheet-switch-container .sheet-asi-tab, &[value="feat"] ~ .sheet-switch-container .sheet-feat-tab
+ border-bottom-width: 0
+ background-color: white
+
+ .sheet-spinnerloader
+ width: 40%
+ padding-right: 13px
+ height: 100px
+ background-image: url('https://app.roll20.net/images/load.gif')
+ background-repeat: no-repeat
+ background-position: center center
+ display: inline-block
+ box-sizing: border-box
+ position: relative
+
+ .sheet-spinner-toggle
+ display: none
+
+ &:empty
+ + .sheet-spinnerloader
+ display: none
+
+ ~ .sheet-choices
+ display: block
+
+ ~ .sheet-choices
+ display: none
.sheet-manver .sheet-yes_spells
display: -webkit-box
@@ -4392,7 +4532,7 @@ span
border-color: #888
border-style: solid
border-radius: 4px 4px 0 0
- border-width: 1px
+ border-width: 1px 1px 0 1px
background-color: #aaa
padding: .25em .5em
margin: 0
@@ -5717,8 +5857,7 @@ div.sheet-charmancer
flex-flow: column
margin-bottom: 1em
- div.sheet-licensedsheet-flag:not(:empty) ~
- * .sheet-logos, .sheet-logos
+ .sheet-logos, .sheet-logos
display: -webkit-box
display: -ms-flexbox
display: flex
@@ -5730,7 +5869,7 @@ div.sheet-charmancer
flex-flow: column
margin-bottom: 1em
- &.sheet-licensedsheet .sheet-charmancer-logo
+ .sheet-charmancer-logo
margin: 0 auto
background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/charactermancer-1.png")
background-position: center
@@ -5742,8 +5881,7 @@ div.sheet-charmancer
width: 70%
height: 5em
- div.sheet-licensedsheet-flag:not(:empty) ~
- * .sheet-charmancer-logo, .sheet-charmancer-logo
+ .sheet-charmancer-logo, .sheet-charmancer-logo
margin: 0 auto
background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/charactermancer-1.png")
background-position: center
@@ -5757,7 +5895,7 @@ div.sheet-charmancer
&.sheet-licensedsheet .sheet-compendium-logo
margin: 0 auto
- background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/DnDlogored.png")
+ background: url("https://raw.githubusercontent.com/skydawn1/esper_genesis/master/EG_Logo.png")
background-position: center
background-size: contain
background-repeat: no-repeat
@@ -5767,10 +5905,9 @@ div.sheet-charmancer
width: 50%
height: 3em
- div.sheet-licensedsheet-flag:not(:empty) ~
- * .sheet-compendium-logo, .sheet-compendium-logo
+ .sheet-compendium-logo, .sheet-compendium-logo
margin: 0 auto
- background: url("https://raw.githubusercontent.com/mperes/Images-for-Roll20-5E-images/master/licensedsheet/DnDlogored.png")
+ background: url("https://raw.githubusercontent.com/skydawn1/esper_genesis/master/EG_Logo.png")
background-position: center
background-size: contain
background-repeat: no-repeat
@@ -6658,7 +6795,7 @@ div.sheet-charmancer
.sheet-table-header
grid-template-columns: 45px 1fr 60px 30px 50px 70px
grid-gap: 2px
- max-width: calc(50% - 10px)
+ max-width: calc(50% - 30px)
span
font-size: 11px
@@ -6669,6 +6806,21 @@ div.sheet-charmancer
.repitem
border-top: 2px solid #e2c285
+ margin-right: 20px
+
+ button[type='roll']
+ position: absolute
+ top: 4px
+ right: -20px
+ background: none
+ border: none
+ color: black
+ box-shadow: none
+ margin: 0
+ padding: 0
+ font-weight: bold
+ &:hover
+ color: #00ba73
.sheet-table-body
grid-template-columns: 45px 1fr 60px 30px 50px 70px
diff --git a/Esper_Genesis_5E/sheetworkers.js b/Esper_Genesis_5E/sheetworkers.js
index 4af2a6e1cf..4a84a8c1be 100644
--- a/Esper_Genesis_5E/sheetworkers.js
+++ b/Esper_Genesis_5E/sheetworkers.js
@@ -1,3 +1,59 @@
+// Create a collective list of attributs to reduce redundancy
+var abilityList = ["Strength", "Dexterity", "Constitution", "Intelligence", "Wisdom", "Charisma"];
+var abilityListEnabledOptionals = [];
+const globalAttributesByCategory = {
+ abilities: ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma'],
+ abilitiesWithAllOptionals: ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma', 'honor', 'sanity'],
+ //classes: ['artificer','barbarian','bard','cleric','druid','fighter','monk','paladin','ranger','rogue','sorcerer','warlock','wizard'],
+ classes: ['adept', 'cybermancer', 'engineer', 'hunter', 'melder', 'sentinel', 'specialist', 'warrior'],
+ hitDieTypes: ['d4', 'd6', 'd8', 'd10', 'd12'],
+ traitsTypes: ['Background', 'Feats', 'Racial', 'Class', 'Other'],
+ proficiencyTypes: ['LANGUAGE', 'ARMOR', 'WEAPON', 'OTHER'],
+ skills: {
+ strength: [
+ 'athletics'
+ ],
+ constitution: [],
+ dexterity: [
+ 'acrobatics',
+ 'sleight_of_hand',
+ 'stealth',
+ ],
+ intelligence: [
+ 'arcana',
+ 'history',
+ 'investigation',
+ 'nature',
+ 'religion',
+ ],
+ wisdom: [
+ 'animal_handling',
+ 'insight',
+ 'medicine',
+ 'perception',
+ 'survival'
+ ],
+ charisma: [
+ 'deception',
+ 'intimidation',
+ 'performance',
+ 'persuasion',
+ ],
+ honor: [],
+ sanity: [],
+ all: () => { return [...globalAttributesByCategory.skills.strength, ...globalAttributesByCategory.skills.dexterity, ...globalAttributesByCategory.skills.intelligence, ...globalAttributesByCategory.skills.wisdom, ...globalAttributesByCategory.skills.charisma]; },
+ getParentAbility: skill => {
+ let parent = '';
+ globalAttributesByCategory['abilities'].forEach(ability => {
+ if(globalAttributesByCategory.skills[ability].indexOf(skill) > -1) {
+ parent = ability;
+ return;
+ }
+ });
+ return parent;
+ }
+ }
+};
on("sheet:opened", function(eventinfo) {
versioning(function() {
@@ -297,25 +353,6 @@ on("change:race change:subrace", function(eventinfo) {
update_race_display();
});
-on("change:drop_category", function(eventinfo) {
- if(eventinfo.newValue === "Monsters" || eventinfo.newValue === "Ships") {
- getAttrs(["class","race","speed","hp"], function(v) {
- if(eventinfo.newValue === "Ships") {
- setAttrs({npc_tab: "ships"});
- }
- if(v["class"] != "" || v["race"] != "" || v["speed"] != "" || v["hp"] != "") {
- setAttrs({monster_confirm_flag: 1});
- }
- else {
- handle_drop(eventinfo.newValue);
- }
- });
- }
- else {
- handle_drop(eventinfo.newValue);
- }
-});
-
on(`change:repeating_inventory:hasattack`, function(eventinfo) {
if(eventinfo.sourceType && eventinfo.sourceType === "sheetworker") {return;};
@@ -1136,1125 +1173,6 @@ var get_repeating_data = function(callback) {
});
};
-var handle_drop = function(category, eventinfo) {
-
- getAttrs(["speed", "drop_name", "drop_data", "drop_content", "character_id", "npc_legendary_actions", "strength_mod", "dexterity_mod", "npc", "base_level", "strength_base", "dexterity_base", "constitution_base", "wisdom_base", "intelligence_base", "charisma_base", "class_resource_name", "other_resource_name", "multiclass1_lvl", "multiclass2_lvl", "multiclass3_lvl"], function(v) {
- var pagedata = {};
- try {
- pagedata = JSON.parse(v.drop_data);
- } catch(e) {
- pagedata = v.drop_data;
- }
- var page = {
- name: v.drop_name,
- data: pagedata,
- content: v.drop_content
- };
- var category = page.data["Category"];
- get_repeating_data(function(repeating) {
- var results = processDrop(page, v, repeating);
- setAttrs(results.update, {silent: true}, function() {results.callbacks.forEach(function(callback) {callback(); })} );
- });
-
- });
-
-};
-
-var processDrop = function(page, currentData, repeating, looped) {
- var jsonparse = function(data) {
- var result = {};
- try {
- result = JSON.parse(data);
- } catch(e) {
- result = data;
- }
- return result;
- };
- var modStringToAttrib = function(modString) {
- var finalAttrib = "";
- if (modString == "FIN") {
- if (parseInt(currentData.strength_base) > parseInt(currentData.dexterity_base)) {
- finalAttrib = "@{strength_mod}";
- } else {
- finalAttrib = "@{dexterity_mod}";
- }
- } else {
- switch(modString) {
- case "STR":
- finalAttrib = "@{strength_mod}";
- break;
- case "DEX":
- finalAttrib = "@{dexterity_mod}";
- break;
- case "CON":
- finalAttrib = "@{constitution_mod}";
- break;
- case "WIS":
- finalAttrib = "@{wisdom_mod}";
- break;
- case "INT":
- finalAttrib = "@{intelligence_mod}";
- break;
- case "CHA":
- finalAttrib = "@{charisma_mod}";
- break;
- }
- }
- return finalAttrib;
- };
- var numUses = function(uses_string) {
- uses_string = parseValues(uses_string);
-
- var terms = uses_string.split("+");
- var total = 0;
- _.each(terms, function(term) {
- total += parseInt(term);
- });
- return uses_string === "" || uses_string === "-" ? uses_string : total;
- };
- var parseValues = function(uses_string) {
- var attribs = ["strength", "dexterity", "constitution", "wisdom", "intelligence", "charisma"];
- uses_string = uses_string ? uses_string.toLowerCase() : "";
- _.each(attribs, function(attrib) {
- var attribMod = Math.floor((parseInt(currentData[attrib + "_base"]) - 10) / 2);
- if (attribMod < 0 || isNaN(attribMod)) attribMod = 0;
- uses_string = uses_string.replace(attrib, attribMod);
- });
- uses_string = uses_string.replace(/half_level/g, Math.floor(classlevel/2));
- return uses_string.replace(/level/g, classlevel);
- };//
- var category = page.data["Category"];
- var callbacks = [];
- var update = {};
- var id = generateRowID();
- var blobs = {};
- var classlevel = currentData.base_level ? parseInt(currentData.base_level) : 1;
- repeating.traits = repeating.traits ? repeating.traits : [];
- update["drop_category"] = "";
- update["drop_name"] = "";
- update["drop_data"] = "";
- update["drop_content"] = "";
- if(category === "Items") {
- console.log(`%c ITEM: ${page.name} dropped`, "color: purple; font-size: 14px;");
- if(currentData.npc === "0") {
- update["tab"] = "core";
- if(page.name) {update[`repeating_inventory_${id}_itemname`] = page.name};
- if(page.data["itemcount"]) {update[`repeating_inventory_${id}_itemcount`] = page.data["itemcount"]};
-
- ["Properties", "Weight"].forEach((attr) => {
- if (page.data[`${attr}`]) {
- update[`repeating_inventory_${id}_item${attr.toLowerCase()}`] = page.data[`${attr}`]
- };
- });
-
- if(page.content) {update[`repeating_inventory_${id}_itemcontent`] = page.content};
- if(!page.data["Item Type"] || page.data["Item Type"] == "") {page.data["Item Type"] = category};
- var mods = "Item Type: " + page.data["Item Type"];
- if(page.data["AC"] && page.data["AC"] != "") {
- mods += ", AC: " + page.data["AC"];
- if(!looped) {
- callbacks.push(() => {update_ac();} )
- }
- };
-
- ["Damage", "Damage Type", "Secondary Damage", "Secondary Damage Type", "Alternate Damage", "Alternate Damage Type", "Alternate Secondary Damage", "Alternate Secondary Damage Type", "Range"].forEach((attr) => {
- if (page.data[`${attr}`] && page.data[`${attr}`] != "") {
- mods += `, ${attr}: ${page.data[`${attr}`]}`
- };
- });
-
- if(page.data["Modifiers"] && page.data["Modifiers"] != "") { mods += `, ${page.data["Modifiers"]}` };
- update[`repeating_inventory_${id}_itemmodifiers`] = mods;
- if(page.data["Item Type"].indexOf("Weapon") > -1) {
- update[`repeating_inventory_${id}_hasattack`] = 1;
- callbacks.push(() => {
- (page.data["Alternate Damage"] && page.data["Alternate Damage"] !== "") ? create_attack_from_item(id, {versatile: true}) : create_attack_from_item(id);
- });
- } else if(page.data["Item Type"].indexOf("Ammunition") > -1) {
- update[`repeating_inventory_${id}_useasresource`] = 1;
- callbacks.push(() => { create_resource_from_item(id); });
- };
-
- if(page.data["Modifiers"]) {
- callbacks.push(() => { check_itemmodifiers(page.data["Modifiers"]); });
- };
-
- if(!looped) {
- callbacks.push(() => { update_weight(); });
- }
- } else {
- if(page.data["Item Type"] && page.data["Item Type"].toLowerCase().includes("weapon")) {
- const type = (page.data["Item Type"]) ? page.data["Item Type"].toLowerCase().split(" ")[0] : " ";
- const properties = (page.data["Properties"]) ? page.data["Properties"].toLowerCase() : undefined;
-
- const make_npc_attack_from_item = (rowid, options) => {
- update[`repeating_npcaction_${rowid}_npc_options-flag`] = "0";
- update[`repeating_npcaction_${rowid}_attack_flag`] = "on";
- if(page.name) {
- update[`repeating_npcaction_${rowid}_name`] = page.name;
- if (options && options.versatile) {
- update[`repeating_npcaction_${rowid}_name`] += " (" + (options.versatile === 1 ? "One-Handed" : "Two-Handed") + ")";
- } else if (options && options.thrown) {
- update[`repeating_npcaction_${rowid}_name`] += " (Thrown)";
- };
- };
- if(page.content) { update[`repeating_npcaction_${rowid}_description`] = page.content; }
-
- update[`repeating_npcaction_${rowid}_attack_display_flag`] = "{{attack=1}}";
- update[`repeating_npcaction_${rowid}_attack_options`] = "{{attack=1}}";
- update[`repeating_npcaction_${rowid}_attack_type`] = page.data["Item Type"];
- update[`repeating_npcaction_${rowid}_attack_target`] = "one target";
-
-
- update[`repeating_npcaction_${rowid}_attack_range`] =
- (page.data["Range"] && page.data["Range"] != "" && (!properties.includes("thrown") || (options && options.thrown))) ? page.data["Range"] :
- (page.data["Properties"] && properties.includes("range")) ? "10 ft" :
- "5 ft";
-
- const weapon_attr_mod = (type.includes("ranged") || (properties && properties.includes("finesse") && currentData.dexterity_mod > currentData.strength_mod)) ? currentData.dexterity_mod : currentData.strength_mod;
- update[`repeating_npcaction_${rowid}_attack_tohit`] = weapon_attr_mod;
-
- const dmgArray = (options && options.versatile === 2) ?
- ["Alternate Damage", "Alternate Damage Type", "Alternate Secondary Damage", "Alternate Secondary Damage Type"] :
- ["Damage", "Damage Type", "Secondary Damage", "Secondary Damage Type"];
-
- dmgArray.forEach((attr) => {
- if (page.data[`${attr}`]) {
- // _attack_damage adds the weapon mod
- const ending = (dmgArray.indexOf(`${attr}`) === 0) ? `+${weapon_attr_mod}` : "";
- //Remove Alternate for the attribute name. Then check for Secondary and remote it while adding 2.
- let attrEdit = (attr.includes("Alternate") && attr.includes("Secondary")) ? attr.slice(20) + "2" : (attr.includes("Alternate") || attr.includes("Secondary")) ? attr.slice(10) : attr;
- //Lower case everything and remove spaces
- let name = attrEdit.toLowerCase().replace(" ", "");
- //Set all the necessary attack attributes
- update[`repeating_npcaction_${rowid}_attack_${name}`] = page.data[`${attr}`] + [`${ending}`];
- };
- });
-
- if(page.data["Modifiers"]) {
- if(type === "melee" || type === "ranged") {
- //+1 Weapons should be in the format of "Melee Attacks +1, Melee Damage +1"
- const split = (page.data["Modifiers"].includes(",")) ? page.data["Modifiers"].split(", ") : page.data["Modifiers"];
- split.forEach((attr) => {
- const name = attr.toLowerCase();
- if (name.includes("attacks")) {
- update[`repeating_npcaction_${rowid}_attack_tohit`] = +update[`repeating_npcaction_${rowid}_attack_tohit`] + name.split("attacks ")[1];
- } else if (name.includes("damage")) {
- update[`repeating_npcaction_${rowid}_attack_damage`] += name.split("damage ")[1];
- } else {
- console.log(`%c ${page.name} modifiers format did not include damage or attacks`, "color:orange;");
- };
- });
- };
- };
- };
-
- const versatile = (properties && properties.includes("versatile")) ? 1 : undefined;
- make_npc_attack_from_item(id, {versatile: versatile});
-
- if (properties && properties.includes("thrown")) {
- make_npc_attack_from_item(generateRowID(), {thrown: true});
- }
- if (versatile && page.data["Alternate Damage"]) {
- make_npc_attack_from_item(generateRowID(), {versatile: 2})
- }
-
- if (page.data["Modifiers"]) {
- callbacks.push(() => { check_itemmodifiers(page.data["Modifiers"]); }, () => { update_npc_action("all"); });
- } else {
- callbacks.push(() => { update_npc_action("all"); });
- };
- }
- }
- };
- if(category === "Powers") {
- console.log(`%c SPELL: ${page.name} dropped`, "color: purple; font-weight:14px;");
- let existing = {};
- var lvl = page.data["Level"] && page.data["Level"] > 0 ? page.data["Level"] : "prime";
- if (repeating[`spell-${lvl}`]) {
- _.each(repeating[`spell-${lvl}`], (spell, spellid) => {
- if (spell.spellname.toLowerCase() === page.name.toLowerCase()) {
- id = spellid;
- existing = spell;
- };
- });
- }
- if(currentData.npc && currentData.npc == 1) update['npcspellcastingflag'] = 1;
- update[`repeating_spell-${lvl}_${id}_spelllevel`] = lvl;
- update[`repeating_spell-${lvl}_${id}_spell_ability`] = (page.data["spellcasting_ability"]) ? `@{${page.data["spellcasting_ability"].toLowerCase()}_mod}+` : "spell";
- (page.name) ? update[`repeating_spell-${lvl}_${id}_spellname`] = page.name : false;
-
- ["spellclass", "spellsource", "data-description"].forEach((attr) => {
- const suffix = (attr.includes("description")) ? "spelldescription" : attr;
- (page.data[`${attr}`]) ? update[`repeating_spell-${lvl}_${id}_${suffix}`] = page.data[`${attr}`] : false;
- });
-
- ["Add Casting Modifier", "Activation Time", "Concentration", "Damage Type", "Damage", "Duration", "Healing", "Material", "Range", "Ritual", "Save", "Save Success", "Domain", "Secondary Damage", "Secondary Damage Type", "Target"].forEach((attr) => {
- if(page.data[`${attr}`]) {
- //Adjust the array entry to match the attribute name in the HTML
- const name = (attr === "Add Casting Modifier") ? "dmgmod" : (attr === "Material") ? `comp_materials` : (attr.includes("Secondary Damage")) ? attr.split("Secondary ")[0] + "2" : attr;
- const spellattribute = name.toLowerCase().replace(" ", "");
- //Concentration, Ritual, and Domain are exceptions to norm
- const updateValue = (attr === "Concentration" || attr === "Ritual") ? `{{${spellattribute}=1}}` : (attr === "Domain") ? page.data["Domain"].toLowerCase() : page.data[`${attr}`];
- update[`repeating_spell-${lvl}_${id}_spell${spellattribute}`] = updateValue;
- };
- });
-
- ["Higher Power Slot Bonus", "Higher Power Slot Desc", "Higher Power Slot Dice", "Higher Power Slot Die"].forEach((attr) => {
- if (page.data[`${attr}`]) {
- const spellattribute = (attr.includes("Bonus")) ? "hlbonus" : (attr.includes("Desc")) ? "athigherlevels" : (attr.includes("Dice")) ? "hldie" : "hldietype";
- update[`repeating_spell-${lvl}_${id}_spell${spellattribute}`] = page.data[`${attr}`];
- };
- });
-
- if(page.data["Components"]) {
- ["v", "s", "m"].forEach((comp) => {
- if(page.data["Components"].toLowerCase().indexOf(comp) === -1) {update[`repeating_spell-${lvl}_${id}_spellcomp_${comp}`] = "0"};
- });
- };
-
- if (page.data["Power Attack"]) {
- update[`repeating_spell-${lvl}_${id}_spellattack`] = page.data[`Power Attack`];
- };
-
- if(page.data["Damage"] || page.data["Healing"]) {
- update["repeating_spell-" + lvl + "_" + id + "_spelloutput"] = "ATTACK";
- if(!existing.spellattackid) callbacks.push( function() {create_attack_from_spell(lvl, id, currentData.character_id);});
- }
- else if(page.data["Higher Power Slot Desc"] && page.data["Higher Power Slot Desc"] != "") {
- var spelllevel = "?{Cast at what level?";
- for(i = 0; i < 10-lvl; i++) {
- spelllevel = spelllevel + "|Level " + (parseInt(i, 10) + parseInt(lvl, 10)) + "," + (parseInt(i, 10) + parseInt(lvl, 10));
- };
- spelllevel = spelllevel + "}";
- update[`repeating_spell-${lvl}_${id}_rollcontent`] = `@{wtype}&{template:spell} {{level=@{spellschool} ${spelllevel}}} {{name=@{spellname}}} {{castingtime=@{spellcastingtime}}} {{range=@{spellrange}}} {{target=@{spelltarget}}} @{pointcost}}} {{duration=@{spellduration}}} {{description=@{spelldescription}}} {{athigherlevels=@{spellathigherlevels}}} @{spellritual} {{innate=@{innate}}} @{spellconcentration} @{charname_output} {{licensedsheet=@{licensedsheet}}}`;
- };
-
- if(page.data["data-Prime Scaling"] && lvl == "prime") {update[`repeating_spell-${lvl}_${id}_spell_damage_progression`] = "Prime " + page.data["data-Prime Scaling"].charAt(0).toUpperCase() + page.data["data-Prime Scaling"].slice(1);};
- update[`repeating_spell-${lvl}_${id}_options-flag`] = "0";
- };
- if(category === "Monsters" || category === "Ships") {
- console.log(`%c MONSTERS: ${page.name} dropped`, "color: purple; font-weight:14px;");
- update["npc"] = "1";
- update["npc_options-flag"] = "0";
- update["licensedsheet"] = "0";
- if(page.name && page.name != "") {update["npc_name"] = page.name};
-
- //ABILITY SCORES
- const npcAbilites = ["strength", "dexterity", "constitution", "intelligence", "wisdom", "charisma"];
- npcAbilites.forEach((ability) => {
- const abbreviation = ability.slice(0, 3).toUpperCase();
- update[`${ability}_base`] = (page.data[`${abbreviation}`]) ? page.data[`${abbreviation}`] : "";
- callbacks.push(() => {
- update_attr(`${ability}`);
- });
- });
-
- const npcExtras = ["Condition Immunities", "Immunities", "Languages", "Resistances", "Speed", "Sensor Range", "Token Size", "Vulnerabilities"];
- npcExtras.forEach((attr) => {
- //console.log(`%c MONSTERS Drop: ${attr}`, "color:cornflowerblue;");
- const prefixExtra = (attr === "Token Size") ? "" : "npc_";
- let nameExtra = (attr.includes(" ")) ? attr.replace(" ", "_").toLowerCase() : attr.toLowerCase();
- update[`${prefixExtra}${nameExtra}`] = (page.data[`${attr}`]) ? page.data[`${attr}`] : "";
- });
-
- //CHALLENGE RATING
- if(page.data["Challenge Rating"] && page.data["Challenge Rating"] != "") {
- callbacks.push( function() {update_challenge();} );
- update["npc_challenge"] = page.data["Challenge Rating"];
- } else {
- update["npc_challenge"] = "";
- };
-
- //XP
- if(page.data["data-XP"]) { update["npc_xp"] = page.data["data-XP"].toString().replace(",",""); };
-
- //SIZE, TYPE, ALIGNMENT
- var type = "";
- if(page.data["Size"]) { type = page.data["Size"] };
- if(page.data["Type"]) { type = (type.length > 0) ? type + " " + page.data["Type"].toLowerCase() : page.data["Type"].toLowerCase(); };
- if(page.data["Alignment"]) { type = (type.length > 0) ? type + ", " + page.data["Alignment"] : page.data["Alignment"]; };
- update["npc_type"] = type;
-
- ["AC", "HP"].forEach((achp) => {
- //console.log(`%c MONSTERS Drop: AC & HP ${achp}`, "color:cornflowerblue;");
- const array = (achp === "AC") ? ["npc_ac", "npc_actype"] : ["hp_max", "npc_hpformula"];
- if (page.data[`${achp}`] && page.data[`${achp}`].toString().indexOf("(") > -1) {
- update[`${array[0]}`] = page.data[`${achp}`].toString().split(" (")[0];
- update[`${array[1]}`] = page.data[`${achp}`].toString().split(" (")[1].slice(0, -1);
- } else {
- update[`${array[0]}`] = (page.data[`${achp}`]) ? page.data[`${achp}`] : "";
- update[`${array[1]}`] = "";
- };
- });
-
- var senses = page.data["Senses"] ? page.data["Senses"] : "";
- if(page.data["Passive Perception"]) {
- senses = (senses.length > 0) ? senses + ", passive Perception " + page.data["Passive Perception"] : "passive Perception " + page.data["Passive Perception"];
- }
- update["npc_senses"] = senses;
-
- //SAVES & SKILLS
- const npcSavesSkills = ["str_save", "dex_save", "con_save", "int_save", "wis_save", "cha_save",'acrobatics','astrophysics','athletics','computers','deception','insight','intimidation','investigation','lore','mechanics','medicine','perception','performance','persuasion','piloting','sleight_of_hand','stealth','survival','xenobiology'];
- npcSavesSkills.forEach((attr) => {
- update[`npc_${attr}_base`] = "";
- });
- ["Saving Throws", "Skills"].forEach((attr) => {
- //console.log(`%c MONSTERS Drop: Saving Throws & Skills: ${attr}`, "color:cornflowerblue;");
- const array = (page.data[`${attr}`]) ? page.data[`${attr}`].split(", ") : [];
- _.each(array, (entry) => {
- const kv = (entry.indexOf("-") > -1) ? entry.split(" ") : entry.split(" +");
- const attribute = (attr === "Saving Throws") ? kv[0].toLowerCase() + "_save" : kv[0].toLowerCase().split(' ').join('_');
- update[`npc_${attribute}_base`] = parseInt(kv[1], 10);
- });
- (attr === "Saving Throws") ? callbacks.push(() => {update_npc_saves();} ) : callbacks.push(() => {update_npc_skills();} );
- });
-
- const npcRepeating = ['npcaction-l', 'npcreaction', 'npcaction', 'npctrait'];
- _.each(npcRepeating, (section) => {
- getSectionIDs(`repeating_${section}`, (idarray) => {
- _.each(idarray, (currentID, i) => {
- removeRepeatingRow(`repeating_${section}_${currentID}`);
- });
- });
- });
- // ACTIONS, LEGENDARY ACTIONS, REACTIONS, TRAITS
- var contentarray = page.content;
- if (page.data["data-Legendary Actions"]) {
- const actionCount = (page.data["data-LANum"]) ? page.data["data-LANum"] : 3;
- update["npc_legendary_actions"] = (page.data["data-LANum"]) ? page.data["data-LANum"] : 3;
- if (page.data["Legendary Actions Desc"]) {
- update["npc_legendary_actions_desc"] = page.data["Legendary Actions Desc"];
- } else {
- update["npc_legendary_actions_desc"] = `The ${page.name} can take ${actionCount}, 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 ${page.name} regains spent legendary actions at the start of its turn.`;
- };
- };
- // ACTIONS & LEGENDARY ACTIONS
- ["Actions", "Legendary Actions"].forEach((attr) => {
- if (page.data[`data-${attr}`]) {
- const npcaction = (attr === "Actions") ? "npcaction" : "npcaction-l";
- let actionsobj = {};
- jsonparse(page.data[`data-${attr}`]).forEach((val) => { actionsobj[val.Name] = val; });
- _.each(actionsobj, (action, name) => {
- newrowid = generateRowID();
- update[`repeating_${npcaction}_${newrowid}_npc_options-flag`] = "0";
- update[`repeating_${npcaction}_${newrowid}_name`] = name;
- (action["Desc"]) ? update[`repeating_${npcaction}_${newrowid}_description`] = action["Desc"] : false;
- if(action["Type Attack"]) {
- update[`repeating_${npcaction}_${newrowid}_attack_display_flag`] = "{{attack=1}}";
- update[`repeating_${npcaction}_${newrowid}_attack_flag`] = "on";
- update[`repeating_${npcaction}_${newrowid}_attack_options`] = "{{attack=1}}";
-
- ["Damage Type", "Damage", "Hit Bonus", "Reach", "Target", "Type"].forEach((attr) => {
- if(action[`${attr}`]) {
- const attributeName = (attr === "Hit Bonus") ? "tohit" : (attr === "Reach") ? "range" : attr.toLowerCase().replace(" ", "");
- update[`repeating_${npcaction}_${newrowid}_attack_${attributeName}`] = action[`${attr}`];
- };
- });
-
- if(action["Damage 2"] && action["Damage 2 Type"]) {
- update[`repeating_${npcaction}_${newrowid}_attack_damage2`] = action["Damage 2"];
- update[`repeating_${npcaction}_${newrowid}_attack_damagetype2`] = action["Damage 2 Type"];
- }
- }
- });
- (attr === "Actions") ? callbacks.push(() => {update_npc_action("all");} ) : false;
- } else if(contentarray && contentarray.indexOf(`${attr}`) > -1) {
- console.log(`%c ${attr} was not found for ${page.name}`, "color: orange;");
- };
- });
- //REACTIONS
- if (page.data["data-Reactions"]) {
- update["npcreactionsflag"] = 1;
- let reactionsobj = {};
- jsonparse(page.data["data-Reactions"]).forEach((val) => { reactionsobj[val.Name] = val.Desc; });
- _.each(reactionsobj, (desc, name) => {
- newrowid = generateRowID();
- update[`repeating_npcreaction_${newrowid}_name`] = name + ".";
- if(desc.substring(0,2) === ": " || encodeURI(desc.substring(0,2)) === ":%C2%A0") {
- desc = desc.substring(2);
- };
- update[`repeating_npcreaction_${newrowid}_desc`] = desc.trim();
- });
- } else if(contentarray && contentarray.indexOf("Reactions") > -1) {
- console.log(`%c Reactions was not found for ${page.name}`, "color: orange;");
- };
- //TRAITS
- if (page.data["data-Traits"]) {
- //console.log(`%c MONSTERS Drop: NPC Traits`, "color:cornflowerblue;");
- let traitsobj = {};
- jsonparse(page.data["data-Traits"]).forEach((val) => {
- traitsobj[val.Name] = (val.Name && val.Desc) ? val.Desc : "";
- if (val.Name && val.Desc) {
- traitsobj[val.Name] = val.Desc;
- } else if (val.Name) {
- traitsobj[val.Name] = "";
- } else {
- console.log(`%c Traits JSON is lacking a Name key`, "color: orange;")
- };
- });
- _.each(traitsobj, (desc, name) => {
- newrowid = generateRowID();
- update[`repeating_npctrait_${newrowid}_name`] = name + ".";
- if(desc.substring(0,2) === ": " || encodeURI(desc.substring(0,2)) === ":%C2%A0") {
- desc = desc.substring(2);
- }
- update[`repeating_npctrait_${newrowid}_desc`] = desc.trim();
- // ESPER NPCS
- if(name === "Spellcasting") {
- var lvl = parseInt(desc.substring(desc.indexOf("-level")-4, desc.indexOf("-level")-2).trim(), 10);
- lvl = !isNaN(lvl) ? lvl : 1;
- var ability = desc.match(/casting ability is (.*?) /);
- ability = ability && ability.length > 1 ? ability[1] : false;
- ability = ability ? "@{" + ability.toLowerCase() + "_mod}+" : "0*";
- update["base_level"] = lvl;
- update["caster_level"] = lvl;
- update["class"] = "Wizard";
- update["level"] = lvl;
- update["npcspellcastingflag"] = 1;
- update["spellcasting_ability"] = ability;
- callbacks.push(() => {update_pb();} );
- callbacks.push(() => {update_spell_slots();} );
- }
- //Githzerai in MToF have (Psionics)
- if (name.includes("Innate Spellcasting")) {
- const ability = (page.data["Spellcasting Ability"]) ? `@{${page.data["Spellcasting Ability"].toLowerCase()}_mod}+` : "0*";
- update["npcspellcastingflag"] = 1;
- update["spellcasting_ability"] = ability;
- };
- });
- } else if(contentarray && contentarray.indexOf("Traits") > -1) {
- console.log(`%c Traits was not found for ${page.name}`, "color: orange;");
- };
- //Powers
- if (page.data["data-Powers"]) {
- let spellsobj = [];
- //Put together a list of spells to get from the Comepndium
- ["spells", "innate"].forEach((type) => {
- let spellList = jsonparse(page.data["data-Powers"])[`${type}`];
- if (spellList) {
- Object.keys(spellList).map((objectKey, index) => {
- spellList[objectKey].forEach((spell) => {
- spellsobj.push(spell);
- });
- });
- };
- });
- getCompendiumPage(spellsobj, (compendiumPages) => {
- compendiumPages = removeDuplicatedPageData(compendiumPages);
- const spellData = (compendiumPages.length === undefined || compendiumPages.length === 1) ? [compendiumPages] : compendiumPages;
- const innate = (jsonparse(page.data["data-Powers"])[`innate`]) ? jsonparse(page.data["data-Powers"])[`innate`] : false;
- let existing = {};
- let update = [], callbacks = [];
-
- spellData.forEach((page) => {
- const spell = page.data;
- const lvl = spell["Level"] && spell["Level"] > 0 ? spell["Level"] : "prime";
- const newrowid = generateRowID();
- const repeatingRow = `repeating_spell-${lvl}_${newrowid}`;
-
- update[`${repeatingRow}_spelllevel`] = lvl;
- update[`${repeatingRow}_spell_ability`] = (update["spellcasting_ability"]) ? update["spellcasting_ability"] : "spell";
- (spell.Name) ? update[`${repeatingRow}_spellname`] = spell.Name : console.log(`%c ${JSON.stringify(page.name)} is incorrect. Update compendium data.`, "color: orange;");
- update[`${repeatingRow}_spelloutput`] = (page.data["Damage"] || page.data["Healing"]) ? "ATTACK" : "POWERCARD";
-
- ["spellclass", "spellsource", "data-description"].forEach((attr) => {
- const suffix = (attr.includes("description")) ? "spelldescription" : attr;
- (spell[`${attr}`]) ? update[`${repeatingRow}_${suffix}`] = spell[`${attr}`] : false;
- });
-
- ["Add Casting Modifier", "Activation Time", "Concentration", "Damage Type", "Damage", "Duration", "Healing", "Material", "Range", "Ritual", "Save", "Save Success", "Domain", "Secondary Damage", "Secondary Damage Type", "Power Attack", "Target"].forEach((attr) => {
- if (spell[`${attr}`]) {
- //Adjust the array entry to match the attribute name in the HTML
- const name =
- (attr === "Add Casting Modifier") ? "dmgmod" :
- (attr === "Material") ? `comp_materials` :
- (attr === "Power Attack") ? `attack` :
- (attr.includes("Secondary Damage")) ? attr.split("Secondary ")[0] + "2" :
- attr;
- const spellattribute = name.toLowerCase().replace(" ", "");
- //Concentration, Ritual, and Domain are exceptions to norm
- const updateValue =
- (attr === "Concentration" || attr === "Ritual") ? `{{${spellattribute}=1}}` :
- (attr === "Domain") ? spell["Domain"].toLowerCase() :
- spell[`${attr}`];
- update[`${repeatingRow}_spell${spellattribute}`] = updateValue;
- };
- });
-
- ["Higher Power Slot Bonus", "Higher Power Slot Desc", "Higher Power Slot Dice", "Higher Power Slot Die"].forEach((attr) => {
- if (spell[`${attr}`]) {
- const spellattribute = (attr.includes("Bonus")) ? "hlbonus" : (attr.includes("Desc")) ? "athigherlevels" : (attr.includes("Dice")) ? "hldie" : "hldietype";
- update[`${repeatingRow}_spell${spellattribute}`] = spell[`${attr}`];
- };
- });
-
- if (spell["Components"]) {
- ["v", "s", "m"].forEach((comp) => {
- if (spell["Components"].toLowerCase().indexOf(comp) === -1) {update[`${repeatingRow}_spellcomp_${comp}`] = "0"};
- });
- };
-
- if(page.data["Damage"] || page.data["Healing"]) {
- //This needs to run the create_attack_from_spell
- callbacks.push(() => { create_attack_from_spell(lvl, newrowid, currentData.character_id); });
- } else if (page.data["Higher Power Slot Desc"] && page.data["Higher Power Slot Desc"] != "") {
- //This needs to run the update_spelloutput
- };
-
- if (spell["data-Prime Scaling"] && lvl == "prime") {
- update[`${repeatingRow}_spell_damage_progression`] = "Prime " + spell["data-Prime Scaling"].charAt(0).toUpperCase() + spell["data-Prime Scaling"].slice(1);
- };
-
- if (innate) {
- const spellName = (spell.Name).toLowerCase();
- //Search each keys in INNATE to see if spell name === one of the Values
- Object.keys(innate).map((objectKey, index) => {
- innate[objectKey].forEach((spell) => {
- (spell === spellName) ? update[`${repeatingRow}_innate`] = objectKey : false;
- });
- });
- };
-
- update[`${repeatingRow}_options-flag`] = "0";
- });
-
- setAttrs(update, {silent: true}, () => {
- callbacks.forEach((callback) => {
- callback();
- })
- });
-
- return {
- callbacks: callbacks
- };
- });
- };
- };
- if(category === "Feats") {
- update["tab"] = "core";
- var match = {name: page.name};
- var existing = _.findWhere(repeating.traits, match);
- var newrowid = generateRowID();
- if(existing) {
- newrowid = existing.id;
- existing.name = page.name;
- existing.source = "Feat";
- existing.type = page.data["Properties"] ? page.data["Properties"] : "";
- } else {
- var newtrait = {};
- newtrait.id = newrowid;
- newtrait.name = page.name;
- newtrait.source = "Feat";
- newtrait.type = page.data["Properties"] ? page.data["Properties"] : "";
- repeating.traits.push(newtrait);
- }
- if(page.name) {update[`repeating_traits_${newrowid}_name`] = page.name};
- if(page.content) {update[`repeating_traits_${newrowid}_description`] = page.content};
- update[`repeating_traits_${newrowid}_source`] = "Feat";
- update[`repeating_traits_${newrowid}_source_type`] = page.data["Properties"] ? page.data["Properties"] : "";
- update[`repeating_traits_${newrowid}_options-flag`] = "0";
- update[`repeating_traits_${newrowid}_display_flag`] = "on";
- };
- if(category === "Proficiencies") {
- var newrowid = generateRowID();
- var type = page.data["Type"] || "";
- if (type.toLowerCase() === "language" || type.toLowerCase() === "armor" || type.toLowerCase() === "weapon" || type.toLowerCase() === "other") {
- if( repeating.prof_names.indexOf(page.name.toLowerCase()) == -1 ) {
- update[`repeating_proficiencies_${newrowid}_prof_type`] = type.replace("custom", "").toUpperCase();
- update[`repeating_proficiencies_${newrowid}_name`] = page.name;
- update[`repeating_proficiencies_${newrowid}_options-flag`] = 0;
- repeating.prof_names.push(page.name.toLowerCase());
- };
- } else if(type.toLowerCase() === "tool" || type.toLowerCase() === "skillcustom") {
- let existing = {};
- _.each(repeating.tool, (tool, id) => {
- if(tool.toolname == page.name.toLowerCase()) {
- newrowid = id;
- existing = tool;
- }
- });
- if(!existing.toolname) repeating.tool[newrowid] = {toolname: page.name.toLowerCase()}
- update[`repeating_tool_${newrowid}_toolname`] = page.name;
- if(!existing.base) update[`repeating_tool_${newrowid}_toolattr_base`] = "?{Attribute?|Strength,@{strength_mod}|Dexterity,@{dexterity_mod}|Constitution,@{constitution_mod}|Intelligence,@{intelligence_mod}|Wisdom,@{wisdom_mod}|Charisma,@{charisma_mod}}";
- update[`repeating_tool_${newrowid}_options-flag`] = 0;
- if(page.data["toolbonus_base"]) update[`repeating_tool_${newrowid}_toolbonus_base`] = "(@{pb}*2)";
- repeating.prof_names.push(page.name.toLowerCase());
- callbacks.push( function() {update_tool(newrowid);} );
- }
- if(type.toLowerCase() === "skill") {
- var skill_string = page.name.toLowerCase().replace(/ /g, '_');
- update[`${skill_string}_prof`] = `(@{pb}*@{${skill_string}_type})`;
- };
- };
- if(category === "Classes") {
- update["tab"] = "core";
- if(page.data.multiclass) {
- if(page.name && page.name !== "") { update[page.data.multiclass] = page.name; }
- update[page.data.multiclass + "_flag"] = "1";
- classlevel = parseInt(currentData[page.data.multiclass + "_lvl"]);
- } else {
- if(page.name && page.name !== "") { update["class"] = page.name; }
- if(page.data["Hit Die"] && page.data["Hit Die"] !== "") {
- update["base_level"] = currentData.base_level ? currentData.base_level : "1";
- update["hit_dice_max"] = update["base_level"] + page.data["Hit Die"];
- update["hit_dice"] = update["base_level"];
- }
- if(page.data["Spellcasting Ability"] && page.data["Spellcasting Ability"] !== "") {
- update["spellcasting_ability"] = "@{" + page.data["Spellcasting Ability"].toLowerCase() + "_mod}+";
- }
- }
- if(page.data["data-Saving Throws"] && !page.data.multiclass) {
- var saves = jsonparse(page.data["data-Saving Throws"]);
- _.each(saves, function(value) {
- update[value.toLowerCase() + "_save_prof"] = "(@{pb})";
- });
- }
-
- if(!looped) {
- callbacks.push(update_class);
- }
- };
- if(category === "Subclasses") {
- if(page.data.multiclass) {
- if(page.name && page.name !== "") { update[page.data.multiclass + "_subclass"] = page.name; }
- classlevel = parseInt(currentData[page.data.multiclass + "_lvl"]);
- } else {
- if(page.name && page.name !== "") { update["subclass"] = page.name; };
- }
- if(page.data["Spellcasting Ability"]) {
- if(page.data.Class == "Fighter") {
- update["arcane_fighter"] = "1";
- } else if(page.data.Class == "Rogue") {
- update["arcane_rogue"] = "1";
- }
- }
- if(!looped) {
- callbacks.push(update_class);
- };
- };
- if(category === "Races" || category === "Subraces") {
- update["tab"] = "core";
- if(category === "Races") {
- update["race"] = page.name;
- if (page.name == "Halfling") {
- update["halflingluck_flag"] = "1";
- }
- }
- else {
- update["subrace"] = page.name;
- };
- if(page.data["Speed"]) {update["speed"] = page.data["Speed"]};
- if(page.data["Size"]) {update["size"] = page.data["Size"]};
- if(!looped) {
- callbacks.push(update_race_display);
- }
- };
- if(category === "Backgrounds") {
- update["tab"] = "core";
- if(page.name && page.name !== "") { update["background"] = page.name; };
- };
-
- if(page.data.theseblobs) {
- _.each(page.data.theseblobs, function(blobname) {
- if(page.data.blobs[blobname]) blobs[blobname] = page.data.blobs[blobname];
- });
- } else {
- blobs = filterBlobs(page.data.blobs, {"Level": "1"});
- }
- _.each(blobs, function(blob, blobname) {
- if(blob["Traits"]) {
- var traitsource = "";
- switch (category) {
- case "Races":
- case "Subraces":
- traitsource = "Racial";
- break;
- case "Classes":
- case "Subclasses":
- traitsource = "Class";
- break;
- default:
- traitsource = "Background";
- }
- var trait_array = jsonparse(blob["Traits"]);
- if(trait_array && trait_array.length) {
- _.each(trait_array, function(trait) {
- if(!trait.Input) {
- var match = {name: trait["Name"], type: page.name};
- if(trait["Replace"]) {
- match = {name: trait["Replace"]};
- }
- var existing = _.findWhere(repeating.traits, match);
- if(existing) {
- newrowid = existing.id;
- existing.name = trait["Name"];
- existing.source = traitsource;
- existing.type = page.name;
- } else {
- var newtrait = {};
- newrowid = generateRowID();
- newtrait.id = newrowid;
- newtrait.name = trait["Name"];
- newtrait.source = traitsource;
- newtrait.type = page.name;
- repeating.traits.push(newtrait);
- }
- update["repeating_traits_" + newrowid + "_name"] = trait["Name"].replace(/{{Input}}/g, "");
- update["repeating_traits_" + newrowid + "_description"] = trait["Desc"] ? trait["Desc"].replace(/{{Input}}/g, "") : "";
- update["repeating_traits_" + newrowid + "_source"] = removeExpansionInfo(traitsource);
- update["repeating_traits_" + newrowid + "_source_type"] = page.name ? removeExpansionInfo(page.name) : "";
- update["repeating_traits_" + newrowid + "_options-flag"] = 0;
- update["repeating_traits_" + newrowid + "_display_flag"] = "on";
- }
- });
- };
- };
- if(blob["Language Proficiency"] || blob["Weapon Proficiency"] || blob["Armor Proficiency"] || blob["Tool Proficiency"]) {
- if(blob["Language Proficiency"]) {
- var lang_array = jsonparse(blob["Language Proficiency"]);
- if(lang_array["Proficiencies"] && lang_array["Proficiencies"].length) {
- _.each(lang_array["Proficiencies"], function(prof) {
- if( repeating.prof_names.indexOf(prof.toLowerCase()) == -1 ) {
- newrowid = generateRowID();
- update["repeating_proficiencies_" + newrowid + "_prof_type"] = "LANGUAGE";
- update["repeating_proficiencies_" + newrowid + "_name"] = prof;
- update["repeating_proficiencies_" + newrowid + "_options-flag"] = 0;
- repeating.prof_names.push(prof.toLowerCase());
- }
- });
- }
- };
- if(blob["Weapon Proficiency"]) {
- var weap_array = jsonparse(blob["Weapon Proficiency"]);
- if(weap_array["Proficiencies"] && weap_array["Proficiencies"].length) {
- _.each(weap_array["Proficiencies"], function(prof) {
- if( repeating.prof_names.indexOf(prof.toLowerCase()) == -1 ) {
- newrowid = generateRowID();
- update["repeating_proficiencies_" + newrowid + "_prof_type"] = "WEAPON";
- update["repeating_proficiencies_" + newrowid + "_name"] = prof;
- update["repeating_proficiencies_" + newrowid + "_options-flag"] = 0;
- repeating.prof_names.push(prof.toLowerCase());
- }
- });
- }
- };
- if(blob["Armor Proficiency"]) {
- var armor_array = jsonparse(blob["Armor Proficiency"]);
- if(armor_array["Proficiencies"] && armor_array["Proficiencies"].length) {
- _.each(armor_array["Proficiencies"], function(prof) {
- if( repeating.prof_names.indexOf(prof.toLowerCase()) == -1 ) {
- newrowid = generateRowID();
- update["repeating_proficiencies_" + newrowid + "_prof_type"] = "ARMOR";
- update["repeating_proficiencies_" + newrowid + "_name"] = prof;
- update["repeating_proficiencies_" + newrowid + "_options-flag"] = 0;
- repeating.prof_names.push(prof.toLowerCase());
- }
- });
- }
- };
- if(blob["Tool Proficiency"]) {
- var tool_array = jsonparse(blob["Tool Proficiency"]);
- if(tool_array["Proficiencies"] && tool_array["Proficiencies"].length) {
- _.each(tool_array["Proficiencies"], function(prof) {
- //D&D 5e Mancer: Land Vehicles proficiency does not drop with Marine background (UC748)
- //Generating ID that was coming empty for not existing rows.
- //By Miguel Peres
- let newrowid = generateRowID();
-
- let existing = {};
- _.each(repeating.tool, function(tool, id) {
- if(tool.toolname == prof.toLowerCase()) {
- newrowid = id;
- existing = tool;
- }
- });
- if(!existing.toolname) repeating.tool[newrowid] = {toolname: prof.toLowerCase()}
- update["repeating_tool_" + newrowid + "_toolname"] = prof;
- if(!existing.base) update["repeating_tool_" + newrowid + "_toolattr_base"] = "?{Attribute?|Strength,@{strength_mod}|Dexterity,@{dexterity_mod}|Constitution,@{constitution_mod}|Intelligence,@{intelligence_mod}|Wisdom,@{wisdom_mod}|Charisma,@{charisma_mod}}";
- update["repeating_tool_" + newrowid + "_options-flag"] = 0;
- repeating.prof_names.push(page.name.toLowerCase());
- callbacks.push( function() {update_tool(newrowid);} );
- });
- }
- };
- };
- if(blob["Skill Proficiency"]) {
- var skill_array = jsonparse(blob["Skill Proficiency"]);
- if(skill_array["Proficiencies"] && skill_array["Proficiencies"].length) {
- _.each(skill_array["Proficiencies"], function(prof) {
- var skill_string = prof.toLowerCase().replace(/ /g, '_');
- update[skill_string + "_prof"] = "(@{pb}*@{" + skill_string + "_type})";
- });
- };
- };
- if(blob["Actions"]) {
- var actionsobj = {};
- jsonparse(blob["Actions"]).forEach(function(val) { actionsobj[val.Name] = val; });
- _.each(actionsobj, function(action, name) {
- newrowid = generateRowID();
- _.each(repeating.attack, function(atk, atkid) {
- if(atk.atkname === name) newrowid = atkid;
- });
- update["repeating_attack_" + newrowid + "_options-flag"] = "0";
- update["repeating_attack_" + newrowid + "_atkname"] = name;
- if(action["Desc"]) {
- update["repeating_attack_" + newrowid + "_atk_desc"] = action["Desc"];
- }
-
- if(action["Type Attack"]) {
- if (action["Type"] == "Spell") {
- update["repeating_attack_" + newrowid + "_atkflag"] = "0";
- update["repeating_attack_" + newrowid + "_attack_options"] = "";
- update["repeating_attack_" + newrowid + "_saveflag"] = "{{save=1}} {{saveattr=@{saveattr}}} {{savedesc=@{saveeffect}}} {{savedc=[[[[@{savedc}]][SAVE]]]}}"
- } else {
- update["repeating_attack_" + newrowid + "_attack_flag"] = "on";
- update["repeating_attack_" + newrowid + "_atkflag"] = "{{attack=1}}";
- update["repeating_attack_" + newrowid + "_attack_options"] = "{{attack=1}}";
- }
- if(action["Reach"]) { update["repeating_attack_" + newrowid + "_atkrange"] = action["Reach"]; }
-
- if(action["Damage"]) { update["repeating_attack_" + newrowid + "_dmgbase"] = action["Damage"]; }
- if(action["Damage Type"]) { update["repeating_attack_" + newrowid + "_dmgtype"] = action["Damage Type"]; }
- if (action["Modifier"]) {
- update["repeating_attack_" + newrowid + "_dmgattr"] = modStringToAttrib(action["Modifier"]);
- update["repeating_attack_" + newrowid + "_atkattr_base"] = modStringToAttrib(action["Modifier"]);
- } else {
- update["repeating_attack_" + newrowid + "_dmgattr"] = "0";
- }
- if (action["Save"]) { update["repeating_attack_" + newrowid + "_saveattr"] = action["Save"] }
- if (action["Save DC"]) { update["repeating_attack_" + newrowid + "_savedc"] = "(" + modStringToAttrib(action["Save DC"]) + "+8+@{pb})" }
- if (action["Save Effect"]) { update["repeating_attack_" + newrowid + "_saveeffect"] = action["Save Effect"] }
-
- if(action["Damage 2"] && action["Damage 2 Type"]) {
- update["repeating_attack_" + newrowid + "_dmg2flag"] = "{{damage=1}} {{dmg2flag=1}}";
- update["repeating_attack_" + newrowid + "_atk_dmg2base"] = action["Damage 2"];
- update["repeating_attack_" + newrowid + "_attack_damagetype2"] = action["Damage 2 Type"];
- if (action["Modifier 2"]) {
- update["repeating_attack_" + newrowid + "_dmg2attr"] = modStringToAttrib(action["Modifier 2"]);
- } else {
- update["repeating_attack_" + newrowid + "_dmgattr"] = "0";
- }
- }
- }
- });
- };
- if(blob["Global Damage"]) {
- var dmgmod = jsonparse(blob["Global Damage"]);
- var id = generateRowID();
- _.each(repeating.damagemod, function(name, rowid) {
- if(name.toLowerCase() === dmgmod["Name"].toLowerCase()) id = rowid;
- });
- update["repeating_damagemod_" + id + "_global_damage_name"] = `${dmgmod["Name"]}`;
- update["repeating_damagemod_" + id + "_global_damage_damage"] = `${parseValues(dmgmod["Damage"])}`;
- if(dmgmod["Active"] == "true") update["repeating_damagemod_" + id + "_global_damage_active_flag"] = "1";
- update["repeating_damagemod_" + id + "_options-flag"] = "0";
- update["repeating_damagemod_" + id + "_global_damage_type"] = dmgmod["Type"] ? dmgmod["Type"] : dmgmod["Name"];
- update["global_damage_mod_flag"] = "1";
- repeating.damagemod[id] = dmgmod["Name"];
- };
- if(blob["Resources"]) {
- var resources = jsonparse(blob["Resources"]);
- _.each(resources, function(value) {
- var section = "";
- if(currentData["class_resource_name"] == "" || currentData["class_resource_name"] == value["Name"]) {
- section = "class_resource";
- } else if (currentData["other_resource_name"] == "" || currentData["other_resource_name"] == value["Name"]) {
- section = "other_resource";
- } else {
- _.each(repeating.resource, function(resource, id) {
- if(resource.left == "" && section == "" || resource.left == value["Name"]) {
- section = "repeating_resource_" + id + "_resource_left";
- }
- if(resource.right == "" && section == "" || resource.right == value["Name"]) {
- section = "repeating_resource_" + id + "_resource_right";
- }
- })
- }
- if(section === "") {
- var id = generateRowID();
- section = "repeating_resource_" + id + "_resource_left";
- repeating.resource[id] = {left: value["Name"], right: ""};
- }
- update[section + "_name"] = value["Name"];
- if(value["Uses"]) update[section] = numUses(value["Uses"]);
- update[section + "_max"] = value["Max"] ? numUses(value["Max"]) : numUses(value["Uses"]);
- });
- };
- if(blob["Custom AC"]) {
- var customac = jsonparse(blob["Custom AC"]);
- update["custom_ac_flag"] = "1";
- update["custom_ac_base"] = customac.Base;
- update["custom_ac_part1"] = customac["Attribute 1"];
- update["custom_ac_part2"] = customac["Attribute 2"] ? customac["Attribute 2"] : "";
- update["custom_ac_shield"] = customac.Shields;
- if(!looped) {
- callbacks.push( function() {update_ac();} )
- }
- };
- if(blob["Hit Points Per Level"]) {
- var id = generateRowID();
- update["repeating_hpmod_" + id + "_mod"] = blob["Hit Points Per Level"];
- update["repeating_hpmod_" + id + "_source"] = page.name ? page.name : "Subclass";
- if(category === "Races" || category === "Subraces") {
- update["repeating_hpmod_" + id + "_levels"] = "total";
- } else {
- update["repeating_hpmod_" + id + "_levels"] = "base";
- }
- };
- if(blob["Global AC Mod"]) {
- var globalac = jsonparse(blob["Global AC Mod"]);
- var id = generateRowID();
- _.each(repeating.acmod, function(name, rowid) {
- if(name.toLowerCase() === globalac["Name"].toLowerCase()) id = rowid;
- });
- update["repeating_acmod_" + id + "_global_ac_val"] = globalac.Bonus;
- if(globalac["Active"] !== "false") update["repeating_acmod_" + id + "_global_ac_active_flag"] = "1";
- update["repeating_acmod_" + id + "_options-flag"] = "0";
- update["repeating_acmod_" + id + "_global_ac_name"] = globalac.Name;
- update["global_ac_mod_flag"] = "1";
- };
- if(blob["Global Save"]) {
- var globalsave = jsonparse(blob["Global Save Mod"]);
- var id = generateRowID();
- _.each(repeating.savemod, function(name, rowid) {
- if(name.toLowerCase() === globalsave["Name"].toLowerCase()) id = rowid;
- });
- update["repeating_savemod_" + id + "_global_save_roll"] = globalsave.Bonus;
- if(globalsave["Active"] !== "false") update["repeating_savemod_" + id + "_global_save_active_flag"] = "1";
- update["repeating_savemod_" + id + "_options-flag"] = "0";
- update["repeating_savemod_" + id + "_global_save_name"] = globalsave.Name;
- update["global_save_mod_flag"] = "1";
- }
- if(blob["Global Attack"]) {
- var globalattack = jsonparse(blob["Global Attack"]);
- var id = generateRowID();
- _.each(repeating.tohitmod, function(name, rowid) {
- if(name.toLowerCase() === globalattack["Name"].toLowerCase()) id = rowid;
- });
- update["repeating_tohitmod_" + id + "_global_attack_rollstring"] = `${globalattack["Bonus"]}[${globalattack["Name"]}]`;
- if(globalattack["Active"] !== "false") update["repeating_tohitmod_" + id + "_global_attack_active_flag"] = "1";
- update["repeating_tohitmod_" + id + "_options-flag"] = "0";
- update["global_attack_mod_flag"] = "1";
- };
- if(blob["Initiative"]) {
- if(blob["Initiative"].toLowerCase() === "advantage") {
- update["initiative_style"] = "{@{d20},@{d20}}kh1";
- } else if (blob["Initiative"].toLowerCase() === "disadvantage") {
- update["initiative_style"] = "{@{d20},@{d20}}kl1";
- } else {
- update.initmod = numUses(blob["Initiative"]);
- }
- };
- if(blob["Carry Multiplier"]) {
- update["carrying_capacity_mod"] = "*" + blob["Carry Multiplier"];
- };
- if(blob["Speed"]) {
- if(blob["Speed"][0] === "+") {
- let prevspeed = update["speed"] || currentData["speed"];
- prevspeed = prevspeed && !isNaN(parseInt(prevspeed)) ? parseInt(prevspeed) : 0;
- update["speed"] = prevspeed + parseInt(blob["Speed"]);
- } else {
- update["speed"] = parseInt(blob["Speed"]);
- }
- };
- if(blob["Jack of All Trades"]) {
- update["jack_of_all_trades"] = "@{jack}";
- };
- if(blob["Saving Throws"]) {
- var saves = jsonparse(blob["Saving Throws"]);
- _.each(saves, function(value) {
- update[value.toLowerCase() + "_save_prof"] = "(@{pb})";
- });
- };
- if(blob["Custom Powers"]) {
- let spells = jsonparse(blob["Custom Powers"]);
- _.each(spells, function(spell) {
- var lvl = spell["Level"] && spell["Level"] > 0 ? spell["Level"] : "prime";
- let id = generateRowID();
- if(repeating["spell-" + lvl]) {
- _.each(repeating["spell-" + lvl], function(spell, spellid) {
- if(spell.spellname.toLowerCase() === page.name.toLowerCase()) {
- id = spellid;
- }
- });
- }
- update["repeating_spell-" + lvl + "_" + id + "_spelllevel"] = lvl;
- if(spell["spellcasting_ability"]) {
- update["repeating_spell-" + lvl + "_" + id + "_spell_ability"] = "@{" + spell["spellcasting_ability"].toLowerCase() + "_mod}+";;
- } else {
- update["repeating_spell-" + lvl + "_" + id + "_spell_ability"] = "spell";
- }
- if(spell["spellclass"]) {
- update["repeating_spell-" + lvl + "_" + id + "_spellclass"] = spell["spellclass"];
- }
- if(spell["spellsource"]) {
- update["repeating_spell-" + lvl + "_" + id + "_spellsource"] = spell["spellsource"];
- }
- update["repeating_spell-" + lvl + "_" + id + "_spellname"] = spell.Name;
- if(spell["Ritual"]) {update["repeating_spell-" + lvl + "_" + id + "_spellritual"] = "{{ritual=1}}"};
- if(spell["Domain"]) {update["repeating_spell-" + lvl + "_" + id + "_spellschool"] = spell["Domain"].toLowerCase()};
- if(spell["Activation Time"]) {update["repeating_spell-" + lvl + "_" + id + "_spellcastingtime"] = spell["Activation Time"]};
- if(spell["Point Cost"]) {update["repeating_spell-" + lvl + "_" + id + "_pointcost"] = spell["Point Cost"]};
- if(spell["Range"]) {update["repeating_spell-" + lvl + "_" + id + "_spellrange"] = spell["Range"]};
- if(spell["Target"]) {update["repeating_spell-" + lvl + "_" + id + "_spelltarget"] = spell["Target"]};
- if(spell["Components"]) {
- if(spell["Components"].toLowerCase().indexOf("v") === -1) {update["repeating_spell-" + lvl + "_" + id + "_spellcomp_v"] = "0"};
- if(spell["Components"].toLowerCase().indexOf("s") === -1) {update["repeating_spell-" + lvl + "_" + id + "_spellcomp_s"] = "0"};
- if(spell["Components"].toLowerCase().indexOf("m") === -1) {update["repeating_spell-" + lvl + "_" + id + "_spellcomp_m"] = "0"};
- };
- if(spell["Material"]) {update["repeating_spell-" + lvl + "_" + id + "_spellcomp_materials"] = spell["Material"]};
- if(spell["Concentration"]) {update["repeating_spell-" + lvl + "_" + id + "_spellconcentration"] = "{{concentration=1}}"};
- if(spell["Duration"]) {update["repeating_spell-" + lvl + "_" + id + "_spellduration"] = spell["Duration"]};
- if(spell["Damage"] || spell["Healing"]) {
- update["repeating_spell-" + lvl + "_" + id + "_spelloutput"] = "ATTACK";
- callbacks.push( function() {create_attack_from_spell(lvl, id, currentData.character_id);} );
- }
- else if(spell["Higher Power Slot Desc"] && spell["Higher Power Slot Desc"] != "") {
- var spelllevel = "?{Cast at what level?";
- for(i = 0; i < 10-lvl; i++) {
- spelllevel = spelllevel + "|Level " + (parseInt(i, 10) + parseInt(lvl, 10)) + "," + (parseInt(i, 10) + parseInt(lvl, 10));
- }
- spelllevel = spelllevel + "}";
- update["repeating_spell-" + lvl + "_" + id + "_rollcontent"] = `@{wtype}&{template:spell} {{level=@{spellschool} ${spelllevel}}} {{name=@{spellname}}} {{castingtime=@{spellcastingtime}}} {{range=@{spellrange}}} {{target=@{spelltarget}}} @{pointcost}}} {{duration=@{spellduration}}} {{description=@{spelldescription}}} {{athigherlevels=@{spellathigherlevels}}} @{spellritual} {{innate=@{innate}}} @{spellconcentration} @{charname_output} {{licensedsheet=@{licensedsheet}}}`;
- };
- if(spell["Power Attack"]) {update["repeating_spell-" + lvl + "_" + id + "_spellattack"] = spell["Power Attack"]};
- if(spell["Damage"]) {update["repeating_spell-" + lvl + "_" + id + "_spelldamage"] = spell["Damage"]};
- if(spell["Damage Type"]) {update["repeating_spell-" + lvl + "_" + id + "_spelldamagetype"] = spell["Damage Type"]};
- if(spell["Secondary Damage"]) {update["repeating_spell-" + lvl + "_" + id + "_spelldamage2"] = spell["Secondary Damage"]};
- if(spell["Secondary Damage Type"]) {update["repeating_spell-" + lvl + "_" + id + "_spelldamagetype2"] = spell["Secondary Damage Type"]};
- if(spell["Healing"]) {update["repeating_spell-" + lvl + "_" + id + "_spellhealing"] = spell["Healing"];};
- if(spell["Add Casting Modifier"]) {update["repeating_spell-" + lvl + "_" + id + "_spelldmgmod"] = spell["Add Casting Modifier"]};
- if(spell["Save"]) {update["repeating_spell-" + lvl + "_" + id + "_spellsave"] = spell["Save"]};
- if(spell["Save Success"]) {update["repeating_spell-" + lvl + "_" + id + "_spellsavesuccess"] = spell["Save Success"]};
- if(spell["Higher Power Slot Dice"]) {update["repeating_spell-" + lvl + "_" + id + "_spellhldie"] = spell["Higher Power Slot Dice"]};
- if(spell["Higher Power Slot Die"]) {update["repeating_spell-" + lvl + "_" + id + "_spellhldietype"] = spell["Higher Power Slot Die"]};
- if(spell["Higher Power Slot Bonus"]) {update["repeating_spell-" + lvl + "_" + id + "_spellhlbonus"] = spell["Higher Power Slot Bonus"]};
- if(spell["Higher Power Slot Desc"]) {update["repeating_spell-" + lvl + "_" + id + "_spellathigherlevels"] = spell["Higher Power Slot Desc"]};
- if(spell["data-Prime Scaling"] && lvl == "prime") {update["repeating_spell-" + lvl + "_" + id + "_spell_damage_progression"] = "Prime " + spell["data-Prime Scaling"].charAt(0).toUpperCase() + spell["data-Prime Scaling"].slice(1);};
- if(spell["data-description"]) { update["repeating_spell-" + lvl + "_" + id + "_spelldescription"] = spell["data-description"]};
- update["repeating_spell-" + lvl + "_" + id + "_options-flag"] = "0";
- })
- };
- if(blob["Global Save Mod"]) {
- update["globalsavemod"] = numUses(blob["Global Save Mod"]);
- };
- if(blob["Proficiency Bonus"]) {
- var bonus = jsonparse(blob["Proficiency Bonus"]);
- _.each(bonus, function(value, prof) {
- update[prof.replace(/ /g, "_").toLowerCase() + "_flat"] = numUses(value);
- });
- };
- /**/
- });
-
- return {
- update: update,
- repeating: repeating,
- callbacks: callbacks
- };
-};
-
var check_itemmodifiers = function(modifiers, previousValue) {
var mods = modifiers.toLowerCase().split(",");
if(previousValue) {
@@ -4203,16 +3121,7 @@ on("mancer:cancel", function(eventinfo) {
setAttrs(update);
});
-on("change:licensedsheet", function(eventinfo) {
- //debugger
-});
-
-/* on("sheet:opened", function(eventinfo) {
- getAttrs([licensedsheet], function(v) {
- debugger
- });
-}); */
- var v2_old_values_check = function() {
+var v2_old_values_check = function() {
// update_attacks("all");
var update = {};
var attrs = ["simpletraits","features_and_traits","initiative_bonus","npc","character_id"];
@@ -4662,6040 +3571,6 @@ var versioning = function(finished) {
};
});
};
-/*********************************************************************/
-/*********************************************************************/
-/****** ******/
-/****** CHARACTERMANCER WORKERS ******/
-/****** ******/
-/*********************************************************************/
-/*********************************************************************/
-
-var proficiencyList = ["Weapon", "Armor", "Skill", "Tool", "Language"];
-var abilityList = ["Strength", "Dexterity", "Constitution", "Intelligence", "Wisdom", "Charisma"];
-var changeListeners = "mancerchange:race_ability_choice1 mancerchange:race_ability_choice2 mancerchange:subrace_ability_choice1 mancerchange:subrace_ability_choice2 mancerchange:custom_hit_die mancerchange:feat_ability_choice";
-var proficiencyNum = 4;
-var customListeners = "";
-_.each(abilityList, function(ability){
- changeListeners += " mancerchange:race_custom_" + ability.toLowerCase();
- changeListeners += " mancerchange:subrace_custom_" + ability.toLowerCase();
-});
-
-/* HELPER FUNCTIONS */
-var recalcData = function(data) {
- //Sets all the text in the top bar, returns ability information
- var update = {"hit_points": "-"};
- var allAbilities = {race: {}, subrace: {}, feat: {}};
- var disableAbilities = {race: [], subrace: [], feat: []};
- var allProficiencies = {};
- var toSet = {};
- var mancerdata = data || getCharmancerData();
- var additionalHP = 0;
-
- if(mancerdata["l1-class"] && mancerdata["l1-class"].data.class && mancerdata["l1-class"].data.class["Suggested Abilities"]) {
- update["class_suggested_abilities"] = mancerdata["l1-class"].data.class["Suggested Abilities"];
- showChoices(["class_suggested_abilities_container"]);
- } else {
- update["class_suggested_abilities"] = "";
- hideChoices(["class_suggested_abilities_container"]);
- }
- if(mancerdata["l1-class"] && mancerdata["l1-class"].data.class && mancerdata["l1-class"].data.class["Spellcasting Ability"]) {
- update["class_spellcasting_ability"] = mancerdata["l1-class"].data.class["Spellcasting Ability"];
- showChoices(["class_spellcasting_ability_container"]);
- } else {
- update["class_spellcasting_ability"] = "";
- hideChoices(["class_spellcasting_ability_container"]);
- }
-
- _.each(mancerdata, function(page){
- _.each(page.values, function(value, name) {
- if(name.search("ability") !== -1) {
- var choiceSection = name.split("_")[0];
- if(page.data[choiceSection] && page.data[choiceSection]["data-Ability Score Choice"]) {
- var increase = 1;
- if(typeof page.data[choiceSection]["data-Ability Score Choice"] == "string") {
- increase = parseInt( _.last( page.data[choiceSection]["data-Ability Score Choice"].split("+") ) );
- }
- allAbilities[choiceSection] = allAbilities[choiceSection] || {};
- allAbilities[choiceSection][value.toLowerCase()] = increase;
- disableAbilities[choiceSection] = disableAbilities[choiceSection] || [];
- disableAbilities[choiceSection].push(value);
- }
- }
- });
- _.each(page.data, function(pagedata, increaseSection) {
- if(pagedata["data-Ability Score Increase"]) {
- _.each(pagedata["data-Ability Score Increase"], function(amount, ability) {
- allAbilities[increaseSection] = allAbilities[increaseSection] || {};
- allAbilities[increaseSection][ability.toLowerCase()] = amount;
- disableAbilities[increaseSection] = disableAbilities[increaseSection] || [];
- disableAbilities[increaseSection].push(ability.toLowerCase());
- });
- }
- //TODO: Investigate if additional hitpoits at first level could be calculated and interted at this point
- //By Miguel
- if(pagedata["data-HP per level"]) {
- additionalHP += pagedata["data-HP per level"];
- }
- });
- });
- if(mancerdata["l1-race"] && mancerdata["l1-race"].values.race == "Rules:Races") {
- _.each(abilityList, function(ability){
- var custom = mancerdata["l1-race"].values["race_custom_" + ability.toLowerCase()] || false;
- if(custom) {
- allAbilities.race[ability.toLowerCase()] = parseInt(custom);
- }
- });
- }
- if(mancerdata["l1-race"] && mancerdata["l1-race"].values.subrace == "Rules:Races") {
- _.each(abilityList, function(ability){
- var custom = mancerdata["l1-race"].values["subrace_custom_" + ability.toLowerCase()] || false;
- if(custom) {
- allAbilities.subrace[ability.toLowerCase()] = parseInt(custom);
- }
- });
- }
- var abilityTotals = {};
- _.each(allAbilities, function(abilities) {
- _.each(abilities, function(amount, ability) {
- abilityTotals[ability] = abilityTotals[ability] || {bonus: 0};
- abilityTotals[ability].bonus += parseInt(amount);
- });
- });
- _.each(abilityList, function(upperAbility) {
- var ability = upperAbility.toLowerCase();
- abilityTotals[ability] = abilityTotals[ability] || {bonus: 0, mod: 0};
- if(mancerdata["l1-abilities"] && mancerdata["l1-abilities"].values[ability]) {
- abilityTotals[ability].base = parseInt( mancerdata["l1-abilities"].values[ability].split("~")[0] );
- } else {
- abilityTotals[ability].base = 0;
- }
- abilityTotals[ability].total = abilityTotals[ability].bonus + abilityTotals[ability].base;
- abilityTotals[ability].mod = Math.floor((abilityTotals[ability].total - 10)/2);
- update[ability + "_total"] = abilityTotals[ability].total == 0 ? "-" : abilityTotals[ability].total;
- });
- allAbilities.totals = abilityTotals;
-
- if(mancerdata["l1-class"] && (mancerdata["l1-class"].data.class || mancerdata["l1-class"].values["custom_hit_die"])) {
- var basehp = mancerdata["l1-class"].data.class ? mancerdata["l1-class"].data.class["Hit Die"] : mancerdata["l1-class"].values["custom_hit_die"];
- var conmod = abilityTotals.constitution.base > 0 ? abilityTotals.constitution.mod : 0;
- //Calculating additional hitpoints at first level from things like Draconic Bloodline ad Hill Dwarf
- //By Miguel
- let additionalHitPointsFromClassAndRaceAtFirstLevel = getAdditionalHitPointsFromClassAndRaceAtFirstLevel(getRelevantBlobs(mancerdata, '1', 'l1'));
- allAbilities.hp = parseInt(basehp.replace("d", "")) + additionalHitPointsFromClassAndRaceAtFirstLevel + additionalHP + conmod;
- update["hit_points"] = allAbilities.hp;
- }
-
- if(!data) {
- _.each(disableAbilities, function(disable, disablesection) {
- disableCharmancerOptions(disablesection + "_ability_choice1", disable);
- disableCharmancerOptions(disablesection + "_ability_choice2", disable);
- });
- setCharmancerText(update);
- setAttrs(toSet);
- }
- return allAbilities;
-};
-
-var getProficiencies = function(data, currentSlide, blobs) {
- //Disables taken proficiency choices, returns proficiency info
- var auto = {};
- var allProficiencies = {"Weapon": [], "Armor": [], "Skill": [], "Tool": [], "Language": [], "Expertise": []};
- var toSet = {};
- var mancerdata = data || getCharmancerData();
- var thismancer = currentSlide && currentSlide != "finish" ? currentSlide.split("-")[0] : "l1";
- if(!blobs) {
- blobs = thismancer == "l1" ? blobs = getRelevantBlobs(mancerdata, "1", "l1") : blobs = getAllLpBlobs(data, true);
- }
- if(thismancer !== "l1") allProficiencies = data["lp-welcome"].values["previous_proficiencies"] ? JSON.parse(data["lp-welcome"].values["previous_proficiencies"]) : allProficiencies;
- currentSlide = currentSlide == "lp-finish" ? "finish" : currentSlide;
- //For this first part, we're only concerned with choices that have already been made
- //Get all of the "automatic" proficiencies
- _.each(blobs.sorted, function(blobarray, section) {
- _.each(blobarray, function(blob) {
- _.each(proficiencyList, function(prof) {
- if(blob[prof + " Proficiency"]) {
- var json = JSON.parse(blob[prof + " Proficiency"]);
- if(json.Proficiencies) {
- auto[section] = auto[section] ? auto[section].concat(json.Proficiencies) : json.Proficiencies;
- allProficiencies[prof] = allProficiencies[prof].concat(json.Proficiencies);
- }
- }
- });
- if(blob.Expertise) {
- var json = JSON.parse(blob.Expertise);
- if(json.Proficiencies) {
- allProficiencies.Expertise = allProficiencies.Expertise.concat(json.Proficiencies);
- }
- }
- });
- });
- //Gather all of the chosen proficiencies
- _.each(mancerdata, function(slide, slidename) {
- if(slidename.split("-")[0] == thismancer) {
- _.each(proficiencyList, function(prof) {
- _.each(slide.values, function(value, name) {
- if(name.split("_")[3] == prof.toLowerCase() && name.split("_")[4] == "choice") {
- if(value != "custom") allProficiencies[prof].push(value.split(":")[1]);
- }
- });
- });
- //Get a list of chosen expertise
- _.each(slide.values, function(value, name) {
- if(name.substr(-16) == "expertise_choice") {
- allProficiencies.Expertise.push(value.split(":")[1]);
- }
- });
- }
- });
- //Gather proficiencies from custom choices
- _.each(mancerdata, function(slide, slidename) {
- if(slidename.split("-")[0] == thismancer) {
- _.each(slide.values, function(value, name) {
- if(name.substr(-18) == "proficiency_choice") {
- if(value != "custom") allProficiencies[slide.values[name.replace("choice", "type")]].push(value.split(":")[1]);
- }
- });
- }
- });
- //If the expertise choice is from the "known" list, make sure the choice is still available
- //Reset to "" if not available. Don't do this if we're applying changes
- if(currentSlide != "finish") {
- _.each(mancerdata, function(slide, slidename) {
- if(slidename.split("-")[0] == thismancer) {
- _.each(slide.values, function(value, name) {
- if(name.substr(-16) == "expertise_choice" && slide.values[name.replace("choice", "info")]) {
- if(!(allProficiencies.Skill.includes(value.split(":")[1]) || allProficiencies.Tool.includes(value.split(":")[1]))) {
- toSet[name] = "";
- }
- }
- });
- }
- });
- setAttrs(toSet);
- }
- if(currentSlide && currentSlide != "finish") {
- //Now we need to know all of the selects, even if a choice hasn't been made
- //Getting a list of all the relevant selects
- var repsecs = {"Weapon": [], "Armor": [], "Skill": [], "Tool": [], "Language": []};
- var repexp = [];
- _.each(mancerdata[currentSlide].repeating, function(id) {
- _.each(proficiencyList, function(prof) {
- if(_.last(id.split("_")) == prof.toLowerCase()) repsecs[prof].push(id);
- });
- if(_.last(id.split("_")) == "expertise") repexp.push(id);
- if(_.last(id.split("_")) == "proficiency") {
- if (mancerdata[currentSlide].values[id + "_type"]) repsecs[mancerdata[currentSlide].values[id + "_type"]].push(id);
- }
- })
- //Disable already chosen proficiencies
- _.each(proficiencyList, function(prof) {
- _.each(repsecs[prof], function(id) {
- disableCharmancerOptions(id + "_choice", allProficiencies[prof], {category: "Proficiencies"});
- });
- });
- //Disable already chosen expertise, rebuild options if choice is from "known" list
- _.each(repexp, function(id) {
- if(mancerdata[currentSlide].values[id + "_info"]) {
- var choices = allProficiencies.Skill;
- var options = JSON.parse(mancerdata[currentSlide].values[id + "_info"]);
- var settings = {category: "Proficiencies", disable: allProficiencies.Expertise, silent: true};
- options.shift();
- settings.add = options;
- setCharmancerOptions(id + "_choice", choices, settings);
- } else {
- disableCharmancerOptions(id + "_choice", allProficiencies.Expertise, {category: "Proficiencies"});
- }
- });
- };
- _.each(allProficiencies, function(section, name) {
- allProficiencies[name] = _.without(section, "");
- });
- return({auto: auto, all: allProficiencies});
-};
-
-var handleAbilities = function(data, section) {
- var showList = [];
- if(data["data-Ability Score Increase"]) {
- showList.push(section + "_abilities");
- }
- if(data["data-Ability Score Choice"]) {
- showList.push(section + "_abilities");
- showList.push(section + "_ability_choice1");
- if(data["data-Ability Score Choice"].split("+")[0] == "2") {
- showList.push(section + "_ability_choice2");
- }
- };
- return showList;
-};
-
-var knownPowers = function(data) {
- var mancerdata = data ? data : getCharmancerData();
- var allPowers = {
- race: false,
- class: false,
- known: [],
- all: [],
- errors: {class: [], race: []}
- };
- var stats = recalcData(data); //since this can get called in the finish step, make sure it doesn't call setAttrs()
- var racename = getName("race", mancerdata, true);
- var subracename = getName("subrace", mancerdata, true);
- var classname = getName("class", mancerdata, true);
- var subclassname = getName("subclass", mancerdata, true);
- var classAbility = mancerdata["l1-class"] && mancerdata["l1-class"].data.class && mancerdata["l1-class"].data.class["Spellcasting Ability"] ? mancerdata["l1-class"].data.class["Spellcasting Ability"] : "";
- var expandedList = {};
- var additionalList = {};
- var blobs = getRelevantBlobs(mancerdata, "1", "l1");
-
- //First look through all Blobs for any blob.Powers
- _.each(blobs.all, function(blob) {
- if(blob.Powers) {
- var spells = JSON.parse(blob.Powers);
- //Examine each spell to determine if it is "Extended List". "Extended List" adds to the classes spell list.
- //Ravnica Guilds backgrounds such as Dimir Operative are examples of this
- _.each(spells, function(spell) {
- if(spell["Expanded List"]) {
- expandedList[spell.Level] = expandedList[spell.Level] ? expandedList[spell.Level].concat(spell["Expanded List"]) : spell["Expanded List"];
- }
- });
- }
- });
- //Look through blobs.sorted.
- _.each(blobs.sorted, function(sectionblobs, section) {
- //Subclass needs to be changed to class.
- var parentsection = section.replace("sub", "");
- additionalList[parentsection] = additionalList[parentsection] || []
- //Examine eaach blob for "Additional Spell List"
- _.each(sectionblobs, function(blob) {
- if(blob["Additional Spell List"]) {
- additionalList[parentsection].push(blob["Additional Spell List"]);
- }
- });
- });
- //Process spell data from blobs
- _.each(blobs.sorted, function(sectionblobs, section) {
- var parentsection = section.replace("sub", "");
- _.each(sectionblobs, function(blob) {
- //Looks through the blobs for Powers attribute
- //class.Powers contains the information for how many spells are choosen at each level & Prepared spells to be selected based on ability modifer + 1
- //[subclass, background, race}.Powers will contain KNOWN, CHOSEN, or EXPANDED LIST for extra spells granted by these sections
- if(blob.Powers) {
- var spells = JSON.parse(blob.Powers);
- allPowers[parentsection] = allPowers[parentsection] || {known: [], choices: []}
- _.each(spells, function(spell) {
- var numPowers = 0;
- expandedList[spell.Level] = expandedList[spell.Level] || [];
- //class.Powers will contain Prepared and Choose.
- //These are used to populate the number of selects needed for each spell lists on the Powers slide
- if(spell.Prepared) {
- numPowers = Math.max(stats.totals[spell.Prepared.split("+")[0].toLowerCase()].mod, 0) + parseInt(spell.Prepared.split("+")[1]);
- }
- if(spell.Choose) {
- numPowers = parseInt(spell.Choose);
- }
- //If Powers are to be Chosen or Prepared add them to a class list, expand the list, and set the Ability modifier & Level
- if(numPowers > 0) {
- _.times(numPowers, function(n) {
- var thisspell = {Level: parseInt(spell.Level)};
- thisspell.List = spell.List ? spell.List : classname;
- thisspell.AddList = additionalList[parentsection];
- thisspell.Ability = spell.Ability ? spell.Ability : classAbility;
- if(parentsection == "class") thisspell["Expanded List"] = expandedList[spell.Level];
- allPowers[parentsection].choices.push(thisspell);
- });
- }
- //Add any spells that are already known from sections such as Forge Domain Cleric starts with identify & searing smite
- _.each(spell.Known, function(known) {
- var thisspell = {Name: known, Level: parseInt(spell.Level)};
- thisspell.Ability = spell.Ability ? spell.Ability : classAbility;
- thisspell.Source = parentsection;
- allPowers[parentsection].known.push(thisspell);
- allPowers.known.push(known);
- allPowers.all.push(thisspell);
- });
- });
- }
- });
- });
- //Collect custom race/subrace spells
- if(mancerdata["l1-race"] && mancerdata["l1-race"].values.custom_race_spell_ability) {
- var raceAbility = mancerdata["l1-race"].values.custom_race_spell_ability;
- var numPowers = mancerdata["l1-race"].values.custom_race_spell_number;
- var spellList = mancerdata["l1-race"].values.custom_race_spell_list;
- if(spellList) {
- allPowers.race = allPowers.race || {known: [], choices: []}
- for(var x=1; x<=numPowers; x++) {
- var thisSpell = {
- Ability: raceAbility,
- Level: 0,
- List: spellList
- };
- allPowers.race.choices.push(thisSpell);
- }
- } else {
- allPowers.errors.race.push("custom_race_spell_list");
- }
- }
- //Collect custom class spells
- if(mancerdata["l1-class"] && mancerdata["l1-class"].values.custom_class_spell_ability) {
- var customAbility = mancerdata["l1-class"].values.custom_class_spell_ability;
- var customList = mancerdata["l1-class"].values.custom_class_spell_list;
- var customPowers = {"0": mancerdata["l1-class"].values.custom_class_prime_number, "1": mancerdata["l1-class"].values.custom_class_spell_number};
- if(customList && (customPowers["0"] > 0 || customPowers["1"] > 0)) {
- allPowers.class = allPowers.class || {known: [], choices: []}
- _.each(customPowers, function(number, level) {
- for(var x=1; x<=number; x++) {
- var thisSpell = {
- Ability: customAbility,
- Level: level,
- List: customList
- };
- allPowers.class.choices.push(thisSpell);
- }
- });
- } else {
- allPowers.errors.class.push("custom_class_spell_list");
- allPowers.errors.class.push("custom_class_spell_number");
- }
- }
- //Collect custom subclass spells
- if(mancerdata["l1-class"] && mancerdata["l1-class"].values.subclass == "Rules:Classes") {
- var customPowers = {"0": mancerdata["l1-class"].values.custom_subclass_prime_number, "1": mancerdata["l1-class"].values.custom_subclass_spell_number};
- if(customPowers["0"] > 0 || customPowers["1"] > 0) {
- allPowers.class = allPowers.class || {known: [], choices: []}
- _.each(customPowers, function(number, level) {
- var customList = classname.toLowerCase();
- if(level == "0" && mancerdata["l1-class"].values.custom_subclass_prime_list) customList = mancerdata["l1-class"].values.custom_subclass_prime_list;
- if(level == "1" && mancerdata["l1-class"].values.custom_subclass_spell_list) customList = mancerdata["l1-class"].values.custom_subclass_spell_list;
- for(var x=1; x<=number; x++) {
- var thisSpell = {
- Ability: classAbility,
- Level: level,
- List: customList
- };
- allPowers.class.choices.push(thisSpell);
- }
- });
- }
- }
- //Collect data from choices
- if(mancerdata["l1-spells"]) {
- _.each(mancerdata["l1-spells"].repeating, function(id) {
- if(mancerdata["l1-spells"].values[id + "_choice"]) {
- var thisspell = {Name: mancerdata["l1-spells"].values[id + "_choice"].substring(7)};
- thisspell.Ability = mancerdata["l1-spells"].values[id + "_info"] ? mancerdata["l1-spells"].values[id + "_info"] : classAbility;
- if(mancerdata["l1-spells"].values[id + "_custom"]) thisspell.Source = mancerdata["l1-spells"].values[id + "_custom"];
- allPowers.known.push(thisspell.Name);
- allPowers.all.push(thisspell);
- };
- });
- }
- return allPowers;
-};
-
-var cleanEquipment = function(equipment) {
- var current_string = "(";
- var hasDouble = false;
- var firstItem = true;
- _.each(equipment, function(item) {
- if (item.search("~DBL") != -1) {
- hasDouble = true;
- item.replace("~DBL","");
- }
- item = item.replace(/"Item Type":(.|)Weapon.*\b/g, "Any Weapon");
- item = item.replace(/Subtype:(.|)Martial.*\b("|)/g, "Any Martial Weapon");
- item = item.replace(/Subtype:(.|)Simple.*\b("|)/g, "Any Simple Weapon");
- item = item.replace(/Subtype:(.|)Artisan's Tools.*\b("|)/g, "A Set of Artisan's Tools");
- item = item.replace(/Subtype:(.|)Gaming Set.*\b("|)/g, "A Gaming Set");
- item = item.replace(/Subtype:(.|)Musical Instrument.*\b("|)/g, "A Musical Instrument");
- if (!firstItem) current_string += " or ";
- current_string += item;
- firstItem = false;
- });
- current_string += ")";
- if (hasDouble) {
- current_string = "two of " + current_string;
- }
- return current_string.replace(/,/g, ", ");
-};
-
-const removeExpansionInfo = function(text) {
- return text.replace(/\??expansion\=([0-9]+)?/gi, "");
-};
-
-var removeDuplicatedPageData = function(data) {
- if(!Array.isArray(data)) return data;
- const getPageName = function(item) {
- let category = "";
- if("data" in item && "Category" in item.data) category += item.data["Category"] + ": ";
- return category+item.name;
- }
- let seen = {};
- return data.filter(function(item) {
- let pageName = getPageName(item);
- return seen.hasOwnProperty(pageName) ? false : (seen[pageName] = true);
- })
-};
-
-var getName = function(request, data, custom) {
- data = data || getCharmancerData();
- var section = request.replace("sub", "");
- var result = "";
- var customString = custom ? "custom" : "";
- if( data["l1-" + section] && data["l1-" + section].values[request] ) {
- result = data["l1-" + section].values[request + "_name"] || data["l1-" + section].values[request];
- }
- result = result.split(":")[0] == "Rules" || result.split(":")[0] == "CategoryIndex" ? customString : result;
- //Removing expansion name from result
- result = removeExpansionInfo(result);
- return _.last(result.split(":"));
-};
-
-var getGainedPowers = function() {
- let gainedPowers = [];
- const data = getCharmancerData();
- if("lp-spells" in data && "values" in data["lp-spells"]) {
- Object.keys(data["lp-spells"].values).forEach(key => {
- let found = false;
- if(key.indexOf("_checked") === -1) return;
- let spellNameKey = key.replace("_checked", "_name");
- let spellName = data["lp-spells"].values[spellNameKey];
- if(data["lp-welcome"].values.spellinfo) {
- let previousPowers = JSON.parse(data["lp-welcome"].values.spellinfo);
- Object.keys(previousPowers).forEach(spell => {
- if(previousPowers[spell].spellname === spellName) found = true;
- });
- }
- if(!found) gainedPowers.push(spellName);
- });
- }
- return gainedPowers;
-};
-
-var getGainedFeatures = function() {
- const data = getCharmancerData();
- if(!"lp-levels" in data) return;
- let gainedFeatures = [];
- for(let charclass=1; charclass<=4; charclass++) {
- let levelsGained = data["lp-levels"].values["class"+ charclass +"_addlevel"] || 0;
- if(levelsGained === 0) continue; //No leves gained in this class, just skip to the next one.
-
- //Now lets get the features got from each class at LP;
- levelsGained = parseInt(levelsGained);
- let currentLevel = parseInt(data["lp-levels"].values["class"+ charclass +"_currentlevel"]);
- Object.keys(data["lp-levels"].data["class"+charclass].blobs).forEach(feature => {
- let featureLevel = parseInt(data["lp-levels"].data["class"+charclass].blobs[feature]["Level"]);
- if(featureLevel > currentLevel && featureLevel <= (currentLevel+levelsGained)) {
- let sanitizedFeatureName = feature.replace(/\(.+\)/g,"");
- sanitizedFeatureName = sanitizedFeatureName.replace(/ - .+/g,"").trim();
- if("Group" in data["lp-levels"].data["class"+charclass].blobs[feature]) return;
- if("Choice" in data["lp-levels"].data["class"+charclass].blobs[feature]) {
- Object.keys(data["lp-choices"].values).forEach(info => {
- if(data["lp-choices"].values[info] === feature) {
- let choice = info.replace("_info", "_choice");
- if(choice in data["lp-choices"].values) {
- let choiceName = data["lp-choices"].values[choice].replace("Blob:", "");
- if(gainedFeatures.indexOf(choiceName) === -1) gainedFeatures.push(choiceName);
- }
- }
- });
- } else {
- if(gainedFeatures.indexOf(sanitizedFeatureName) === -1) gainedFeatures.push(sanitizedFeatureName);
- }
- }
- });
- }
- return gainedFeatures;
-};
-
-var filterBlobs = function(blobs, filters) {
- var remove = filters.multiclass ? "no" : "yes";
- var results = {};
- delete filters.multiclass;
- delete filters.slide;
- _.each(blobs, function(blob, name) {
- var match = true;
- if(blob.Group && !filters.Group && !filters.name) match = false;
- _.each(filters, function(v, k) {
- if(k == "name") {
- if(name != v) match = false;
- } else if(v[0] === "<" && !isNaN(parseInt(v.substring(1)))) {
- let blobval = isNaN(parseInt(blob[k])) ? 0 : parseInt(blob[k]);
- if(blobval > parseInt(v.substring(1))) match = false;
- } else {
- if(blob[k] != v) match = false;
- }
- });
- if(match && name.split("(")[0].toLowerCase() != "spell slots") results[name] = blob;
- });
- _.each(results, function(blob, name) {
- if(blob.Multiclass == remove) {
- delete results[name];
- }
- });
- return results;
-};
-
-var handleBlobs = function(blobs, options) {
- //Old parameters: (blobs, filters, section, element, thisblob)
-
- //Function to get blob parameter for Spell Pickers like Magical Secrets
- //By Miguel
- const getBlobDescription = function(blob) {
- if("Description" in blob) {
- return blob.Description;
- }
- else if("Traits" in blob) {
- traits = JSON.parse(blob.Traits)[0];
- if("Desc" in traits) return traits.Desc;
- }
- return "";
- }
-
- const handleProficiencies = function(data, subsection) {
- if(!data) {
- return;
- }
- subsection = subsection ? subsection : element
- _.each(proficiencyList, function(prof) {
- if(data[prof + " Proficiency"]) {
- addRepeatingSection(subsection, "row", function(rowid) {
- var json = JSON.parse(data[prof + " Proficiency"]);
- if(!json.Hidden) {
- var repupdate = {};
- repupdate[rowid + " label span"] = json.Title ? json.Title : getTranslationByKey(prof.toLowerCase() + "-proficiencies");
- if(json.Desc) {
- repupdate[rowid + " label p"] = json.Desc;
- if(json.Proficiencies) {
- repupdate[rowid + " label p"] += "
" + json.Proficiencies.join(", ");
- }
- } else if(json.Proficiencies) {
- repupdate[rowid + " label p"] = json.Proficiencies.join(", ");
- }
- setCharmancerText(repupdate);
- }
- _.each(json.Choice, function(v) {
- addRepeatingSection(rowid + " label", "choose", section + "_" + prof.toLowerCase(), function(id) {
- var choices = "";
- var settings = {category: "Proficiencies", disable: profdata.all[prof]};
- if(prof == "Language") {
- var customupdate = {};
- customupdate[id + " select"] = '
';
- setCharmancerText(customupdate);
- }
- if(Array.isArray(v)) {
- if(v[0].split(":").length > 1) {
- choices = "Category:Proficiencies \"Type:" + prof + "\" " + v.shift();
- settings.add = v;
- } else if (v[0] == "all") {
- v.shift();
- choices = "Category:Proficiencies \"Type:" + prof + "\"";
- settings.add = v;
- } else {
- choices = v;
- }
- } else {
- choices = "Category:Proficiencies \"Type:" + prof + "\"";
- if(v != "all" && v != "any") {
- console.log("MISSED THE ALL CHECK")
- console.log(v);
- choices += " " + v;
- }
- }
- setCharmancerOptions(id + "_choice", choices, settings);
- });
- });
- });
- }
- });
- if(data.Expertise) {
- addRepeatingSection(subsection, "row", function(rowid) {
- var json = JSON.parse(data.Expertise);
- if(json.Title) {
- var repupdate = {};
- repupdate[rowid + " label span"] = json.Title;
- setCharmancerText(repupdate);
- }
- _.each(json.Choice, function(v) {
- addRepeatingSection(rowid + " label", "choose", section + "_expertise", function(id) {
- var choices = "";
- var settings = {category: "Proficiencies", disable: profdata.all.Expertise};
- if(v[0].split(":").length > 1) {
- choices = "Category:Proficiencies \"Type:" + prof + "\" " + v.shift();
- settings.add = v;
- } else if (v[0] == "KNOWN") {
- var info = {};
- info[id + "_info"] = JSON.stringify(v);
- setAttrs(info);
- v.shift();
- choices = profdata.all.Skill;
- settings.add = v;
- } else {
- choices = v;
- }
- setCharmancerOptions(id + "_choice", choices, settings);
- });
- });
- });
- }
- };
- const handleTraits = function(blob, subsection, name) {
- var traits = JSON.parse(blob.Traits);
- subsection = subsection ? subsection : element;
- _.each(traits, function(trait) {
- if(trait["Input Powers"]) {
- addRepeatingSection(subsection, "utilityrow", function(rowid) {
- let repupdate = {};
- let set = {};
- repupdate[`${rowid} label span .sheet-title`] = trait.Name.split("{{")[0];
- if(!trait.Hide) repupdate[`${rowid} label p`] = trait.Desc;
- repupdate[`${rowid} button`] = trait["Input Powers"].ButtonText;
- set[`${rowid}_info`] = JSON.stringify(trait["Input Powers"]);
- set[`${rowid}_type`] = "trait";
- set[`${rowid}_blob`] = name;
- set[`${rowid}_parent`] = options.parent;
- set[`${rowid}_title`] = trait.Name;
- set[`${rowid}_desc`] = trait.Desc;
- setCharmancerText(repupdate);
- setAttrs(set);
- });
- } else if(!trait.Hide) {
- addRepeatingSection(subsection, "row", function(rowid) {
- let repupdate = {};
- if(trait.Input) {
- //Fixing custom data in inputs not being remembered when switching tabs (UC809)
- //By Miguel
- const data = getCharmancerData();
- //The function below looks for valyes through all Mancer data that match a input rowid:
- const getPreviousInputValue = function(data, rowid) {
- let parsedId = rowid.match(/-.+_/g)[0];
- for(let attribute in data) {
- if(!("values" in data[attribute])) continue;
- for (let key in data[attribute].values){
- if(data[attribute].values.hasOwnProperty(key) && key.indexOf("_input") > -1 && key.indexOf(parsedId) > -1) {
- return data[attribute].values[key];
- }
- }
- }
- return "";
- }
- const previousValue = getPreviousInputValue(data, rowid);
- repupdate[`${rowid} label span`] = `
`;
- repupdate[`${rowid} label span`] += `
`;
- repupdate[`${rowid} label span`] += `
`;
- repupdate[`${rowid} label span`] += `
`;
- } else {
- repupdate[`${rowid} label span`] = trait.Name;
- repupdate[`${rowid} label p`] = blob.Prerequisite ? "
" + blob.Prerequisite + "
" : "";
- //Fixing undefined when selecting Ranger Favored Enemy and Land (UC809)
- //By Miguel
- repupdate[`${rowid} label p`] += (trait.Desc ? trait.Desc : "");
- }
- setCharmancerText(repupdate);
- handleProficiencies(blob, rowid);
- });
- };
- });
- };
- const mancerdata = getCharmancerData();
- let filters = options.filters || {};
- let section = options.section || undefined;
- let thisblob = options.thisblob || undefined;
- let element = options.element ? options.element : section + "_holder";
- let sorted = {choices: {}, traits: {}, other: {}, spells: {}};
- let profdata = getProficiencies(mancerdata, options.slide);
- let filtered = {};
- if(thisblob) {
- filtered[thisblob] = blobs[thisblob];
- } else {
- filtered = filterBlobs(blobs, filters);
- }
- _.each(filtered, function(blob, name) {
- if(name.split(" ")[0] == "Proficiencies") {
- sorted.proficiencies = blob;
- } else if (blob["Pick Powers"]) {
- sorted.spells[name] = blob;
- } else if(blob.Choice) {
- sorted.choices[name] = blob;
- } else if(blob.Traits) {
- sorted.traits[name] = blob;
- } else {
- sorted.other[name] = blob;
- }
- });
-
- handleProficiencies(sorted.proficiencies);
- _.each(sorted.choices, function(blob, name) {
- addRepeatingSection(element, "row", function(rowid) {
- var title = blob.Title ? blob.Title : name;
- var choice = blob.Choice;
- var settings = {};
- let choicenum = blob["Choice Number"] ? parseInt(blob["Choice Number"]) : 1;
- if(blob.Choice.split(":")[0] == "Blob") {
- choice = Object.keys(filterBlobs(blobs, {Group: blob.Choice.split(":")[1], Level: ("<" + (options.maxlevel || blob.Level))})).sort();
- settings.category = "Blob";
- }
- var repupdate = {};
- repupdate[rowid + " label span"] = title;
- if(blob.Description) {
- repupdate[rowid + " label p"] = blob.Description;
- }
- setCharmancerText(repupdate);
- if(section.indexOf("-") === -1) {
- let match = /[0-9]+$/.exec(section);
- if(match) {
- section = [section.slice(0, match.index), "-", section.slice(match.index)].join('');
- section += "--" + blob.Level;
- }
- }
- for(let x=1; x<=choicenum; x++) {
- addRepeatingSection(rowid + " label", "choose", section + "_feature", function(id) {
- var info = {};
- info[id + "_info"] = title;
- setAttrs(info);
- setCharmancerOptions(id + "_choice", choice, settings, function() {
- if(mancerdata[options.slide].values[id + "_choice"] && mancerdata[options.slide].values[id + "_choice"].split(":")[0] == "Blob") {
- handleBlobs(blobs, {
- filters: {name: mancerdata[options.slide].values[id + "_choice"].split(":")[1]},
- section: section,
- element: id + " span",
- slide: options.slide,
- parent: options.parent
- });
- }
- });
- });
- }
- handleProficiencies(blob, rowid);
- });
- });
- _.each(sorted.spells, function(blob, name) {
- addRepeatingSection(element, "row", function(rowid) {
- let title = blob.Title ? blob.Title : name;
- let spells = JSON.parse(blob["Pick Powers"]);
- let settings = {};
- let repupdate = {};
- repupdate[rowid + ">label>span"] = title;
-
- //This used to check for blob.Description which does not exist for Spell Pickers
- //In such case the description is located at blob.Traits.Desc
- //By Miguel
- let description = getBlobDescription(blob);
- if(description.length > 0) {
- repupdate[rowid + ">label>p"] = description;
- }
-
- _.each(spells, function(spell) {
- addRepeatingSection(rowid, "utilityrow", function(rowid) {
- let repupdate = {};
- let set = {};
- repupdate[`${rowid} button`] = spell.ButtonText;
- set[`${rowid}_info`] = JSON.stringify(spell);
- set[`${rowid}_type`] = "pick";
- set[`${rowid}_parent`] = options.parent;
- set[`${rowid}_blob`] = name;
- setCharmancerText(repupdate);
- setAttrs(set);
- });
- })
- setCharmancerText(repupdate);
- handleProficiencies(blob, rowid);
- });
- });
- _.each(sorted.other, function(blob, name) {
- if(blob.Title || blob.Description) {
- addRepeatingSection(element, "row", function(rowid) {
- var title = blob.Title ? blob.Title : name;
- var repupdate = {};
- repupdate[rowid + " label span"] = "" + title;
- repupdate[`${rowid} label p`] = blob.Prerequisite ? "
" + blob.Prerequisite + "
" : "";
- if(blob.Description) repupdate[rowid + " label p"] += blob.Description;
- setCharmancerText(repupdate);
- handleProficiencies(blob, rowid);
- });
- } else {
- handleProficiencies(blob);
- }
- });
- _.each(sorted.traits, function(blob, name) {
- var traitsObj = JSON.parse(blob.Traits);
- var title = blob.Title ? blob.Title : name;
- if(blob.Description || traitsObj.length > 1) {
- addRepeatingSection(element, "row", function(rowid) {
- if(blob.Description || blob.Title) {
- var repupdate = {};
- repupdate[rowid + " label span"] = "" + title;
- if(blob.Description) repupdate[rowid + " label p"] = "" + blob.Description;
- setCharmancerText(repupdate);
- }
- handleTraits(blob, rowid, name);
- handleProficiencies(blob, rowid);
- });
- } else {
- handleTraits(blob, undefined, name);
- }
- });
-};
-
-var addCustomSections = function(section) {
- var lower = section.toLowerCase();
- var page = "l1-" + lower.replace("sub", "");
- var mancerdata = getCharmancerData()[page];
- var repids = [];
- var total = 0;
- var current = 0;
- var traits = [];
- var profs = [];
- console.log(mancerdata);
- _.each(mancerdata.repeating, function(repid) {
- if(_.last(repid.split("_")) == "trait") {
- if(mancerdata.values[repid + "_name"] || mancerdata.values[repid + "_desc"]) {
- var thistrait = {};
- thistrait.name = mancerdata.values[repid + "_name"] ? mancerdata.values[repid + "_name"] : "";
- thistrait.desc = mancerdata.values[repid + "_desc"] ? mancerdata.values[repid + "_desc"] : "";
- traits.push(thistrait);
- total++;
- }
- }
- if(_.last(repid.split("_")) == "proficiency") {
- if(mancerdata.values[repid + "_type"]) {
- var thisprof = {};
- thisprof.type = mancerdata.values[repid + "_type"];
- thisprof.choice = mancerdata.values[repid + "_choice"] ? mancerdata.values[repid + "_choice"] : "";
- profs.push(thisprof);
- total++;
- }
- }
- });
- if(traits.length == 0) {
- traits.push({name: "", desc: ""});
- total++;
- }
- if(profs.length == 0) {
- profs.push({type: "", choice: ""});
- total ++;
- }
- addRepeatingSection(lower + "_holder", "row", "customrow", function(rowid) {
- var toset = {};
- toset[rowid + " label span"] = "Proficiencies";
- repids.push(rowid);
- setCharmancerText(toset);
- _.each(profs, function(prof) {
- addRepeatingSection(rowid, "custom-proficiency", "custom_" + lower + "_proficiency", function(id) {
- var toset = {};
- if(prof.type != "") toset[id + "_type"] = prof.type;
- if(prof.choice != "") toset[id + "_choice"] = prof.choice;
- setAttrs(toset);
- current++;
- repids.push(id);
- if(current >= total) clearRepeating(repids, page, "customrow");
- });
- });
- });
- addRepeatingSection(lower + "_holder", "row", "customrow", function(rowid) {
- var toset = {};
- toset[rowid + " label span"] = "Custom " + section + " Features";
- repids.push(rowid);
- setCharmancerText(toset);
- _.each(traits, function(trait) {
- addRepeatingSection(rowid, "custom-trait", "custom_" + lower + "_trait", function(id) {
- var toset = {};
- if(trait.name != "") toset[id + "_name"] = trait.name;
- if(trait.desc != "") toset[id + "_desc"] = trait.desc;
- //update[id + " span"] = trait.name;
- setAttrs(toset);
- current++;
- repids.push(id);
- if(current >= total) clearRepeating(repids, page, "customrow");
- });
- });
- });
-}
-
-var clearRepeating = function(repids, page, match) {
- //This function removes all repeating sections that aren't in the repids array (except for the topbar).
- //The optional third argument will only remove certain types of repeating sections
- var mancerdata = getCharmancerData();
- _.each(mancerdata[page].repeating, function(repid) {
- if(_.last(repid.split("_")) != "topbar" && !repids.includes(repid) && (!match || match && repid.includes(match))) clearRepeatingSectionById(repid);
- });
-}
-
-//This function should be used to read additional hit points gained at first level by things like Draconic Bloodline or Hill Dwarf. Can be possbily be used in the future for Tough feat(?)
-//By Miguel
-var getAdditionalHitPointsFromClassAndRaceAtFirstLevel = function(blobs) {
- let additionalHP = 0;
- blobs.all.map(blob => {
- if("Hit Points Per Level" in blob) {
- additionalHP += parseInt(blob["Hit Points Per Level"]);
- }
- });
- return additionalHP;
-};
-
-var getRelevantBlobs = function(mancerdata, level, section) {
- var results = [];
- var sorted = {};
- var names = {};
- level = level ? "" + level : "1";
- _.each(mancerdata, function(slide, slidename) {
- if(slidename.split("-")[0] == section) {
- _.each(slide.data, function(data, section) {
- if(data.blobs) {
- var levelblobs = _.extend(filterBlobs(data.blobs, {"Level": level}), filterBlobs(data.blobs, {"Level": "every"}));
- sorted[section] = [];
- names[section] = [];
- _.each(levelblobs, function(blob, blobname) {
- results.push(blob);
- sorted[section].push(blob);
- names[section].push(blobname);
- });
- };
- });
- _.each(slide.values, function(value, name) {
- if((value + "").split(":")[0] == "Blob") {
- var section = name.split("_")[2];
- var blobs = slide.data[section] && slide.data[section].blobs ? slide.data[section].blobs : [];
- _.each(filterBlobs(blobs, {"name":value.split(":")[1]}), function(blob, blobname) {
- results.push(blob);
- sorted[section] = sorted[section] ? sorted[section] : [];
- sorted[section].push(blob);
- names[section] = names[section] ? names[section] : [];
- names[section].push(blobname);
- });
- };
- });
- }
- });
- return {all: results, sorted: sorted, names: names};
-};
-
-var costOfScore = function(score) {
- if (isNaN(score) || score == 8) {
- return 0;
- }
- var cost = 0;
- if (score > 8) {
- if (score < 14) {
- cost = score - 8;
- } else if (score == 14) {
- cost = 7;
- } else if (score == 15) {
- cost = 9;
- } else { // Score should never be higher, but let's cover our bases.
- cost = 11;
- }
- }
- return cost;
-};
-
-var recalcPoints = function() {
- data = getCharmancerData();
- var attribs = ["strength","dexterity","constitution","intelligence","wisdom","charisma"];
- var maxPoints = 27;
-
- var scores = {};
-
- _.each(attribs, function(attrib) {
- scores[attrib] = parseInt(data["l1-abilities"].values[attrib]);
- if (isNaN(scores[attrib])) {
- scores[attrib] = 8;
- }
- });
-
- var pointsAvailable = maxPoints;
-
- // Decrement points based on selected attribs
- _.each(scores, function(score) {
- if (!isNaN(score)) {
- var cost = costOfScore(score);
- pointsAvailable -= cost;
- }
- });
-
- // Disable options if points are below a threshold.
- if (pointsAvailable < 9) {
- var choicesToDisable = ["15","14","13","12","11","10","9"];
-
- _.each(attribs, function(attrib) {
- var toDisableForThisAttrib = []
- _.each(choicesToDisable, function(choice) {
- if (scores[attrib] <= Number(choice) && (costOfScore(scores[attrib]) + pointsAvailable < costOfScore(Number(choice)))) {
- toDisableForThisAttrib.push(choice);
- }
- });
- disableCharmancerOptions(attrib, toDisableForThisAttrib);
- });
- } else {
- _.each(attribs, function(attrib) {
- disableCharmancerOptions(attrib, []);
- });
- }
-
- _.each(attribs, function(attrib) {
- setCharmancerText({"points_available_display":String(pointsAvailable)});
- });
-
- return String(pointsAvailable);
-};
-
-var setRollButton = function(name, data, title, hold) {
- getAttrs(["licensedsheet"], function(v) {
- var set = {};
- var holdstring = hold ? "r" + hold : "";
- title = title || name.split("_")[1];
- title = title[0].toUpperCase() + title.substring(1);
- const licensedsheet = (v.licensedsheet && v.licensedsheet === "1") ? "licensedsheet" : "";
- if(title == "Personality") title += " Trait";
- var roll = `@{wtype}&{template:mancerroll} {{title=${title}}} {{c1=[[1d${data.length + holdstring}]]}} {{licensedsheet=${licensedsheet}}}`;
- _.each(data, function(trait, x) {
- roll += ' {{option' + (x+1) + '=' + trait + '}}';
- });
- set["roll_" + name + "_roll"] = roll;
- if(!hold) {
- set[name + "_array"] = JSON.stringify({name: title, array: data});
- }
- setAttrs(set);
- });
-};
-
-/* MAIN CHOICE HANDLING */
-on("mancerchange:race", function(eventinfo) {
- var mancerdata = getCharmancerData();
- getProficiencies(mancerdata, eventinfo.currentStep);
- changeCompendiumPage("sheet-race-info", eventinfo.newValue);
- hideChoices();
-
- var reset = {};
- if(!(eventinfo.newValue === "" || eventinfo.newValue === undefined)) {
- showChoices(["race_options"]);
- }
- recalcData();
-
- if(eventinfo.sourceType == "player") {
- reset = {race_ability_choice1: "", race_ability_choice2: "", subrace_ability_choice1: "", subrace_ability_choice2: "", subrace: "", race_name: "", subrace_name: ""};
- _.each(abilityList, function(ability){
- reset["race_custom_" + ability.toLowerCase()] = 0;
- reset["subrace_custom_" + ability.toLowerCase()] = 0;
- reset[ability.toLowerCase() + "_save"] = "";
- });
- reset["custom_race_spell_ability"] = "";
- reset["custom_race_spell_number"] = "1";
- reset["custom_race_spell_list"] = "";
- reset["race_name"] = "";
- reset["subrace_name"] = "";
- reset["has_subrace"] = "";
- clearRepeatingSections("race_holder");
- clearRepeatingSections("subrace_holder");
- }
-
- if(eventinfo.newValue === "Rules:Races") {
- //Clears saved data for this field
- getCompendiumPage("");
- setAttrs(reset, function() {
- var update = {"race_text": ""};
- var options = eventinfo.sourceType == "player" ? {selected: ""} : {};
- showChoices(["custom_race"]);
- setCharmancerText(update);
- addCustomSections("Race");
- deleteCharmancerData(["l1-feat"]);
- });
- } else {
- getCompendiumPage(eventinfo.newValue, function(p) {
- p = removeDuplicatedPageData(p);
- setAttrs(reset, function() {
- mancerdata = getCharmancerData();
- var update = {};
- var showList = ["race_always", "race_traits"];
- var possibles = ["race_size", "race_speed", "race_ability_score", "race_traits"];
- var data = p["data"];
-
- _.each(proficiencyList, function(type){
- possibles.push("race_" + type.toLowerCase() + "s");
- });
- _.each(possibles, function(key) {
- update[key] = "";
- });
-
- if(data["Size"]) {update["race_size"] = data["Size"];};
- if(data["Speed"]) {update["race_speed"] = data["Speed"];};
-
- showList = showList.concat(handleAbilities(data, "race"));
- if(data["data-Ability Score Increase"]) {
- var abilityText = [];
- var json = JSON.parse(data["data-Ability Score Increase"]);
- _.each(json, function(increase, ability) {
- abilityText.push(ability + " +" + increase);
- });
- update["race_ability_score"] = abilityText.join(", ");
- }
- handleBlobs(data.blobs, {filters: {"Level": "1"}, section: "race", slide: "l1-race"});
-
- setCharmancerText(update);
-
- var race_name = eventinfo.newValue && eventinfo.newValue.split(":").length > 1 && eventinfo.newValue.split(":")[0] === "Races" ? eventinfo.newValue.split(":")[1] : false;
- race_name = removeExpansionInfo(race_name);
- if(race_name) {
- var subOptions = {show_source: true};
- if(eventinfo.sourceType != "player") {
- subOptions.silent = true;
- } else {
- subOptions.selected = "";
- }
-
- setCharmancerOptions("subrace","Category:Subraces data-Parent:" + race_name, subOptions, function(values) {
- if (values.length) {
- setAttrs({"has_subrace": "true"});
- showChoices(["subrace"]);
- }
- });
- }
- else {
- hideChoices(["subrace"]);
- }
-
- showChoices(showList);
- recalcData();
- });
- });
- }
-});
-
-on("mancerchange:subrace", function(eventinfo) {
- var mancerdata = getCharmancerData();
- getProficiencies(mancerdata, eventinfo.currentStep);
- changeCompendiumPage("sheet-race-info", eventinfo.newValue);
-
- var initHide = ["subrace_possible", "custom_trait_2", "custom_trait_3", "custom_trait_4"];
- var reset = {};
- if(eventinfo.newValue === "" || eventinfo.newValue === undefined) {
- initHide.push("subrace_options");
- }
- else {
- showChoices(["subrace_options"]);
- }
- hideChoices(initHide);
- recalcData();
- if(eventinfo.sourceType == "player") {
- reset = {subrace_ability_choice1: "", subrace_ability_choice2: "", subrace_name: ""};
- _.each(abilityList, function(ability){
- reset["race_custom_" + ability.toLowerCase()] = 0;
- reset["subrace_custom_" + ability.toLowerCase()] = 0;
- });
- reset["custom_race_spell_ability"] = "";
- reset["custom_race_spell_number"] = "1";
- reset["custom_race_spell_list"] = "";
- reset["subrace_name"] = "";
- clearRepeatingSections("subrace_holder");
- }
-
- if(eventinfo.newValue === "Rules:Races") {
- //Clears saved data for this field
- getCompendiumPage("");
- setAttrs(reset, function() {
- var update = {"subrace_text": ""};
- var options = eventinfo.sourceType == "player" ? {selected: ""} : {};
- showChoices(["custom_subrace"]);
- setCharmancerText(update);
- addCustomSections("Subrace");
- deleteCharmancerData(["l1-feat"]);
- });
- } else {
- hideChoices(["custom_subrace"]);
- getCompendiumPage(eventinfo.newValue, function(p) {
- p = removeDuplicatedPageData(p);
- var update = {};
- var showList = ["subrace_choices"];
- var possibles = ["subrace_speed", "subrace_ability_score"];
- var data = p["data"];
- _.each(possibles, function(key) {
- update[key] = "";
- });
-
- if(!data["data-Feats"]) deleteCharmancerData(["l1-feat"], function() {recalcData();});
-
- if(data["Speed"]) {
- update["subrace_speed"] = data["Speed"];
- showList.push("subrace_speed_row");
- };
-
- showList = showList.concat(handleAbilities(data, "subrace"));
- if(data["data-Ability Score Increase"]) {
- var abilityText = [];
- var json = JSON.parse(data["data-Ability Score Increase"]);
- _.each(json, function(increase, ability) {
- abilityText.push(ability + " +" + increase);
- });
- update["subrace_ability_score"] = abilityText.join(", ");
- }
- handleBlobs(data.blobs, {filters: {"Level": "1"}, section: "subrace", slide: "l1-race"});
-
- setCharmancerText(update);
- showChoices(showList);
- setAttrs(reset);
- recalcData();
- });
- }
-});
-
-on("mancerchange:class", function(eventinfo) {
- var mancerdata = getCharmancerData();
- getProficiencies(mancerdata, eventinfo.currentStep);
- changeCompendiumPage("sheet-class-info", eventinfo.newValue);
- hideChoices();
-
- var initHide = ["class_possible", "subclass_choices"];
- var reset = {};
- if(!(eventinfo.newValue === "" || eventinfo.newValue === undefined)) {
- showChoices(["classes_options"]);
- }
- var current = recalcData();
-
- if(eventinfo.sourceType == "player") {
- reset = {subclass: ""};
- _.each(abilityList, function(ability){
- reset[ability.toLowerCase() + "_save"] = "";
- });
- reset["custom_class_spell_ability"] = "";
- reset["custom_class_prime_number"] = "0";
- reset["custom_class_spell_number"] = "0";
- reset["custom_class_spell_list"] = "";
- reset["custom_hit_die"] = "";
- reset["class_name"] = "";
- reset["subclass_name"] = "";
- reset["class_equipment_choice1"] = "";
- reset["class_equipment_choice2"] = "";
- reset["class_equipment_choice3"] = "";
- reset["class_equipment_choice4"] = "";
- clearRepeatingSections("class_holder");
- clearRepeatingSections("subclass_holder");
- }
-
- if(eventinfo.newValue === "Rules:Classes") {
- //Clears saved data for this field
- getCompendiumPage("");
- setAttrs(reset, function() {
- var update = {"class_text": "", "custom_feature_name": "Class Features"};
- var options = eventinfo.sourceType == "player" ? {selected: ""} : {}
- showChoices(["custom_class"]);
- update["custom_feature_name"] = "Custom Class Features";
- setCharmancerText(update);
- addCustomSections("Class");
- });
- } else {
- getCompendiumPage(eventinfo.newValue, function(p) {
- p = removeDuplicatedPageData(p);
- var update = {};
- var showList = [];
- var data = p["data"];
- var hideList = [];
- handleBlobs(data.blobs, {filters: {"Level": "1"}, section: "class", slide: "l1-class"});
-
- var class_name = eventinfo.newValue && eventinfo.newValue.split(":").length > 1 && eventinfo.newValue.split(":")[0] === "Classes" ? eventinfo.newValue.split(":")[1] : false;
- class_name = removeExpansionInfo(class_name);
- if(class_name && data["data-Subclass Level"] == 1) {
- var subOptions = {show_source: true};
- if(eventinfo.sourceType != "player") {
- subOptions.silent = true;
- } else {
- subOptions.selected = "";
- }
- update["subclass_prompt"] = "Choose a " + data["Subclass Name"];
- setCharmancerOptions("subclass","Category:Subclasses data-Parent:" + class_name, subOptions, function(values) {
- if (values.length) showChoices(["subclass"]);
- });
- }
- else {
- hideList.push("subclass");
- }
-
- if (data["data-Equipment"]) {
- showList.push("class_equipment_row");
- var equipment_string = "";
- var json = JSON.parse(data["data-Equipment"]);
- if(json["default"]) {
- equipment_string += json["default"].join(", ");
- }
- for (var i = 1; i < 5; i++) {
- if(json[i]) {
- if (!json["default"].length && i == 1) {
- equipment_string += "";
- } else {
- equipment_string += " and ";
- }
-
- equipment_string += cleanEquipment(json[i]);
- }
- };
- update["class_standard_equipment"] = equipment_string;
- }
-
- setCharmancerText(update);
- showChoices(showList);
- hideChoices(hideList);
- recalcData();
- setAttrs(reset);
- });
- }
-});
-
-on("mancerchange:subclass", function(eventinfo) {
- var mancerdata = getCharmancerData();
- getProficiencies(mancerdata, eventinfo.currentStep);
- changeCompendiumPage("sheet-class-info", eventinfo.newValue);
-
- var initHide = ["subclass_possible"];
- var reset = {};
- if(eventinfo.newValue === "" || eventinfo.newValue === undefined) {
- initHide.push("subclass_options");
- initHide.push("custom_subclass");
- }
- else {
- showChoices(["subclass_options"]);
- if(eventinfo.newValue === "Rules:Classes") {
- showChoices(["custom_subclass"]);
- }
- else {
- initHide.push("custom_subclass");
- }
- }
- hideChoices(initHide);
- var current = recalcData();
-
- if(eventinfo.sourceType == "player") {
- reset["custom_class_spell_ability"] = "";
- reset["custom_class_prime_number"] = "0";
- reset["custom_class_spell_number"] = "0";
- reset["custom_class_spell_list"] = "";
- reset["custom_subclass_prime_number"] = "0";
- reset["custom_subclass_prime_list"] = "";
- reset["custom_subclass_spell_number"] = "0";
- reset["custom_subclass_spell_list"] = "";
- reset["subclass_name"] = "";
- clearRepeatingSections("subclass_holder");
- }
-
- if(eventinfo.newValue === "Rules:Classes") {
- //Clears saved data for this field
- getCompendiumPage("");
- setAttrs(reset, function() {
- var mancerdata = getCharmancerData();
- var options = eventinfo.sourceType == "player" ? {selected: ""} : {};
- var subclassname = mancerdata["l1-class"].data.class["Subclass Name"];
- showChoices(["custom_subclass"]);
- if(mancerdata["l1-class"].data.class && mancerdata["l1-class"].data.class["Spellcasting Ability"]) {
- showChoices(["custom_additional_spells"]);
- } else {
- showChoices(["custom_class_spells"]);
- }
- addCustomSections("Subclass");
- });
- } else {
- hideChoices(["custom_subclass"]);
- getCompendiumPage(eventinfo.newValue, function(p) {
- p = removeDuplicatedPageData(p);
- var data = p["data"];
- handleBlobs(data.blobs, {filters: {"Level": "1"}, section: "subclass", slide: "l1-class"});
-
- recalcData();
- setAttrs(reset);
- });
- }
-});
-
-on("mancerchange:background", function(eventinfo) {
- var mancerdata = getCharmancerData();
- getProficiencies(mancerdata, eventinfo.currentStep);
- changeCompendiumPage("sheet-background-info", eventinfo.newValue);
-
- var initHide = ["background_possible", "custom_background"];
- var reset = {};
- if(eventinfo.newValue === "" || eventinfo.newValue === undefined) {
- initHide.push("backgrounds_options");
- }
- else {
- showChoices(["backgrounds_options"]);
- }
- hideChoices(initHide);
- var current = recalcData();
-
- if(eventinfo.sourceType == "player") {
- reset = {};
- reset["background_detail_choice"] = "";
- reset["background_personality_choice1"] = "";
- reset["background_personality_choice2"] = "";
- reset["background_ideal_choice"] = "";
- reset["background_bond_choice"] = "";
- reset["background_flaw_choice"] = "";
- reset["custom_background_trait_name"] = "";
- reset["custom_background_trait_desc"] = "";
- clearRepeatingSections("background_holder");
- }
-
- if(eventinfo.newValue === "Rules:Backgrounds") {
- //Clears saved data for this field
- getCompendiumPage("");
- setAttrs(reset, function() {
- var update = {"background_text": ""};
- var options = eventinfo.sourceType == "player" ? {selected: ""} : {}
- hideChoices(["standardbg"]);
- showChoices(["custom_background"]);
- setCharmancerText(update);
- addCustomSections("Background");
- });
- } else {
- getCompendiumPage(eventinfo.newValue, function(p) {
- p = removeDuplicatedPageData(p);
- var update = {};
- var showList = ["standardbg"];
- var possibles = ["background_feature"];
- var data = p["data"];
- var hideList = [];
-
- _.each(proficiencyList, function(type){
- possibles.push("background_" + type.toLowerCase() + "s");
- });
- _.each(possibles, function(key) {
- update[key] = "";
- });
- handleBlobs(data.blobs, {filters: {"Level": "1"}, section: "background", slide: "l1-background"});
-
- if (data["data-Background Choices"] && data["data-Background Choices"] != "") {
- showList.push("background_detail_choice_row");
- var choices = JSON.parse(data["data-Background Choices"]);
- showList.push("background_detail_choice");
- setCharmancerOptions("background_detail_choice", choices, {}, function(opts) {
- setRollButton("background_detail_choice", opts, data["data-Background Choice Name"]);
- });
- update["background_detail_choice_name"] = data["data-Background Choice Name"];
- }
- if(eventinfo.sourceType == "player") {
- reset["background_detail_choice"] = "";
- }
-
- if (data["data-Personality Traits"]) {
- showList.push("background_personality_row");
- var choices = JSON.parse(data["data-Personality Traits"]);
- setCharmancerOptions("background_personality_choice1", choices, {}, function(opts) {
- setRollButton("background_personality_choice1", opts);
- });
- setCharmancerOptions("background_personality_choice2", choices, {}, function(opts) {
- setRollButton("background_personality_choice2", opts);
- });
- showList.push("background_personality_choice1");
- showList.push("background_personality_choice2");
- }
- if (data["data-Ideals"]) {
- var choices = JSON.parse(data["data-Ideals"]);
- setCharmancerOptions("background_ideal_choice", choices, {}, function(opts) {
- setRollButton("background_ideal_choice", opts);
- });
- showList.push("background_ideal_choice");
- }
- if (data["data-Bonds"]) {
- var choices = JSON.parse(data["data-Bonds"]);
- setCharmancerOptions("background_bond_choice", choices, {}, function(opts) {
- setRollButton("background_bond_choice", opts);
- });
- showList.push("background_bond_choice");
- }
- if (data["data-Flaws"]) {
- var choices = JSON.parse(data["data-Flaws"]);
- setCharmancerOptions("background_flaw_choice", choices, {}, function(data) {
- setRollButton("background_flaw_choice", data);
- });
- showList.push("background_flaw_choice");
- }
-
- if(eventinfo.sourceType == "player") {
- reset = _.extend(reset, {"background_personality_choice1": "", "background_personality_choice2": "", "background_ideal_choice": "", "background_bond_choice": "", "background_flaw_choice": ""});
- }
-
- if (data["data-Equipment"]) {
- showList.push("background_equipment_row");
- var equipment_string = "";
- var json = JSON.parse(data["data-Equipment"]);
- if(json["default"]) {
- equipment_string += json["default"].join(", ");
- }
- for (var i = 1; i < 5; i++) {
- if(json[i]) {
- if (!json["default"].length && i == 1) {
- equipment_string += "";
- } else {
- equipment_string += " and ";
- }
-
- equipment_string += cleanEquipment(json[i]);
- }
- };
- update["background_standard_equipment"] = equipment_string;
- }
-
- var background_name = eventinfo.newValue && eventinfo.newValue.split(":").length > 1 && eventinfo.newValue.split(":")[0] === "Backgrounds" ? eventinfo.newValue.split(":")[1] : false;
-
- setCharmancerText(update);
- showChoices(showList);
- hideChoices(hideList);
- recalcData();
- setAttrs(reset);
- });
- }
-});
-
-/* ABILITY SCORE */
-on("page:l1-abilities", function(eventinfo) {
- var data = getCharmancerData();
- getCompendiumPage("Rules:Ability%20Scores", function(p) {
- p = removeDuplicatedPageData(p);
- var pagedata = p["data"];
- var allChoices = [];
- if (pagedata["data-Generation Choices"]) {
- var genChoices = JSON.parse(pagedata["data-Generation Choices"]);
- _.each(genChoices, function(value, choice) {
- allChoices.push(choice);
- });
- }
- setCharmancerOptions("abilities", allChoices);
-
-
- if (data["l1-abilities"] && data["l1-abilities"].values && data["l1-abilities"].values.abilities) {
- setAttrs({"abilities": data["l1-abilities"].values.abilities});
- }
- });
-});
-
-on("mancerchange:abilities", function(eventinfo) {
- var data = getCharmancerData();
- var initHide = ["abilities_possible"];
- var attribs = ["strength","dexterity","constitution","intelligence","wisdom","charisma"];
- var standardArray = ["8", "10", "12", "13", "14", "15"];
- var pointbuyChoices = ["8", "9", "10", "11", "12", "13", "14", "15"];
-
- hideChoices(initHide);
-
-
- if (data["l1-abilities"].values.abilities == "Standard Array") {
- showChoices(["abilities_stdarray", "abilities_selects"]);
- _.each(attribs, function(attrib) {
- setCharmancerOptions(attrib, standardArray);
- });
- }
-
- if (data["l1-abilities"].values.abilities == "Roll for Stats") {
- showChoices(["abilities_rollstats"]);
- if (data["l1-abilities"].values.roll_results && data["l1-abilities"].values.roll_results.length) {
- showChoices(["abilities_rollstats_rolled","abilities_selects"]);
- var roll_results = typeof data["l1-abilities"].values.roll_results == "string" ? data["l1-abilities"].values.roll_results.split(",") : data["l1-abilities"].values.roll_results;
- _.each(attribs, function(attrib) {
- setCharmancerOptions(attrib, roll_results);
- });
- }
- }
-
- if (data["l1-abilities"].values.abilities == "Point Buy") {
- showChoices(["abilities_pointbuy", "abilities_selects"]);
- setCharmancerText({"points_available_display":data["l1-abilities"].values.pointbuy_points || "27"});
- _.each(attribs, function(attrib) {
- setCharmancerOptions(attrib, pointbuyChoices);
- });
- }
-
- if (data["l1-abilities"].values.abilities == "custom") {
- showChoices(["abilities_custom"]);
- }
-
- reset = {};
- if (eventinfo.sourceType == "player") {
- _.each(attribs, function(attrib) {
- reset[attrib] = "";
- });
- reset["pointbuy_points"] = "27"
- }
-
-
- recalcData();
- setAttrs(reset);
-});
-
-on("mancerchange:strength mancerchange:dexterity mancerchange:constitution mancerchange:intelligence mancerchange:wisdom mancerchange:charisma", function(eventinfo) {
- data = getCharmancerData();
- var attribs = ["strength","dexterity","constitution","intelligence","wisdom","charisma"];
- var clearvalue = eventinfo.newValue;
- var clearObject = {
- strength: data["l1-abilities"].values.strength,
- dexterity: data["l1-abilities"].values.dexterity,
- constitution: data["l1-abilities"].values.constitution,
- intelligence: data["l1-abilities"].values.intelligence,
- wisdom: data["l1-abilities"].values.wisdom,
- charisma: data["l1-abilities"].values.charisma};
-
- if (data["l1-abilities"].values.abilities != "custom" && data["l1-abilities"].values.abilities != "Point Buy") {
- attribs = _.reject(attribs, function(item) { return item == eventinfo.triggerName; });
- _.each(attribs, function(attrib) {
- if (clearvalue == clearObject[attrib]) {
- clearObject[attrib] = "";
- }
- });
- }
-
- if (data["l1-abilities"].values.abilities == "Point Buy") {
- clearObject.pointbuy_points = recalcPoints();
- }
-
- if (eventinfo.sourceType == "player") {
- setAttrs(clearObject);
- }
- recalcData();
-});
-
-on("mancerroll:rollstats", function(eventinfo) {
- var attribs = ["strength","dexterity","constitution","intelligence","wisdom","charisma"];
- var results = [];
- var i = 1;
- _.each(eventinfo.roll, function(roll) {
- results.push(roll.result + "~" + i);
- i++;
- });
- results.sort(function(a,b) {return Number(a.split("~")[0]) - Number(b.split("~")[0])});
- _.each(attribs, function(attrib) {
- setCharmancerOptions(attrib, results);
- });
- setAttrs({roll_results: results, strength: "", dexterity: "", constitution: "", intelligence: "", wisdom: "", charisma: ""});
- showChoices(["abilities_rollstats_rolled","abilities_selects"]);
-});
-
-on("clicked:clearstats", function(eventinfo) {
- var data = getCharmancerData();
- var attribs = ["strength","dexterity","constitution","intelligence","wisdom","charisma"];
- reset = {};
- _.each(attribs, function(attrib) {
- reset[attrib] = "";
- disableCharmancerOptions(attrib, []);
- });
-
- setAttrs(reset);
-});
-
-/* EQUIPMENT */
-on("page:l1-equipment", function(eventinfo) {
- getAttrs(["licensedsheet"], function(v) {
- var data = getCharmancerData();
- var class_string = getName("class", data, true);
- var background_string = getName("background", data, true);
- var class_equipment = data && data["l1-equipment"] && data["l1-equipment"].values.equipment_class ? data["l1-equipment"].values.equipment_class : undefined;
- var background_equipment = data && data["l1-equipment"] && data["l1-equipment"].values.equipment_background ? data["l1-class"].values.equipment_background : undefined;
- var update = {};
- var update_attr = {};
- var showList = [];
- var hideList = [];
- var allBlobs = getRelevantBlobs(data, "1", "l1");
- var equipmentType = data["l1-equipment"] && data["l1-equipment"].values.equipment_type ? data["l1-equipment"].values.equipment_type : "";
- const licensedsheet = (v.licensedsheet && v.licensedsheet === "1") ? "licensedsheet" : "";
- var handleChoices = function(type) {
- var equipment = {};
- if(data["l1-" + type] && data["l1-" + type].data[type] && data["l1-" + type].data[type]["data-Equipment"]) {
- equipment = data["l1-" + type].data[type]["data-Equipment"];
- };
- if(allBlobs.sorted[type]) {
- _.each(allBlobs.sorted[type], function(blob) {
- if(blob.Equipment) {
- var blobstuff = blob.Equipment;
- try {
- blobstuff = JSON.parse(blob.Equipment);
- } catch (e) {}
- equipment.default = equipment.default ? equipment.default.concat(blobstuff) : blobstuff;
- }
- });
- };
- _.each(equipment, function(feature, num) {
- if(num === "default") {
- update[type + "_equipment"] = feature.join(", ");
- } else {
-
- var dynamic_items = "Category:None";
- var static_items = [];
- var hasDouble = false;
- var doubleOffset = 4;
- var equipmentTitle = cleanEquipment(feature).replace(/^\w/, function(char) { return char.toUpperCase(); }).replace(/(^\(|\)$)/g, "");
- if (equipmentTitle.search("Two of") == 0) {
- equipmentTitle += ")";
- }
- update[type + "_equipment_choice" + num + "_title"] = equipmentTitle;
- _.each(feature, function(f) {
- if(f.indexOf("Subtype:") > -1) {
- dynamic_items = 'Category:Items "Item Rarity":Standard ' + f.split("~")[0];
- } else if (f.indexOf("*Weapon") > -1) {
- dynamic_items = 'Category:Items "Item Rarity":Standard ' + f.split("~")[0];
- } else {
- static_items.push(f);
- }
- if (f.split("~")[1] && f.split("~")[1] == "DBL") {
- hasDouble = true;
- }
- });
- if (hasDouble) {
- showList.push(type + "_equipment_choice" + num + "_double");
- var doubleChoiceNum = parseInt(num) + doubleOffset;
- setCharmancerOptions(type + "_equipment_choice" + doubleChoiceNum, dynamic_items, {add:static_items, category:"Items"});
- } else {
- hideList.push(type + "_equipment_choice" + num + "_double");
- }
- setCharmancerOptions(type + "_equipment_choice" + num, dynamic_items, {add: static_items, category:"Items"});
- showList.push(type + "_equipment_choice" + num);
- }
- });
- };
- recalcData();
-
- if(class_string) {
- showList.push("has_class");
- update["class_label"] = class_string;
- update_attr["equipment_class"] = class_string;
- if(class_equipment && class_equipment != class_string) {
- update["starting_cubil_btn_label"] = "";
- update["class_equipment"] = "";
- update_attr["starting_cubil"] = 0;
- update_attr["equipment_type"] = "";
- equipmentType = "";
- update_attr["class_equipment_choice1"] = "";
- update_attr["class_equipment_choice2"] = "";
- update_attr["class_equipment_choice3"] = "";
- update_attr["class_equipment_choice4"] = "";
- update_attr["class_equipment_choice5"] = "";
- update_attr["class_equipment_choice6"] = "";
- update_attr["class_equipment_choice7"] = "";
- update_attr["class_equipment_choice8"] = "";
- };
-
- if(class_string == "custom") {
- update_attr["equipment_type"] = "cubil";
- hideList.push("equipment_type", "random_cubil_option")
- showList.push("custom_class_cubil", "cubil_option", "eqp_custom_class");
- } else {
- handleChoices("class");
- var startingCubil = data["l1-class"].data.class && data["l1-class"].data.class["Starting Cubil"] ? data["l1-class"].data.class["Starting Cubil"] : false;
- if(startingCubil) {
- update["starting_cubil_btn_label"] = startingCubil;
- update_attr["roll_starting_cubil"] = `@{wtype}&{template:mancerroll} {{title=Starting Cubil}} {{r1=[[${startingCubil.replace("x", "*")}]]}} {{licensedsheet=${licensedsheet}}}`;
- showList.push("random_cubil_option");
- } else {
- update_attr["roll_starting_cubil"] = `@{wtype}&{template:mancerroll} {{title=Starting Cubil}} {{r1=[[0]]}} {{licensedsheet=${licensedsheet}}}`;
- update_attr["equipment_type"] = "class";
- equipmentType = "class";
- hideList.push("equipment_type", "cubil_option");
- showList.push("class_option", "no_cubil_option");
- }
- }
- } else {
- showList.push("no_class");
- };
-
- if(background_string) {
- update["background_label"] = background_string;
- update_attr["equipment_background"] = background_string;
- if(background_string != "custom") {
- handleChoices("background");
- }
- if(data["l1-equipment"] && data["l1-equipment"].values.equipment_type || class_string == "custom") {
- if(data["l1-equipment"] && equipmentType == "class" || class_string == "custom") {
- showList.push("has_background");
- if(background_equipment && background_equipment != background_string) {
- update["background_equipment"] = "";
- update_attr["background_equipment_choice1"] = "";
- update_attr["background_equipment_choice2"] = "";
- update_attr["background_equipment_choice3"] = "";
- update_attr["background_equipment_choice4"] = "";
- };
- }
- if(data["l1-equipment"] && equipmentType == "cubil" && class_string != "custom") {
- showList.push("background_chose_starting_cubil");
- }
- }
- } else {
- showList.push("no_background");
- }
-
- if(equipmentType === "" || equipmentType === undefined) {
- hideList.push("cubil_option", "class_option");
- } else if(equipmentType === "cubil") {
- if(background_string) showList.push("background_cubil_option");
- showList.push("cubil_option");
- hideList.push("class_option");
- } else if(equipmentType === "class") {
- showList.push("class_option");
- hideList.push("cubil_option");
- }
-
- showChoices(showList);
- hideChoices(hideList);
- setCharmancerText(update);
- setAttrs(update_attr);
- });
-});
-
-on("mancerchange:equipment_type", function(eventinfo) {
- var showList = [];
- var hideList = [];
- var update = {};
- var reset = {};
- var data = getCharmancerData();
- var class_string = getName("class", data, true);
- var background_string = getName("background", data, true);
- if(eventinfo.sourceType == "player") {
- if(eventinfo.newValue === "" || eventinfo.newValue === undefined) {
- hideList.push("cubil_option", "class_option", "background_cubil_option");
- } else if(eventinfo.newValue === "cubil") {
- if(background_string) showList.push("background_cubil_option");
- if(class_string != "custom") showList.push("random_cubil_option")
- showList.push("cubil_option");
- hideList.push("class_option");
- } else if(eventinfo.newValue === "class") {
- showList.push("class_option");
- hideList.push("cubil_option", "background_cubil_option");
- }
- }
- showChoices(showList);
- hideChoices(hideList);
-});
-
-on("mancerroll:starting_cubil", function(eventinfo) {
- setAttrs({starting_cubil: eventinfo.roll[0].result});
-});
-
-/* REPEATING SECTION LISTENERS */
-on("mancerchange:repeating_row", function(eventinfo) {
- var mancerdata = getCharmancerData();
- var proficiencies = getProficiencies(mancerdata, eventinfo.currentStep);
- var section = eventinfo.sourceSection.split("_")[2].split("-")[0].replace(/[0-9]+$/gm, "");
- var type = eventinfo.sourceSection.split("_")[3];
- var sourcepage = eventinfo.currentStep;
- if(eventinfo.currentStep.split("-")[0] == "lp") {
- var sectioninfo = eventinfo.sourceSection.split("_")[2].split("--")[0];
- if(sectioninfo.indexOf("-") === -1) {
- let index = sectioninfo.indexOf(section) + section.length;
- sectioninfo = [sectioninfo.slice(0, index), "-", sectioninfo.slice(index)].join('');
- }
- sectioninfo = sectioninfo.split("-");
- if(sectioninfo.length > 1) {
- sourcepage = "lp-levels";
- section = "class" + sectioninfo[1];
- if(sectioninfo[0] == "subclass") section += "_subclass";
- } else {
- sourcepage = "lp-welcome";
- section = "lp-" + sectioninfo[0];
- }
- }
- var pagedata = mancerdata[sourcepage].data[section];
- if(_.last(eventinfo.sourceAttribute.split("_")) == "choice") {
- if(type == "feature") {
- if(eventinfo.previousValue !== eventinfo.newValue){
- clearRepeatingSections(eventinfo.sourceSection + " span");
- if(eventinfo.newValue.split(":")[0] == "Blob") {
- console.log(pagedata.blobs[eventinfo.newValue.split(":")[1]]);
- if(pagedata.blobs[eventinfo.newValue.split(":")[1]]["Pick Powers"] || pagedata.blobs[eventinfo.newValue.split(":")[1]].Powers) {
- deleteCharmancerData(["lp-spells"]);
- }
- handleBlobs(pagedata.blobs, {
- filters: {name: eventinfo.newValue.split(":")[1]},
- section: section,
- element: eventinfo.sourceSection + " span",
- slide: eventinfo.currentStep,
- parent: section
- });
- }
- }
- }
- if(eventinfo.newValue == "custom") {
-
- showChoices(["custom[name=comp_" + eventinfo.sourceSection + "_custom]"]);
- } else {
- var toset = {};
- hideChoices(["custom[name=comp_" + eventinfo.sourceSection + "_custom]"]);
- toset[eventinfo.sourceSection + "_custom"] = "";
- setAttrs(toset);
- }
- }
-});
-
-on("mancerchange:repeating_row", function(eventinfo) {
- if(eventinfo.currentStep !== "lp-choices") return;
- if(eventinfo.sourceAttribute.indexOf("feature_choice") === -1 && eventinfo.sourceAttribute.indexOf("feature_info") === -1) return;
-
- const data = getCharmancerData();
- const traits = JSON.parse(data["lp-welcome"].values.previous_repeating).traits || [];
- const singleSelectionTraits = [
- {group: "Maneuvers", single: "Maneuver" }
- ]; //Types of traits that can be taken only once.
- let traitsAlreadyTaken = [];
-
- //Read the current type of a trait
- const currentTrait = data["lp-choices"].values[eventinfo.sourceAttribute.replace("_choice", "_info")] || "";
- const traitIndex = singleSelectionTraits.map(trait => { return trait.group; }).indexOf(currentTrait);
-
- //Return if the trait is not among the ones set for single selection.
- if(traitIndex === -1) return;
-
- //Get single item type
- const traitType = singleSelectionTraits[traitIndex].single + ": ";
-
- const getRelevantChoices = function(data, choiceType) {
- const choices = data["lp-choices"].values || [];
- let relevantChoices = [];
- for(choice in choices) {
- if(choice.indexOf("_info") === -1) continue;
- if(choices[choice] === choiceType) relevantChoices.push(choice.replace("_info", ""));
- }
- return relevantChoices;
- };
-
- //Reading traits set in previous Levels
- for(trait in traits) {
- if(traits[trait].name.indexOf(traitType) > -1) {
- const selectedTrait = traits[trait].name.replace(traitType, "");
- traitsAlreadyTaken.push("Blob:" + selectedTrait);
- }
- }
-
- //Handling traits choosen at current LP
- const choices = getRelevantChoices(data, singleSelectionTraits[traitIndex].group);
- for(choice in choices) {
- if(choices[choice]+"_choice" in data["lp-choices"].values) {
- traitsAlreadyTaken.push(data["lp-choices"].values[choices[choice]+"_choice"]);
- }
- }
-
- //Disable elements
- for(choice in choices) {
- //Enables all options
- disableCharmancerOptions(choices[choice]+"_choice", "");
- //Disable maneuvers arealdy selected at lv1 or during current LP
- disableCharmancerOptions(choices[choice]+"_choice", traitsAlreadyTaken);
- }
-});
-
-on("mancerchange:repeating_spellrow", function(eventinfo) {
- if(eventinfo.sourceType == "player") {
- changeCompendiumPage("sheet-spells-info", eventinfo.newValue, "card_only");
- }
- var mancerdata = getCharmancerData();
- var known = knownPowers().known;
- _.each(mancerdata["l1-spells"].repeating, function(id) {
- disableCharmancerOptions(id + "_choice", known, {category: "Powers"});
- });
-});
-
-//D&D 5e: Charactermancer Lvl+ Druid, Circle of Land feedback improvement (UC811)
-//Land druids used to be able to change multiple lands once they levelup. This goes against the rules. This is a fix for that issue.
-//By Miguel
-on("mancerchange:repeating_row", function(eventinfo) {
- const featureName = "Circle Powers";
- const feedback = "You must choose your Circle Land at 3rd level";
-
- const data = getCharmancerData();
- //First we detect if this is circle spell, otherwise return.
- if(eventinfo.currentStep !== "lp-choices") return;
- if(eventinfo.sourceAttribute.indexOf("feature_choice") === -1 && eventinfo.sourceAttribute.indexOf("feature_info") === -1) return;
- if(!eventinfo.sourceSection+"_info" in data["lp-choices"].values || !data["lp-choices"].values[eventinfo.sourceSection+"_info"] === featureName) return;
-
- const previousRepeating = JSON.parse(data["lp-welcome"].values.previous_repeating);
- const previousTraits = previousRepeating.traits;
- const initialCircleTrait = previousTraits.findIndex(item => item.name.indexOf(featureName+": ") > -1);
-
- //A land was had not been selected yet when Mancer was started (Ex: Levelling from LV 1st to 5th)
- if(!(/repeating_-.+_subclass-.+--[^3]+_feature/g).test(eventinfo.sourceSection)) {
- const choices = data["lp-choices"].values;
- for(choice in choices) {
- if(choices[choice] === featureName) {
- //Set all non 3rd level pickers to the choose value
- if((/repeating_-.+_subclass-.+--[^3]+_feature/g).test(choice) && choice.indexOf("_info") > -1 && choices[choice] === featureName) {
- const pickerClass = choice.replace("_info", "_choice");
- const currentValue = eventinfo.newValue.replace("Blob:", "");
- const initialLand = currentValue.replace(featureName, "").trim();
- const choiceLevel = choice.match(/--./)[0].replace("--", "");
- const choiceValue = initialLand + " " + featureName + "(" + choiceLevel + ")";
- if((eventinfo.newValue === "" || eventinfo.newValue === featureName) && eventinfo.previousValue !== feedback) {
- setCharmancerOptions(pickerClass, [feedback], { selected: feedback }, function() {
- disableCharmancerOptions(pickerClass, [""]);
- });
- } else {
- setCharmancerOptions(pickerClass, [choiceValue], { category: "Blob", selected: "Blob:"+choiceValue }, function() {
- disableCharmancerOptions(pickerClass, [""]);
- });
- }
- }
- }
- }
- return;
- }
- //A land was already selected when Mancer was started (Ex: Levelling from LV 3rd to 5th)
- else if(initialCircleTrait > -1) {
- const initialLand = previousTraits[initialCircleTrait].name.replace(featureName+": ", "");
- const choiceLevel = eventinfo.sourceSection.match(/--./)[0].replace("--", "");
- const choiceValue = initialLand + " " + featureName + "(" + choiceLevel + ")";
- const choiceClass = eventinfo.sourceSection+"_choice";
- setCharmancerOptions(choiceClass, [choiceValue], { category: "Blob", selected: "Blob:"+choiceValue }, function() {
- disableCharmancerOptions(choiceClass, [""]);
- });
- }
-});
-
-on("clicked:repeating_spellrow", function(eventinfo) {
- var spell_name = "";
- var data = getCharmancerData();
- var card = "card_only";
- if(_.last(eventinfo.sourceSection.split("_")) == "spellrow") {
- spell_name = data["l1-spells"].values[eventinfo.sourceAttribute];
- } else {
- spell_name = data["l1-spells"].values[eventinfo.sourceSection + "_choice"] ? data["l1-spells"].values[eventinfo.sourceSection + "_choice"] : "Rules:Powers";
- card = data["l1-spells"].values[eventinfo.sourceSection + "_choice"] ? card : "";
- }
- changeCompendiumPage("sheet-spells-info", spell_name, card);
-});
-
-on("mancerchange:repeating_customrow", function(eventinfo) {
- var mancerdata = getCharmancerData();
- var profdata = getProficiencies(mancerdata, eventinfo.currentStep);
- if(eventinfo.sourceAttribute.substr(-10) == "trait_name") {
- var update = {};
- update[eventinfo.sourceSection + " span"] = eventinfo.newValue;
- setCharmancerText(update);
- }
- if(_.last(eventinfo.sourceSection.split("_")) == "proficiency") {
- if(_.last(eventinfo.sourceAttribute.split("_")) == "type") {
- var update = {};
- var prof = eventinfo.newValue;
- var choices = prof == "" ? [] : "Category:Proficiencies \"Type:" + prof + "\"";
- var settings = {category: "Proficiencies", disable: profdata.all[prof]};
- update[eventinfo.sourceSection + " span + select"] = '
';
- if(prof == "Language") update[eventinfo.sourceSection + " span + select"] += '
';
- update[eventinfo.sourceSection + " span"] = eventinfo.newValue;
- setCharmancerText(update);
- if(prof == "") {
- var toset = {};
- toset[eventinfo.sourceSection + "_choice"] = "";
- toset[eventinfo.sourceSection + "_custom"] = "";
- setAttrs(toset);
- hideChoices(["custom[name=comp_" + eventinfo.sourceSection + "_custom]"]);
- } else {
- setCharmancerOptions(eventinfo.sourceSection + "_choice", choices, settings);
- }
- } else if(_.last(eventinfo.sourceAttribute.split("_")) == "choice") {
- if(eventinfo.newValue == "custom") {
- showChoices(["custom[name=comp_" + eventinfo.sourceSection + "_custom]"]);
- } else {
- var toset = {};
- hideChoices(["custom[name=comp_" + eventinfo.sourceSection + "_custom]"]);
- toset[eventinfo.sourceSection + "_custom"] = "";
- setAttrs(toset);
- }
- }
- }
-});
-
-on("clicked:repeating_customrow", function(eventinfo) {
- var mancerdata = getCharmancerData();
- getRepeatingSections(function(repeating) {
- var target = "";
- var section = eventinfo.sourceSection.split("_")[3]
- var type = _.last(eventinfo.sourceSection.split("_"));
- _.each(repeating.tree, function(branch, parentid) {
- _.each(branch, function(child, childid) {
- if(childid == eventinfo.sourceSection) target = parentid;
- });
- });
- addRepeatingSection(target, "custom-" + type, "custom_" + section + "_" + type);
- });
-});
-
-on(customListeners, function(eventinfo) {
- var mancerdata = getCharmancerData();
- var num = parseInt(eventinfo.triggerName.substr(-1));
- var base = eventinfo.triggerName.slice(0, -1);
- var section = eventinfo.triggerName.split("_")[0].replace("sub", "");
- if(mancerdata["l1-" + section].values[base.split("_")[0]]
- && ["Rules", "CategoryIndex"].indexOf(mancerdata["l1-" + section].values[base.split("_")[0]].split(":")[0]) != -1
- && eventinfo.newValue) {
- showChoices([base + (num+1)]);
- }
-});
-
-on(changeListeners, function(eventinfo) {
- recalcData();
-});
-
-on("mancerchange:custom_race_spell_ability mancerchange:custom_class_spell_ability", function(eventinfo) {
- var section = eventinfo.triggerName.split("_")[1];
- if(eventinfo.newValue) {
- showChoices(["custom_spellcasting"]);
- } else {
- var set = {}
- set["custom_" + section + "_spell_number"] = "1";
- set["custom_" + section + "_prime_number"] = "1";
- set["custom_" + section + "_spell_list"] = "";
- setAttrs(set);
- hideChoices(["custom_spellcasting"]);
- }
-});
-
-on("page:l1-welcome page:l1-class page:l1-race page:l1-abilities page:l1-background page:l1-equipment page:l1-spells page:l1-feat page:l1-bio page:l1-summary", function(eventinfo) {
- var mancerdata = getCharmancerData();
- var buttons = "";
- var buttoninfo = {
- welcome: "charmancer-start",
- race: "race-u",
- class: "class-u",
- abilities: "abilities-u",
- background: "background-u",
- equipment: "equipment-u",
- spells: "spells-u",
- feat: "feats-u",
- bio: "bio-u",
- gear: "gear-u",
- summary: "review-u"
- }
- _.each(buttoninfo, function(translation, page) {
- var here = "l1-" + page == eventinfo.triggerName;
- buttons += "
";
- });
- buttons += "
CANCEL ";
- setCharmancerText({steps: buttons});
- if(eventinfo.triggerName != "l1-welcome") {
- addRepeatingSection("topbar-holder", "topbar");
- recalcData();
- getProficiencies(mancerdata, eventinfo.currentStep);
- }
- getAttrs(["licensedsheet"], function(v) {
- if("licensedsheet" in v && v.licensedsheet === "1") {
- setCharmancerText({"sheet-licensedsheet-flag":"true"});
- }
- });
-});
-
-on("mancerchange:class_feature_choice_1 mancerchange:class_feature_choice_2", function(eventinfo) {
- var data = getCharmancerData();
- var featureNum = _.last( eventinfo.triggerName.split("_") );
- var update = {};
- var set = {};
- set["class_feature_choice_" + featureNum + "_desc"] = "";
- if(eventinfo.newValue) {
- getCompendiumPage(data["l1-class"].values.class, function(p) {
- p = removeDuplicatedPageData(p);
- var data = p["data"];
- if(data["data-Feature Choices"]) {
- var feature = JSON.parse(data["data-Feature Choices"])[featureNum-1];
- var featureName = feature.Name;
- var offset = 3;
-
- if (eventinfo.newValue.split("~")[1] && eventinfo.newValue.split("~")[1] == "DBL") {
- showChoices(["class_feature_row_" + featureNum + "_manual"]);
- // var doubleChoiceNum = featureNum + offset;
- // setCharmancerOptions("class_feature_choice_" + doubleChoiceNum, [eventinfo.newValue]);
- } else {
- hideChoices(["class_feature_row_" + featureNum + "_manual"]);
- }
- if(data["data-" + featureName + " Data"]) {
- var json = JSON.parse(data["data-" + featureName + " Data"]);
- var selected = _.findWhere(json, {Name: eventinfo.newValue});
- if(selected) {
- update["class_feature_description_" + featureNum] = selected.Desc;
- set["class_feature_choice_" + featureNum + "_desc"] = selected.Desc;
- setAttrs(set);
- setCharmancerText(update);
- }
- }
- }
- });
- } else {
- update["class_feature_description_" + featureNum] = "";
- setAttrs(set);
- setCharmancerText(update);
- }
-});
-
-on("mancerchange:custom_subclass_prime_number mancerchange:custom_subclass_spell_number", function(eventinfo) {
- var section = eventinfo.triggerName.split("_")[2];
- if(eventinfo.newValue && eventinfo.newValue > 0) {
- showChoices(["custom_" + section + "_list"]);
- } else {
- var reset = {};
- reset["custom_subclass_" + section + "_list"] = "";
- hideChoices(["custom_" + section + "_list"]);
- setAttrs(reset);
- }
-});
-
-on("mancerchange:background_personality_choice1 mancerchange:background_personality_choice2", function(eventinfo) {
- var mancerdata = getCharmancerData();
- var choices = [];
- if(mancerdata["l1-background"].values["background_personality_choice1"]) choices.push(mancerdata["l1-background"].values["background_personality_choice1"]);
- if(mancerdata["l1-background"].values["background_personality_choice2"]) choices.push(mancerdata["l1-background"].values["background_personality_choice2"]);
- disableCharmancerOptions("background_personality_choice1", choices);
- disableCharmancerOptions("background_personality_choice2", choices);
-});
-
-on("mancerroll:background_detail_choice_roll mancerroll:background_personality_choice1_roll mancerroll:background_personality_choice2_roll mancerroll:background_ideal_choice_roll mancerroll:background_bond_choice_roll mancerroll:background_flaw_choice_roll", function(eventinfo) {
- var data = getCharmancerData();
- var index = eventinfo.roll[0].dice[0] - 1;
- var baseName = eventinfo.triggerName.split(":")[1].slice(0,-5);
- var choices = JSON.parse(data["l1-background"].values[baseName + "_array"]);
- setCharmancerOptions(baseName, choices.array, {selected: choices.array[index]});
- if(baseName.slice(0, -1) == "background_personality_choice") {
- var num = baseName.substr(-1) == "1" ? "2" : "1";
- setRollButton(baseName.slice(0, -1) + num, choices.array, choices.name, index + 1);
- }
-});
-
-on("clicked:cancel", function() {
- showChoices(["cancel-prompt"]);
- var data = getCharmancerData();
- console.log(data);
- //console.log(recalcData(data));
- //console.log(getProficiencies(data, "finish"));
- //console.log(getRelevantBlobs(data, "1", "l1"));
-});
-
-on("clicked:continue", function() {
- hideChoices(["cancel-prompt"]);
-});
-
-on("page:l1-spells", function(eventinfo) {
- var stats = recalcData();
- var mancerdata = getCharmancerData();
- var spellData = knownPowers();
- var set = {};
- var titles = {};
- var sorted = {};
- var repids = [];
- var totalchoices = 0;
- var racename = getName("race", mancerdata, true);
- var subracename = getName("subrace", mancerdata, true);
- var classname = getName("class", mancerdata, true);
- var subclassname = getName("subclass", mancerdata, true);
- set["race_spells"] = racename + subracename;
- set["class_spells"] = classname + subclassname;
- set["race_number"] = spellData.race ? spellData.race.choices.length : 0;
- set["class_number"] = spellData.class ? spellData.class.choices.length : 0;
-
- subracename = getName("subrace", mancerdata) == "" ? "" : " - " + getName("subrace", mancerdata);
- subclassname = getName("subclass", mancerdata) == "" ? "" : " - " + getName("subclass", mancerdata);
- setAttrs(set, function() {
- spellData = knownPowers();
- titles["race"] = getName("race", mancerdata) + subracename;
- titles["class"] = getName("class", mancerdata) + subclassname;
-
- _.each(["race", "class"], function(section) {
- if(spellData[section]) {
- _.each(spellData[section].known, function(spell) {
- sorted[spell.Level] = sorted[spell.Level] ? sorted[spell.Level] : {};
- sorted[spell.Level][section] = sorted[spell.Level][section] ? sorted[spell.Level][section] : {known: [], choices: []};
- sorted[spell.Level][section].known.push(spell.Name);
- });
- _.each(spellData[section].choices, function(spell) {
- sorted[spell.Level] = sorted[spell.Level] ? sorted[spell.Level] : {};
- sorted[spell.Level][section] = sorted[spell.Level][section] ? sorted[spell.Level][section] : {known: [], choices: []};
- sorted[spell.Level][section].choices.push(spell);
- });
- }
- });
- //This is just to get the total number of repeating sections we need. when we've added enough, erase the rest
- _.each(sorted, function(spellarray, level) {
- _.each(spellarray, function(spells, section) {
- totalchoices++;
- _.each(spells.choices, function(spell) {
- totalchoices++;
- });
- });
- });
- _.each(sorted, function(spellarray, level) {
- _.each(spellarray, function(spells, section) {
- addRepeatingSection("spell_holder", "row", "spellrow", function(rowid) {
- var repupdate = {};
- var knownspells = [];
- var toset = {};
- repupdate[rowid + " label span"] = level == 0 ? titles[section] + " Primes" : titles[section] + " Level " + level;
- _.each(spells.known, function(spell, index) {
- var thisSpell = spell;
- thisSpell += "
i ";
- thisSpell += "
";
- toset[rowid + "_known" + index] = "Powers:" + spell;
- knownspells.push(thisSpell);
- });
- repupdate[rowid + " label p"] = knownspells.join(", ");
- setAttrs(toset);
- setCharmancerText(repupdate);
- repids.push(rowid);
- _.each(spells.choices, function(spell) {
- addRepeatingSection(rowid, "choose", section + "_spell-l" + spell.Level, function(id) {
- var toset = {};
- var lists = [spell.List];
- if(spell.AddList) lists = lists.concat(spell.AddList);
- var choices = "Category:Powers Classes:*" + lists.join("|*") + " Level:" + spell.Level;
- var settings = {category: "Powers", disable: spellData.known, add: spell["Expanded List"]};
- toset[id + "_info"] = spell.Ability;
- if(section != "class") toset[id + "_custom"] = section;
- repids.push(id);
- setCharmancerOptions(id + "_choice", choices, settings);
- setAttrs(toset);
- showChoices(["action[name=act_" + id + "_action]"]);
- if(repids.length >= totalchoices) {
- clearRepeating(repids, "l1-spells");
- }
- });
- });
- });
- })
- });
-
- if (!spellData.race && !spellData.class) {
- showChoices(["no_spells"]);
- clearRepeatingSections("spell_holder");
- } else {
- showChoices(["spell-info-container"]);
- hideChoices(["no_spells"]);
- }
-
- setAttrs(set);
- });
-});
-
-on("page:l1-feat", function(eventinfo) {
- var stats = recalcData();
- var mancerdata = getCharmancerData();
- var showList = [];
- var hideList = [];
-
- if(mancerdata["l1-race"] && mancerdata["l1-race"].data.subrace && mancerdata["l1-race"].data.subrace["data-Feats"]) {
- showList = ["yes_feat"];
- hideList = ["no_feat"];
- } else {
- hideList = ["yes_feat"];
- showList = ["no_feat"];
- deleteCharmancerData(["l1-feat"]);
- }
-
- showChoices(showList);
- hideChoices(hideList);
-});
-
-on("mancerchange:feat", function(eventinfo) {
- changeCompendiumPage("sheet-feat-info", eventinfo.newValue);
-
- var reset = {};
- if(!(eventinfo.newValue === "" || eventinfo.newValue === undefined)) {
- showChoices(["feat_options"]);
- }
- hideChoices(["feat_possible"]);
-
- if(eventinfo.sourceType == "player") {
- reset = {};
- for(var x=1; x<=proficiencyNum; x++) {
- //reset["custom_race_prof_name_choice" + x] = "";
- //reset["custom_race_prof_type_choice" + x] = "";
- }
- reset["feat_ability_choice"] = "";
- setCharmancerText({"feat_text": ""});
- }
-
- getCompendiumPage(eventinfo.newValue, function(p) {
- p = removeDuplicatedPageData(p);
- setAttrs(reset, function() {
- var mancerdata = getCharmancerData();
- var data = p["data"];
- var showList = [];
- var update = {};
-
- if(data["data-Ability Score Increase"]) {
- var abilityText = [];
- var json = JSON.parse(data["data-Ability Score Increase"]);
- _.each(json, function(increase, ability) {
- abilityText.push(ability + " +" + increase);
- });
- update["feat_ability_score"] = abilityText.join(", ");
- showList.push("feat_ability");
- }
-
- if(data["data-Ability Score Choice"]) {
- var json = JSON.parse(data["data-Ability Score Choice"]);
- setCharmancerOptions("feat_ability_choice", json);
- showList.push("feat_ability", "feat_ability_choice");
- }
-
- if(data["Prerequisite"]) {
- showList.push("feat_prereq")
- update["feat_prerequisite"] = data["Prerequisite"];
- }
- //feat_ability_choice
-
- setCharmancerText(update);
- showChoices(showList);
- recalcData();
- });
- });
-});
-
-/* BIO PAGE */
-on("page:l1-bio", function(eventinfo) {
- const attrs = ["age", "character_name", "eyes", "hair", "height", "weight", "skin"];
- const mancerdata = getCharmancerData();
- const biodata = mancerdata["l1-bio"] || undefined;
- const race = getName("race");
-
- //Check for any data that has already been filled in and populate the Bio slide
- if (biodata === undefined) {
- getAttrs(attrs, function(v) {
- let update = {};
-
- _.each(attrs, function(value) {
- if (v[`${value}`] != "" || v[`${value}`] != undefined) {
- update[`${value}`] = v[`${value}`];
- };
- });
-
- setAttrs(update);
- });
- };
-
- //Set the previous_race so the Summary page can offer a warning if needed
- if (biodata === undefined || biodata.values["previous_race"] === undefined || biodata.values["previous_race"] != race) {
-
- setAttrs({
- previous_race: race
- });
- };
-
- if (mancerdata["l1-race"] != undefined) {
- const raceInfo = mancerdata["l1-race"].values.race;
- changeCompendiumPage("sheet-race-info", raceInfo);
- };
-});
-
-/* SUMMARY PAGE */
-on("page:l1-summary", function() {
- var mancerdata = getCharmancerData();
- var profdata = getProficiencies(mancerdata);
- var set = {};
- var racename = getName("race", mancerdata);
- var subracename = getName("subrace", mancerdata);
- var classname = getName("class", mancerdata);
- var subclassname = getName("subclass", mancerdata);
- var bgname = getName("background", mancerdata);
- var spelldata = knownPowers();
- var racePowers = spelldata.race ? spelldata.race.choices.length : 0;
- var classPowers = spelldata.class ? spelldata.class.choices.length : 0;
- var ready = true;
-
- var handleMissing = function(section, sectionName) {
- var page = mancerdata["l1-" + section.replace("sub", "")] || false;
- var missing = {};
- var warnings = "";
- sectionName = sectionName || section;
- if(page && page.data && page.data[section]) {
- if(page.data[section]["data-Ability Score Choice"]) {
- var choices = 1;
- if(typeof page.data[section]["data-Ability Score Choice"] == "string") {
- choices = parseInt( page.data[section]["data-Ability Score Choice"].split("+")[0] );
- }
- var total = choices;
- if(choices >= 2 && page.values[section + "_ability_choice2"]) choices--;
- if(page.values[section + "_ability_choice"]) choices--;
- if(page.values[section + "_ability_choice1"]) choices--;
- if(choices > 0) missing.ability = [total, choices];
- }
- _.each(page.repeating, function(id) {
- if(id.split("_")[2] == section && id.split("_")[3] == "feature") {
- var featurename = page.values[id + "_info"];
- if(page.values[id + "_choice"]) {
- warnings += '
Your ' + featurename + ' is ' + _.last(page.values[id + "_choice"].split(":")) + '.
'
- } else {
- warnings += '
Your have not chosen a ' + featurename + '.
';
- };
- }
- });
- _.each(proficiencyList, function(prof) {
- var numChoices = 0;
- var totalChoices = 0;
- _.each(page.repeating, function(id) {
- if(id.split("_")[2] == section && id.split("_")[3] == prof.toLowerCase()) {
- totalChoices++;
- numChoices++;
- if(page.values[id + "_choice"]) {
- numChoices--;
- var thischoice = _.last(page.values[id + "_choice"].split(":"));
- if(thischoice == "custom" && !page.values[id + "_choice"]) {
- warnings += '
You\'ve chosen a custom language, but you haven\'t entered a custom language name.
';
- }
- _.each(profdata.auto, function(profs, source) {
- if(profs.includes(thischoice)) {
- warnings += '
You\'ve chosen the ' + prof.toLowerCase() + ' ' + thischoice;
- warnings += ', but you already have that ' + prof.toLowerCase() + ' from your ' + source + '.
';
- };
- });
- }
- }
- });
- if(numChoices > 0) missing[prof] = [totalChoices, numChoices];
- });
- var total = 0;
- var choices = 0;
- _.each(page.repeating, function(id) {
- if(id.split("_")[2] == section && id.split("_")[3] == "expertise") {
- total++;
- choices++;
- if(page.values[id + "_choice"]) choices--;
- if(choices > 0) missing.expertise = [total, choices];
- }
- });
- }
- _.each(missing, function(number, type) {
- var singular = type == "ability" ? "an" : "a"
- if(type == "ability") {
- type = 'ability score increase'
- }
- warnings += '
Your ' + sectionName;
- if(type == "expertise") {
- warnings += " gives you expertise in ";
- warnings += number[0] > 1 ? 'up to ' + number[0] + ' skills' : " a skill";
- } else {
- warnings += " allows you to choose ";
- warnings += number[0] > 1 ? "up to " + number[0] + ' ' + type.toLowerCase() + 's' : singular + " " + type.toLowerCase();
- }
- if(number[0] - number[1] > 0) {
- warnings += ', but you\'ve only chosen ' + number[1] + '!
';
- } else {
- warnings += number[0] > 1 ? ', and you haven\'t chosen any!' : ', and you haven\'t chosen one!';
- }
- });
- return warnings;
- };
-
- ///Show the bio info we need to put in places
- if(mancerdata["l1-bio"]) {
- let length = Object.keys(mancerdata["l1-bio"].values).length;
- set["bio_info"] = "";
-
- //Check if race has changed since entering data and add a warning
- if(length < 2) {
- set["bio_info"] += '
You have not added new information to the Bio tab.
';
- } else {
- if(mancerdata["l1-bio"].values.character_name) {
- set["bio_info"] += '
Your name is ' + mancerdata["l1-bio"].values.character_name + '.
';};
-
- if(mancerdata["l1-bio"].values.age) {
- set["bio_info"] += '
Your age is ' + mancerdata["l1-bio"].values.age + '.
';};
-
- if(mancerdata["l1-bio"].values["height"]) {
- set["bio_info"] += '
Your height is ' + mancerdata["l1-bio"].values["height"] + '.
';};
-
- if(mancerdata["l1-bio"].values.weight) {
- set["bio_info"] += '
Your weight is ' + mancerdata["l1-bio"].values.weight + '.
';};
-
- if(mancerdata["l1-bio"].values.eyes) {
- set["bio_info"] += '
Your eye color is ' + mancerdata["l1-bio"].values.eyes + '.
';};
-
- if(mancerdata["l1-bio"].values.hair) {
- set["bio_info"] += '
Your hair is ' + mancerdata["l1-bio"].values.hair + '.
';};
-
- if(mancerdata["l1-bio"].values.skin) {
- set["bio_info"] += '
Your skin is ' + mancerdata["l1-bio"].values.skin + '.
';};
-
- if (mancerdata["l1-bio"].values.previous_race != racename) {
- setCharmancerText({
- race_warning: '
Each race has unique look and different names. You might want to adjust your choices to reflect your race.
'
- });
- };
- };
- };
-
- if(mancerdata["l1-race"] && racename) {
- set["race_info"] = '
Your race is ' + racename + '
';
- if(!mancerdata["l1-race"].values.alignment) set["race_info"] += '
You haven\'t chosen your alignment.
';
- set["race_info"] += handleMissing("race");
- if(mancerdata["l1-race"].values["has_subrace"] == "true") {
- if(subracename) {
- set["race_info"] += '
Your subrace is ' + subracename + '
';
- set["race_info"] += handleMissing("subrace");
- } else {
- if(mancerdata["l1-race"].values.subrace == "Rules:Races" && !mancerdata["l1-race"].values.subrace_name) {
- set["race_info"] = '
You need to pick a name for your custom subrace!
';
- } else {
- set["race_info"] += '
You have not selected a subrace!
';
- }
- ready = false;
- showChoices(["race_button"]);
- }
- }
- _.each(spelldata.errors.race, function(error) {
- switch(error) {
- case "custom_race_spell_list":
- set["race_info"] += '
You have not selected spell list for your innate spellcasting!
';
- ready = false;
- break;
- default:
- console.log("Unknown race spell error: " + error);
- }
- });
- if(mancerdata["l1-race"].values.race == "Rules:Races") {
- if(!mancerdata["l1-race"].values.size) set["race_info"] += '
You have not selected a size for your custom race!
';
- if(!mancerdata["l1-race"].values.speed) set["race_info"] += '
You have not selected a walking speed for your custom race!
';
- }
- } else {
- if(mancerdata["l1-race"] && mancerdata["l1-race"].values.race == "Rules:Races" && !mancerdata["l1-race"].values.race_name) {
- set["race_info"] = '
You need to pick a name for your custom race!
';
- } else {
- set["race_info"] = '
You have not selected a race!
';
- }
- ready = false;
- showChoices(["race_button"]);
- }
-
- if(mancerdata["l1-class"] && classname) {
- set["class_info"] = '
Your class is ' + classname + '.
';
- set["class_info"] += handleMissing("class");
- if(mancerdata["l1-class"].values.race == "Rules:Classes" && !mancerdata["l1-class"].values.custom_hit_die) {
- set["class_info"] = '
You need to pick a hit die for your custom class!
';
- }
- if(mancerdata["l1-class"].data.class && mancerdata["l1-class"].data.class["data-Subclass Level"] == 1) {
- if(subclassname && mancerdata["l1-class"].data.class && mancerdata["l1-class"].data.class["data-Subclass Level"] == 1) {
- set["class_info"] += '
Your ' + mancerdata["l1-class"].data.class["Subclass Name"] + ' is ' + subclassname + '.
';
- set["class_info"] += handleMissing("subclass", mancerdata["l1-class"].data.class["Subclass Name"]);
- } else {
- if(mancerdata["l1-class"].values.subclass == "Rules:Classes" && !mancerdata["l1-class"].values.subrace_name) {
- set["class_info"] = '
You need to pick a name for your custom ' + mancerdata["l1-class"].data.class["Subclass Name"] + '!
';
- } else {
- set["class_info"] += '
You have not selected a ' + mancerdata["l1-class"].data.class["Subclass Name"] + '!
';
- }
- ready = false;
- showChoices(["class_button"]);
- }
- }
- _.each(spelldata.errors.class, function(error) {
- switch(error) {
- case "custom_class_spell_list":
- set["race_info"] += '
You have selected a spellcasting ability for your custom class, but you have not selected a spell list.
';
- ready = false;
- showChoices(["class_button"]);
- break;
- case "custom_class_spell_number":
- set["race_info"] += '
You have selected a spellcasting ability for your custom class, but you have not selected a number of spells.
';
- ready = false;
- showChoices(["class_button"]);
- break;
- default:
- console.log("Unknown class spell error: " + error);
- }
- });
- } else {
- if(mancerdata["l1-class"] && mancerdata["l1-class"].values.race == "Rules:Classes" && !mancerdata["l1-class"].values.race_name) {
- set["class_info"] = '
You need to pick a name for your custom class!
';
- } else {
- set["class_info"] = '
You have not selected a class!
';
- }
- ready = false;
- showChoices(["class_button"]);
- }
-
- if(mancerdata["l1-abilities"] && mancerdata["l1-abilities"].values.abilities) {
- switch(mancerdata["l1-abilities"].values.abilities) {
- case "Standard Array":
- set["ability_info"] = '
You generated your stats from the standard array.
';
- break;
- case "Roll for Stats":
- set["ability_info"] = '
You generated your stats by rolling.
';
- break;
- case "Point Buy":
- set["ability_info"] = '
You generated your stats with the point buy method.
';
- break;
- case "custom":
- set["ability_info"] = '
You entered custom values for your stats.
';
- break;
- }
- var x = 0;
- _.each(abilityList, function(ability) {
- if(!mancerdata["l1-abilities"].values[ability.toLowerCase()]) {
- x++;
- set["ability_info"] += '
You have not selected a score for your ' + ability.toLowerCase() + '!
';
- ready = false;
- showChoices(["abilities_button"]);
- }
- });
- if(x == 6) set["ability_info"] = '
You have not selected your ability scores!
';
- } else {
- set["ability_info"] = '
You have not generated your ability scores!
';
- ready = false;
- showChoices(["abilities_button"]);
- }
-
- if(mancerdata["l1-background"] && bgname) {
- set["background_info"] = '
You come from a ' + bgname + ' background.
';
- if(mancerdata["l1-background"].data.background && mancerdata["l1-background"].data.background["data-Background Choice Name"]) {
- if(!mancerdata["l1-background"].values["background_detail_choice"]) {
- set["background_info"] += '
You haven\'t chosen your ';
- set["background_info"] += mancerdata["l1-background"].data.background["data-Background Choice Name"] +'.
';
- }
- }
- if(!mancerdata["l1-background"].values["background_personality_choice1"] && !mancerdata["l1-background"].values["background_personality_choice2"]) {
- set["background_info"] += '
You haven\'t picked your personality traits.
';
- } else if(!mancerdata["l1-background"].values["background_personality_choice1"] || !mancerdata["l1-background"].values["background_personality_choice2"]) {
- set["background_info"] += '
You haven\'t picked one of your personality traits.
';
- }
- if(!mancerdata["l1-background"].values["background_ideal_choice"]) {
- set["background_info"] += '
You haven\'t chosen your ideal.
';
- }
- if(!mancerdata["l1-background"].values["background_bond_choice"]) {
- set["background_info"] += '
You haven\'t chosen your bond.
';
- }
- if(!mancerdata["l1-background"].values["background_flaw_choice"]) {
- set["background_info"] += '
You haven\'t chosen your flaw.
';
- }
- set["background_info"] += handleMissing("background");
- } else {
- set["background_info"] = '
You have not selected a background!
';
- ready = false;
- showChoices(["background_button"]);
- }
-
- if(mancerdata["l1-equipment"] && mancerdata["l1-equipment"].values["equipment_type"]) {
- switch(mancerdata["l1-equipment"].values["equipment_type"]) {
- case "class":
- set["equipment_info"] = '
You got starting equipment based on your class and background.
';
- break;
- case "cubil":
- set["equipment_info"] = '
You opted for cubil instead of starting equipment.
';
- break;
- }
- if(mancerdata["l1-equipment"].values["equipment_type"] == "class") {
- var choices = {"class": [0,0], "background": [0,0]};
- _.each(choices, function(numbers, section) {
- var equipment = mancerdata["l1-" + section].data[section] && mancerdata["l1-" + section].data[section]["data-Equipment"] ? mancerdata["l1-" + section].data[section]["data-Equipment"] : {};
- _.each(equipment, function(choice, choicekey) {
- if(choicekey != "default") numbers[0]++;
- });
- _.each(mancerdata["l1-equipment"].values, function(val, key) {
- if(key.includes(section + "_equipment_choice")) numbers[1]++;
- });
- });
- _.each(choices, function(number, type) {
- if(number[0] - number[1] > 0) {
- set["equipment_info"] += '
Your ' + type + ' gives you ';
- set["equipment_info"] += number[0] > 1 ? number[0] + " equipment choices" : "an equipment choice";
- if(number[1] > 0) {
- set["equipment_info"] += ', but you\'ve only chosen ' + number[1] + '!
';
- } else {
- set["equipment_info"] += number[0] > 1 ? ', and you haven\'t chosen any!' : ', and you haven\'t chosen it!';
- }
- }
- });
- }
- if(mancerdata["l1-equipment"].values["equipment_type"] == "cubil" && mancerdata["l1-equipment"].values["starting_cubil"] == "0") {
- set["equipment_info"] = '
You selected starting wealth for your equipment, but you don\'t have any cubil yet!
';
- }
- if(mancerdata["l1-equipment"].values["equipment_class"] != getName("class", mancerdata, true) || (mancerdata["l1-equipment"].values["equipment_background"] != getName("background", mancerdata, true) && mancerdata["l1-equipment"].values["equipment_type"] != "cubil")) {
- set["equipment_info"] = '
Your equipment options have changed, you\'ll need to choose again.
';
- ready = false;
- showChoices(["equipment_button"]);
- }
- } else {
- set["equipment_info"] = '
You have not selected any equipment!
';
- ready = false;
- showChoices(["equipment_button"]);
- }
-
- var spellsready = true;
- var toDelete = [];
- if(mancerdata["l1-spells"]) {
- prevRace = mancerdata["l1-spells"].values.race_spells || "";
- prevClass = mancerdata["l1-spells"].values.class_spells || "";
- currentRace = getName("race", mancerdata, true) + getName("subrace", mancerdata, true);
- currentClass = getName("class", mancerdata, true) + getName("subclass", mancerdata, true);
- set["spell_info"] = "";
- if((racePowers + classPowers) == 0) {
- set["spell_info"] += '
The arcane is a mystery to you.
';
- deleteCharmancerData(["l1-spells"]);
- spellsready = false;
- } else if(prevRace != currentRace || prevClass != currentClass || mancerdata["l1-spells"].values.race_number != racePowers || mancerdata["l1-spells"].values.class_number != classPowers) {
- if(prevRace != currentRace || mancerdata["l1-spells"].values.race_number > racePowers) {
- for(var x = 1; x<=9; x++) {
- toDelete.push("race_level0_choice" + x);
- toDelete.push("race_level1_choice" + x);
- }
- if(racePowers > 0 && mancerdata["l1-spells"].values.race_number > 0) {
- set["spell_info"] += '
Your racial spells were reset because your options have changed.
';
- }
- }
- if(prevClass != currentClass || mancerdata["l1-spells"].values.class_number > classPowers) {
- for(var x = 1; x<=9; x++) {
- toDelete.push("class_level0_choice" + x);
- toDelete.push("class_level1_choice" + x);
- }
- if(classPowers > 0 && mancerdata["l1-spells"].values.class_number > 0) {
- set["spell_info"] += '
Your class spells were reset because your options have changed.
';
- }
- }
- }
- } else if((racePowers + classPowers) > 0) {
- set["spell_info"] = '
You haven\'t selected your spells!
';
- spellsready = false;
- showChoices(["spells_button"]);
- } else {
- set["spell_info"] = '
The arcane is a mystery to you.
';
- spellsready = false
- }
-
- if(mancerdata["l1-race"] && mancerdata["l1-race"].data.subrace && mancerdata["l1-race"].data.subrace["data-Feats"]) {
- if(mancerdata["l1-feat"] && mancerdata["l1-feat"].values.feat) {
- set["feat_info"] = '
You\'ve selected the ' + mancerdata["l1-feat"].values.feat.split(":")[1] + ' feat.
';
- set["feat_info"] += handleMissing("feat");
- } else {
- set["feat_info"] = '
You have access to a feat, but you have not yet selected one!
';
- }
- } else {
- set["feat_info"] = '
As you exchange your novice notions of the world for experience, a feat may become within reach. Not today, however.
';
- deleteCharmancerData(["l1-feat"]);
- }
-
- if(ready) {
- set.ready_message = "If you're ready to build your " + racename;
- set.ready_message += subracename == "" ? " " : " (" + subracename + ") ";
- set.ready_message += subclassname == "" ? classname : classname + " (" + subclassname + ")";
- set.ready_message += " from a " + bgname + " background, click \"Apply Changes.\"";
- showChoices(["apply_changes", "ready_text"]);
- } else {
- set.ready_message = "Hold on there! You've missed some required fields, which have been marked with a
.";
- }
- //If you're ready to build your race class from a background background, click "Apply Changes."
- deleteCharmancerData([{"l1-spells":toDelete}], function() {
- spelldata = knownPowers();
- if(spellsready) {
- if (spelldata.known && spelldata.known.length) {
- set["spell_info"] += '
You know these spells: ' + removeExpansionInfo(spelldata.known.join(", ")) + '.
';
- }
- var choices = {"prime": [0,0], "spell": [0,0]};
- _.each(spelldata, function(section) {
- _.each(section.choices, function(spell) {
- if(spell.Level == 0) choices.prime[0]++;
- if(spell.Level == 1) choices.spell[0]++;
- });
- });
- choices.prime[1] = choices.prime[0];
- choices.spell[1] = choices.spell[0];
- _.each(mancerdata["l1-spells"].values, function(val, name) {
- if(name.split("_")[3] == "spell-l0" && _.last(name.split("_")) == "choice") choices.prime[1]--;
- if(name.split("_")[3] == "spell-l1" && _.last(name.split("_")) == "choice") choices.spell[1]--;
- });
- _.each(choices, function(number, type) {
- if(number[1] > 0) {
- set["spell_info"] += '
You can choose ';
- set["spell_info"] += number[0] > 1 ? "up to " + number[0] + ' ' + type + 's' : "a " + type;
- if(number[1] < number[0]) {
- set["spell_info"] += ', but you\'ve only chosen ' + (number[0] - number[1]) + '!
';
- } else {
- set["spell_info"] += number[0] > 1 ? ', and you haven\'t chosen any!' : ', and you haven\'t chosen one!';
- }
- }
- });
- }
- setCharmancerText(set);
- });
-});
-
-/* Info Button Listeners */
-on("clicked:info_race", function(eventinfo) {
- var data = getCharmancerData();
- var race = data["l1-race"] && data["l1-race"].values.race ? data["l1-race"].values.race : "Rules:Races";
- changeCompendiumPage("sheet-race-info", race);
-});
-
-on("clicked:info_subrace", function(eventinfo) {
- var data = getCharmancerData();
- var subrace = data["l1-race"] && data["l1-race"].values.subrace ? data["l1-race"].values.subrace : data["l1-race"].values.race;
- changeCompendiumPage("sheet-race-info", subrace);
-});
-
-on("clicked:info_class", function(eventinfo) {
- var data = getCharmancerData();
- var oclass = data["l1-class"] && data["l1-class"].values.class ? data["l1-class"].values.class : "Rules:Classes";
- changeCompendiumPage("sheet-class-info", oclass);
-});
-
-on("clicked:info_subclass", function(eventinfo) {
- var data = getCharmancerData();
- var osubclass = data["l1-class"] && data["l1-class"].values.subclass ? data["l1-class"].values.subclass : data["l1-class"].values.class;
- changeCompendiumPage("sheet-class-info", osubclass);
-});
-
-on("mancerfinish:l1-mancer", function(eventinfo) {
- var doAllDrops = function(dropArray, callback) {
- getAttrs(["character_id"], function(v) {
- _.each(stats.totals, function(scores, name) {
- v[name + "_base"] = scores.total;
- v[name + "_mod"] = scores.mod;
- });
- v.base_level = "1";
- v.npc = "0";
- v["class_resource_name"] = "";
- v["other_resource_name"] = "";
- var update = {};
- var callbacks = [];
- var totalDrops = dropArray.length;
- var x = 0;
- callbacks.push(update_class);
- callbacks.push(update_race_display);
- get_repeating_data(function(repeating) {
- _.each(dropArray, function(page) {
- page.data.Category = page.data.Category.replace("@@!!@@", "");
- var dropUpdate = processDrop(page, v, repeating, true);
- callbacks = callbacks.concat(dropUpdate.callbacks);
- repeating.prof_names = _.uniq(repeating.prof_names.concat(dropUpdate.prof_names));
- update = _.extend(update, dropUpdate.update);
- x++;
- setCharmancerText({"mancer_progress" :'
'});
- });
-
- callbacks.push( function() {update_ac();} );
- callbacks.push( function() {update_weight();} );
- callbacks.push(callback);
- console.log(update);
- setAttrs(update, {silent: true}, function() {
- setCharmancerText({"mancer_progress" :'
'});
- _.each(callbacks, function(callback) {
- callback();
- });
- });/**/
- });
- });
- };
- var getOtherDrops = function(pagedata) {
- var results = [];
- if(pagedata["data-Equipment"]) {
- console.log("ADDING ADDITIONAL ITEMS:");
- var json = {};
- try {
- json = JSON.parse(pagedata["data-Equipment"]);
- } catch(e) {
- json = pagedata["data-Equipment"];
- }
- var newItems = makeItemData(json.default);
- results = results.concat(newItems);
- }
- if(pagedata["data-Bundle"]) {
- console.log("ADDING ADDITIONAL ITEMS (FROM BUNDLE):");
- var json = {};
- try {
- json = JSON.parse(pagedata["data-Bundle"]);
- } catch(e) {
- json = pagedata["data-Bundle"];
- }
- var newItems = makeItemData(json);
- results = results.concat(newItems);
- }
- return results;
- };
- var getAllPages = function(pageArray, callback) {
- var getNames = [];
- _.each(pageArray, function(page){
- if(page.name) {
- getNames.push(page.name);
- } else {
- getNames.push(page);
- }
- });
- getCompendiumPage(getNames, function(data) {
- data = removeDuplicatedPageData(data);
- var nextGet = [];
- if (getNames.length === 1) { data = {0:data} }; //Fix single spell selections failing.
- _.each(data, function(page, index) {
- var pagedata = false;
- _.each(pageArray, function(arrayData) {
- if(arrayData.name.toLowerCase() == (page.data.Category + ":" + page.name).toLowerCase()) {
- pagedata = arrayData;
- }
- });
- if(pagedata && pagedata.data) {
- page.data = _.extend(page.data, pagedata.data);
- }
- if(!page.id) page.data.Source = "Charactermancer";
- page.name = page.name.replace(/@@!!@@/g,""); // Hacky bugfix to prevent custom names from matching unavailable content
- nextGet = nextGet.concat(getOtherDrops(page.data));
- if(page.data["data-Starting Cubil"] && !noEquipmentDrop) {
- set["cu"] += parseInt(page.data["data-Starting Cubil"]);
- }
- allPageData.push(page);
- });
-
- if(nextGet.length > 0) {
- console.log("DOING ANOTHER GET!!");
- getAllPages(nextGet, callback);
- } else {
- callback();
- }
-
- });
- };
- var makeItemData = function(items) {
- if (noEquipmentDrop) {
- return [];
- } else {
- var itemArray = [];
- var splitItems = [];
- _.each(items, function(item) {
- item = item.split(",");
- _.each(item, function(splitItem) {
- splitItems.push(splitItem.trim());
- });
- })
- _.each(splitItems, function(item) {
- var itemname = item.split("(")[0].trim().replace("Items:", "");
- itemname = itemname.substring(0,4) == "and " ? itemname.substr(4) : itemname;
- var itemdata = {name:"Items:" + itemname, data:{}}
- if(item.includes("(")) {
- var par = item.split("(")[1].split(")")[0];
- if( !isNaN(parseInt(par)) ) {
- itemdata.data["itemcount"] = parseInt(par);
- }
- }
- if(itemname != "") {
- itemArray.push(itemdata);
- }
- });
- return itemArray;
- }
- };
- var eraseRepeating = function(sectionArray, callback) {
- var thisSection = sectionArray.shift();
- getSectionIDs(thisSection, function(itemids) {
- _.each(itemids, function(item) {
- removeRepeatingRow("repeating_" + thisSection + "_" + item);
- });
- if(sectionArray.length > 0) {
- eraseRepeating(sectionArray, callback);
- } else {
- callback();
- }
-
- });
- };
- var noEquipmentDrop = false;
- var startTime = Date.now();
- var allPageData = [];
- if(eventinfo.data["l1-equipment"]) {
- noEquipmentDrop = eventinfo.data["l1-equipment"].values["equipment_type"] == "cubil";
- }
- var data = eventinfo.data;
- var stats = recalcData(data);
- var profs = getProficiencies(data, "finish");
- var spells = knownPowers(data);
- var blobs = getRelevantBlobs(data, "1", "l1");
- var customtraits = {race: [], subrace: [], class: [], subclass: [], background: []};
- var equipment = [];
- var silentset = {};
- var silentattrs = ["class_resource_name", "class_resource", "class_resource_max", "other_resource_name", "other_resource", "other_resource_max", "other_resource_itemid", "class", "class_display", "subclass", "hitdietype", "hitdie_final", "race", "subrace", "race_display", "custom_class", "cust_classname"];
- var clearset = {};
- var clearattrs = ["hp", "hp_max", "size", "speed", "cu", "alignment", "global_damage_mod_flag", "spellcasting_ability", "cust_hitdietype", "cust_spellslots", "cust_spellcasting_ability", "ac", "jack_bonus", "jack_attr", "death_save_bonus", "weighttotal", "initiative_bonus", "hit_dice", "hit_dice_max", "pb", "jack", "caster_level", "spell_attack_mod", "spell_attack_bonus", "spell_save_dc", "passive_wisdom", "custom_ac_base", "custom_ac_part1", "custom_ac_part2", "custom_ac_shield", "background", "global_ac_mod_flag", "global_attack_mod_flag", "global_save_mod_flag", "global_skill_mod_flag"];
- var classname = "";
- var set = {cu: 0};
- var allDrops = [];
- var currentDrop = 0;
- var totalDrops = 1;
- var allSkills = ["athletics", "acrobatics", "sleight_of_hand", "stealth", "astrophysics", "lore", "investigation", "xenobiology", "computers", "mechanics", "insight", "medicine", "perception", "survival", "deception", "intimidation", "performance", "persuasion", "piloting"];
- var allAbilities = abilityList.map(function(x) {return x.toLowerCase()});
- var eraseSections = ["attack", "inventory", "traits", "resource", "proficiencies", "tool", "damagemod", "spell-prime", "hpmod", "acmod", "tohitmod", "savemod", "skillmod"];
- console.log(blobs);
- console.log(spells);
- for(var x=1; x<=9; x++) {
- eraseSections.push("spell-" + x);
- }
- //first set is silent to make sure certain things don't trigger workers
- _.each(silentattrs, function(attr) {
- silentset[attr] = "";
- });
- //Set up setAttrs to erase some fields
- _.each(clearattrs, function(attr) {
- clearset[attr] = "";
- });
- clearset["halflingluck_flag"] = "0";
- clearset["tab"] = "core";
- clearset["base_level"] = "1";
- clearset["level"] = "1";
- clearset["armorwarningflag"] = "hide";
- clearset["customacwarningflag"] = "hide";
- clearset["custom_ac_flag"] = "0";
- clearset["custom_attack_flag"] = "0";
- clearset["custom_ac_flag"] = "0";
- clearset["multiclass1_flag"] = "0";
- clearset["multiclass1_lvl"] = "1";
- clearset["multiclass2_flag"] = "0";
- clearset["multiclass2_lvl"] = "1";
- clearset["multiclass3_flag"] = "0";
- clearset["multiclass3_lvl"] = "1";
- clearset["custom_class"] = "0";
- _.each(allSkills, function(skill) {
- clearset[skill + "_prof"] = "";//0
- clearset[skill + "_type"] = "";//1
- clearset[skill + "_bonus"] = "";
- });
- _.each(allAbilities, function(ability) {
- clearset[ability + "_save_prof"] = "";
- clearset[ability + "_save_bonus"] = "";
- clearset[ability + "_bonus"] = "0";
- clearset["cust_" + ability + "_save_prof"] = "";
- });
- clearset["personality_traits"] = "";
- _.each(["ideal", "bond", "flaw"], function(type) {
- clearset[type + "s"] = "";
- });
- //Set up second setAttrs with ability scores
- _.each(stats.totals, function(scores, name) {
- clearset[name + "_base"] = scores.total;
- });
- // Build new blobs for traits with inputs, collect custom traits and languages
- _.each(data, function(slide, pagename) {
- _.each(slide.values, function(value, name) {
- if(name.substr(-11) == "trait_input") {
- var sectionid = name.substring(0, name.length - 6);
- var thisblob = {};
- var thistrait = {};
- thistrait.Name = slide.values[sectionid + "_name"].replace(/{{Input}}/g, value);
- thistrait.Desc = slide.values[sectionid + "_desc"] ? slide.values[sectionid + "_desc"].replace(/{{Input}}/g, value) : "";
- thisblob.Traits = JSON.stringify([thistrait]);
- blobs.names[slide.values[sectionid + "_section"]].push(sectionid);
- slide.data[slide.values[sectionid + "_section"]].blobs[sectionid] = thisblob;
- }
- if(name.split("_")[2] == "custom" && name.substr(-10) == "trait_name") {
- var sectionid = name.substring(0, name.length - 5);
- var thistrait = {};
- thistrait.Name = slide.values[sectionid + "_name"];
- thistrait.Desc = slide.values[sectionid + "_desc"] ? slide.values[sectionid + "_desc"] : "";
- customtraits[name.split("_")[3]].push(thistrait);
- }
- if(value == "custom" && name.substr(-18) == "proficiency_choice") {
- var sectionid = name.substring(0, name.length - 7);
- if(slide.values[sectionid + "_custom"] && slide.values[sectionid + "_type"]) {
- profs.all[slide.values[sectionid + "_type"]].push(slide.values[sectionid + "_custom"])
- }
- }
- })
- });
- //Set up drops. start with class, subclass, race, subrace, background
- if(data["l1-class"].values["class_name"] && !data["l1-class"].data.class) {
- classname = removeExpansionInfo(data["l1-class"].values["class_name"]);
- var customClass = {name: classname, data: {Category: "Classes", blobs:{}}};
- set["custom_class"] = "1";
- set["cust_classname"] = data["l1-class"].values["class_name"];
- set["cust_hitdietype"] = data["l1-class"].values["custom_hit_die"];
- if(data["l1-class"].values["custom_class_spell_ability"]) {
- set["cust_spellslots"] = "full";
- set["cust_spellcasting_ability"] = "@{" + data["l1-class"].values["custom_class_spell_ability"].toLowerCase() + "_mod}+";
- }
- if(customtraits.class.length > 0) {
- customClass.data.theseblobs = ["customblob"];
- customClass.data.blobs.customblob = {Traits: JSON.stringify(customtraits.class)};
- }
- _.each(allAbilities, function(ability) {
- if(data["l1-class"].values[ability.toLowerCase() + "_save"]) {
- set["cust_" + ability + "_save_prof"] = "(@{pb})";
- }
- });
- allPageData.push(customClass);
- } else {
- //allDrops.push(data["l1-class"].values.class);
- classname = removeExpansionInfo( _.last(data["l1-class"].values.class.split(":")) );
- var thisdata = {name: classname, data: data["l1-class"].data.class};
- thisdata.data.theseblobs = blobs.names.class;
- allPageData.push(thisdata);
- };
- //set up subclass drop
- if(data["l1-class"].values.subclass && data["l1-class"].values["subclass_name"]) {
- var customSubclass = {name: removeExpansionInfo (data["l1-class"].values["subclass_name"] ), data: {Category: "Subclasses", blobs:{}}};
- if(customtraits.subclass.length > 0) {
- customSubclass.data.theseblobs = ["customblob"];
- customSubclass.data.blobs.customblob = {Traits: JSON.stringify(customtraits.subclass)};
- }
- allPageData.push(customSubclass);
- } else if(data["l1-class"].values.subclass) {
- //allDrops.push(data["l1-class"].values.subclass);
- var thisdata = {name: removeExpansionInfo( _.last(data["l1-class"].values.subclass.split(":")) ), data: data["l1-class"].data.subclass};
- thisdata.data.theseblobs = blobs.names.subclass;
- allPageData.push(thisdata);
- };
- //set up race drop
- if(data["l1-race"].values["race_name"] && !data["l1-race"].data.race) {
- var customRace = {name: removeExpansionInfo(data["l1-race"].values["race_name"]), data: {Category: "Races", blobs:{}}};
- if(data["l1-race"].values.size) {
- customRace.data.Size = data["l1-race"].values.size;
- }
- if(data["l1-race"].values.speed) {
- customRace.data.Speed = data["l1-race"].values.speed;
- }
- if(customtraits.race.length > 0) {
- customRace.data.theseblobs = ["customblob"];
- customRace.data.blobs.customblob = {Traits: JSON.stringify(customtraits.race)};
- }
- allPageData.push(customRace);
- } else {
- //allDrops.push(data["l1-race"].values.race);
- var thisdata = {name: removeExpansionInfo(_.last(data["l1-race"].values.race.split(":"))), data: data["l1-race"].data.race};
- thisdata.data.theseblobs = blobs.names.race;
- allPageData.push(thisdata);
- }
- //set up subrace drop
- if(data["l1-race"].values.subrace && data["l1-race"].values["subrace_name"]) {
- var customSubrace = {name: removeExpansionInfo(data["l1-race"].values["subrace_name"]), data: {Category: "Subraces", blobs:{}}};
- customSubrace.data["data-Parent"] = data["l1-race"].values.race.split(":")[1];
- if(data["l1-race"].values.speed) {
- customSubrace.data.Speed = data["l1-race"].values.speed;
- }
- if(customtraits.subrace.length > 0) {
- customSubrace.data.theseblobs = ["customblob"];
- customSubrace.data.blobs.customblob = {Traits: JSON.stringify(customtraits.subrace)};
- }
- allPageData.push(customSubrace);
- } else if(data["l1-race"].values.subrace) {
- //allDrops.push(data["l1-race"].values.subrace);
- var thisdata = {name: removeExpansionInfo(_.last(data["l1-race"].values.subrace.split(":"))), data: data["l1-race"].data.subrace};
- thisdata.data.theseblobs = blobs.names.subrace;
- allPageData.push(thisdata);
- };
- //set up feat drop
- if(data["l1-feat"] && data["l1-feat"].values.feat) {
- var feat = {name: data["l1-feat"].values.feat, data: {Properties: "1st Level"}};
- allDrops.push(feat);
- }
- //set up background drop
- if(data["l1-background"].values.background) {
- if(data["l1-background"].values.background == "Rules:Backgrounds") {
- var customBg = {name: removeExpansionInfo(data["l1-background"].values["background_name"]), data: {Category: "Backgrounds", blobs:{}}};
- if(customtraits.background.length > 0) {
- customBg.data.theseblobs = ["customblob"];
- customBg.data.blobs.customblob = {Traits: JSON.stringify(customtraits.background)};
- }
- allPageData.push(customBg);
- } else {
- var thisdata = {name: removeExpansionInfo(_.last(data["l1-background"].values.background.split(":"))), data: data["l1-background"].data.background};
- thisdata.data.theseblobs = blobs.names.background;
- allPageData.push(thisdata);
- }
- }
-
- //Now add proficiency drops
- _.each(["Armor", "Language", "Tool", "Weapon"], function(proftype) {
- _.each(profs.all[proftype], function(prof) {
- var profdata = {name: "Proficiencies:" + prof, data: {Type: proftype}}
- if(profs.all.Expertise.indexOf(prof) != -1) {
- profdata.data["toolbonus_base"] = "(@{pb}*2)";
- allDrops.unshift(profdata);
- } else {
- allDrops.push(profdata);
- }
- });
- });
-
- //Next, add spell drops
- _.each(spells.all, function(spell) {
- console.log(spell);
- var spelldata = {name: "Powers:" + spell.Name};
- spelldata.data = {"spellcasting_ability": spell.Ability};
- if(spell.Source == "race") {
- spelldata.data.spellclass = "Racial";
- } else {
- spelldata.data.spellclass = classname;
- };
- allDrops.push(spelldata);
- });
- //Add equipment choice drops unless starting cubil was chosen
- if (data["l1-equipment"].values["equipment_type"] != "cubil") {
- _.each(data["l1-equipment"].values, function(val, name) {
- if(name.includes("background_equipment_choice")) {
- equipment = equipment.concat(val.split(" and "));
- }
- });
- _.each(blobs.all, function(blob) {
- if(blob.Equipment) {
- var blobstuff = blob.Equipment;
- try {
- blobstuff = JSON.parse(blob.Equipment);
- } catch (e) {}
- equipment = equipment.concat(blobstuff);
- }
- })
- }
-
- //Here there is a window to modify the hitpoints, however additional hitpoints inserted here would not appear on charatermancer header
- //By Miguel
-
- //Set up the final setAttrs()
- set["alignment"] = data["l1-race"].values.alignment || "";
- set["hp"] = stats.hp;
- set["hp_max"] = stats.hp;
- set["l1mancer_status"] = "completed";
- set["options-class-selection"] = "0";
- if(data["l1-equipment"].values["equipment_type"] == "class") {
- _.each(data["l1-equipment"].values, function(val, name) {
- if(name.includes("class_equipment_choice")) {
- equipment = equipment.concat(val.split(" and "));
- }
- });
- } else if(data["l1-equipment"].values["equipment_type"] == "cubil" && data["l1-equipment"].values["starting_cubil"]) {
- set["cu"] = parseInt(data["l1-equipment"].values["starting_cubil"]);
- }
- //Add the bio info
- if(data["l1-bio"]) {
- _.each(["character_name", "age", "height", "weight", "eyes", "hair", "skin"], function(type) {
- if(data["l1-bio"].values[type]) {
- set[type] = data["l1-bio"].values[type] || "";
- }
- });
- }
- //Add skill proficiencies
- _.each(_.uniq(profs.all.Skill.concat(profs.all.Expertise)), function(prof) {
- var profName = prof.toLowerCase().replace(/ /g, "_");
- set[profName + "_prof"] = "(@{pb}*@{" + profName + "_type})";
- if(profs.all.Expertise.indexOf(prof) != -1) {
- set[profName + "_type"] = 2;
- }
- });
- //Add background traits
- if(data["l1-background"].values["background_personality_choice1"] || data["l1-background"].values["background_personality_choice2"]) {
- var choice1 = data["l1-background"].values["background_personality_choice1"] || false;
- var choice2 = data["l1-background"].values["background_personality_choice2"] || false;
- choice1 = choice1 || choice2;
- if(choice1) {
- set["personality_traits"] = choice1;
- }
- if(choice2) {
- set["personality_traits"] += "\n\n" + choice2;
- }
- set["options-flag-personality"] = 0;
- }
- _.each(["ideal", "bond", "flaw"], function(type) {
- if(data["l1-background"].values["background_" + type + "_choice"]) {
- set[type + "s"] = data["l1-background"].values["background_" + type + "_choice"];
- set["options-flag-" + type + "s"] = 0;
- }
- });
- if(data["l1-background"].values["background_detail_choice"]) {
- set["background"] = removeExpansionInfo(_.last(data["l1-background"].values["background"].split(":"))) + " (" + data["l1-background"].values["background_detail_choice"] + ")";
- }
- allDrops = allDrops.concat(makeItemData(equipment));
- totalDrops += allDrops.length;
- _.each(allPageData, function(page) {
- allDrops = allDrops.concat(getOtherDrops(page.data));
- });
-
- //erase all repeating sections
- eraseRepeating(eraseSections, function() {
- setCharmancerText({"mancer_progress" :'
'});
- //first set is silent to prevent unwanted sheet workers
- setAttrs(silentset, {silent:true}, function() {
- setCharmancerText({"mancer_progress" :'
'});
- //reset remaining attributes, and set ability scores/custom info
- setAttrs(clearset, function() {
- setCharmancerText({"mancer_progress" :'
'});
- getAllPages(allDrops, function() {
- setCharmancerText({"mancer_progress" :'
'});
- doAllDrops(allPageData, function() {
- console.log("DOING THE FINAL SET!!");
- setAttrs(set, function() {
- setCharmancerText({"mancer_progress" :'
'});
- update_class();
- organize_section_proficiencies();
- update_skills(allSkills);
- update_attacks("all");
- var endTime = Date.now();
- console.log("Elapsed time: ");
- console.log((endTime-startTime)/1000);
- finishCharactermancer();
- });
- });
- });
- });
- });
- });
- /* */
-});
-
-/*********************************************************************/
-/****** LEVEL UP MANCER WORKERS ******/
-/*********************************************************************/
-
-//Helper function to update the text in the top bar
-var recalcLpData = function(blobs) {
- var mancerdata = getCharmancerData();
- var abilities = getAbilityTotals(mancerdata, blobs);
- var update = {};
- _.each(abilityList, function(ability) {
- var selector = "attr-container .sheet-" + ability.toLowerCase() + "_total";
- update[selector] = abilities[ability.toLowerCase()] + " | " + abilities[ability.toLowerCase() + "_mod"];
- });
- update["hit_points"] = getHpTotal(mancerdata, blobs, abilities);
- setCharmancerText(update);
-};
-//Helper function to get ability totals, including asi
-var getAbilityTotals = function(mancerdata, blobs) {
- mancerdata = mancerdata || getCharmancerData();
- blobs = blobs || getAllLpBlobs(mancerdata, true);
- var abilities = mancerdata["lp-welcome"].values["previous_abilities"] ? JSON.parse(mancerdata["lp-welcome"].values["previous_abilities"]) : {};
- var lcAbilities = abilityList.map(function(x) {return x.toLowerCase()});
- //Set previous scores first
- _.each(lcAbilities, function(ability) {
- abilities[ability + "_previous"] = abilities[ability];
- abilities[ability + "_previous_mod"] = abilities[ability + "_mod"];
- abilities[ability + "_maximum"] = abilities[ability + "_maximum"] ? parseInt(abilities[ability + "_maximum"]) : 20;
- });
- _.each(blobs.all, function(blob) {
- if(blob["Ability Score Increase"]) {
- var asi = JSON.parse(blob["Ability Score Increase"]);
- _.each(asi, function(increase, ability) {
- abilities[ability.toLowerCase()] += parseInt(increase);
- });
- }
- if(blob["Ability Score Max"]) {
- var max = JSON.parse(blob["Ability Score Max"]);
- _.each(max, function(increase, ability) {
- abilities[ability.toLowerCase() + "_maximum"] = parseInt(increase);
- });
- }
- })
- //Now add asi if it exists
- if(mancerdata["lp-asi"]) {
- _.each(mancerdata["lp-asi"].repeating, function(repid) {
- if(repid.substr(31) == "asi-row" && mancerdata["lp-asi"].values[repid + "_switch"] != "feat") {
- _.each(lcAbilities, function(ability) {
- abilities[ability] += mancerdata["lp-asi"].values[repid + "_" + ability] ? parseInt(mancerdata["lp-asi"].values[repid + "_" + ability]) : 0;
- abilities[ability + "_mod"] = Math.floor((abilities[ability] - 10)/2);
- });
- }
- });
- }
- return abilities;
-};
-//Helper function to get hp total
-var getHpTotal = function(mancerdata, blobs, abilities) {
- mancerdata = mancerdata || getCharmancerData();
- var leveldata = getLevelingData(mancerdata);
- var abilities = abilities || getAbilityTotals(mancerdata, blobs);
- var previous = mancerdata["lp-welcome"].values["previous_attributes"] ? JSON.parse(mancerdata["lp-welcome"].values["previous_attributes"]) : {};
- var prev_repeat = JSON.parse(mancerdata["lp-welcome"].values["previous_repeating"]), hpmod = prev_repeat["hpmod"];
- var newhp = 0;
- var additionalhp = 0;
- var totalpreviouslevel = parseInt(previous["base_level"]);
- for(var x=1; x<=3; x++) {
- if(previous["multiclass" + x + "_flag"] != "0") totalpreviouslevel += parseInt(previous["multiclass" + x + "_lvl"]);
- };
-
- //Calculate HP Mods things like Hill Dwarf
- let levelbonus = 0;
- _.each(hpmod, (mod) => {
- const bonus = mod["mod"];
- if (mod["levels"] === "total") {
- levelbonus += parseInt(bonus);
- };
- });
-
- //Add up the hp per level
- _.each(leveldata, function(level) {
- newhp += level.addhp > 0 ? level.addhp + (level.addlevel * abilities["constitution_mod"]) + (level.addlevel * levelbonus) : 0;
- });
-
- additionalhp = totalpreviouslevel * (abilities["constitution_mod"] - abilities["constitution_previous_mod"])
- return parseInt(previous["hp_max"]) + newhp + additionalhp;
-};
-
-var recalcButtons = function(mancerdata, thispage) {
- mancerdata = mancerdata || getCharmancerData();
- var buttons = "";
- var buttoninfo = {
- welcome: "charmancer-start",
- levels: "levels-u",
- choices: "features-u",
- asi: "asi-u",
- spells: "spells-u",
- summary: "review-u"
- };
- _.each(buttoninfo, function(translation, page) {
- let here = "lp-" + page == thispage;
- let disabled = false;
- if(thispage === "lp-spellchoice") disabled = true;
- if(!here && page !== "levels" && thispage === "lp-welcome") disabled = true;
- if(mancerdata["lp-levels"]) {
- if (!here && page === "asi" && mancerdata["lp-levels"].values.asi !== "true") disabled = true;
- if (!here && page === "spells" && mancerdata["lp-levels"].values.spells !== "true") disabled = true;
- } else {
- if (!here && (page === "asi" || page === "spells")) disabled = true;
- }
- buttons += "
";
- });
- buttons += "
CANCEL ";
- setCharmancerText({steps: buttons});
-}
-//Worker for every page to add topbar/buttons
-on("page:lp-welcome page:lp-levels page:lp-choices page:lp-asi page:lp-spells page:lp-summary page:lp-spellchoice", function(eventinfo) {
- var mancerdata = getCharmancerData();
- recalcButtons(mancerdata, eventinfo.triggerName);
- if(eventinfo.triggerName != "lp-welcome" && eventinfo.triggerName != "lp-summary") {
- addRepeatingSection("topbar-holder", "leveler-topbar");
- if(eventinfo.triggerName != "lp-choices" && eventinfo.triggerName != "lp-spells") recalcLpData();
- getProficiencies(mancerdata, eventinfo.currentStep);
- }
- getAttrs(["licensedsheet"], function(v) {
- if("licensedsheet" in v && v.licensedsheet === "1") {
- setCharmancerText({"sheet-licensedsheet-flag":"true"});
- }
- });
-});
-
-on("page:lp-welcome", function(eventinfo) {
- var getInfo = (sections, callback, results) => {
- results = results || {};
- if(sections.length > 0) {
- var section = sections.pop();
- getSectionIDs(section, function(ids) {
- results[section] = ids;
- getInfo(sections, callback, results);
- });
- } else {
- callback(results);
- }
- };
- var capitalize = function(string) {
- return string.split(" ").map((x) => {
- x = x.toLowerCase();
- return x[0].toUpperCase() + x.substr(1, x.length);
- }).join(" ");
- };
- var spellSections = ["spell-prime"];
- var allSkills = ["athletics", "acrobatics", "sleight_of_hand", "stealth", "astrophysics", "lore", "investigation", "xenobiology", "computers", "mechanics", "insight", "medicine", "perception", "survival", "deception", "intimidation", "performance", "persuasion", "piloting"];
- var skillget = [];
- for(var x=1; x<=9; x++) {
- spellSections.push("spell-" + x);
- }
-
- getInfo(spellSections, function(results) {
- var getList = [];
- _.each(results, function(sectionids, sectionname) {
- _.each(sectionids, function(spellid) {
- getList.push("repeating_" + sectionname + "_" + spellid + "_spellname");
- getList.push("repeating_" + sectionname + "_" + spellid + "_spellclass");
- getList.push("repeating_" + sectionname + "_" + spellid + "_spelllevel");
- getList.push("repeating_" + sectionname + "_" + spellid + "_spellsource");
- });
- });
- getAttrs(getList, function(attrs) {
- var spellInfo = {};
- _.each(attrs, function(data, name) {
- var namearray = name.split("_");
- var thisattr = namearray.pop();
- var thisname = namearray.join("_");
- spellInfo[thisname] = spellInfo[thisname] || {};
- spellInfo[thisname][thisattr] = data;
- });
- setAttrs({spellinfo: JSON.stringify(spellInfo)});
- });
- });
- getAttrs(["strength", "strength_mod", "dexterity", "dexterity_mod", "constitution", "constitution_mod", "intelligence", "intelligence_mod", "wisdom", "wisdom_mod", "charisma", "charisma_mod", "strength_maximum", "dexterity_maximum", "constitution_maximum", "intelligence_maximum", "wisdom_maximum", "charisma_maximum"], function(attrs) {
- _.each(attrs, function(x, y) {
- attrs[y] = parseInt(x);
- });
- setAttrs({previous_abilities: JSON.stringify(attrs)});
- });
- getAttrs(["class", "subclass", "base_level", "multiclass1_flag", "multiclass2_flag", "multiclass3_flag", "multiclass1", "multiclass1_lvl", "multiclass1_subclass", "multiclass2", "multiclass2_lvl", "multiclass2_subclass", "multiclass3", "multiclass3_lvl", "multiclass3_subclass", "hp_max", "class_resource_name", "other_resource_name", "speed", "race", "subrace", "background", "custom_class", "cust_classname", "cust_hitdietype"], function(v) {
- let set = {};
- set["previous_attributes"] = JSON.stringify(v);
- set["lp-race"] = "Races:" + v.race;
- set["lp-subrace"] = "Subraces:" + v.subrace;
- set["lp-background"] = "Backgrounds:" + v.background.split("(")[0].trim();
- setAttrs(set);
- });
- _.each(allSkills, function(skill) {
- skillget.push(skill + "_prof");
- skillget.push(skill + "_type");
- });
- getAttrs(skillget, function(v) {
- var proficiencies = {"Weapon": [], "Armor": [], "Skill": [], "Tool": [], "Language": [], "Expertise": []};
- _.each(allSkills, function(skill) {
- if(v[skill + "_prof"] !== "0") {
- proficiencies.Skill.push(capitalize(skill.replace(/_/g, " ")));
- }
- if(v[skill + "_type"] !== "1" && v[skill + "_prof"] !== "0") {
- proficiencies.Expertise.push(capitalize(skill.replace(/_/g, " ")));
- }
- });
- getSectionIDs("tool", function(ids) {
- var getList = [];
- _.each(ids, function(id) {
- getList.push("repeating_tool_" + id + "_toolname");
- getList.push("repeating_tool_" + id + "_toolbonus_base");
- });
- getAttrs(getList, function(v) {
- _.each(ids, function(id) {
- proficiencies.Tool.push(v["repeating_tool_" + id + "_toolname"]);
- if(v["repeating_tool_" + id + "_toolbonus_base"] == "(@{pb}*2)") {
- proficiencies.Expertise.push(v["repeating_tool_" + id + "_toolname"]);
- };
- });
- getSectionIDs("proficiencies", function(ids) {
- var getList = [];
- _.each(ids, function(id) {
- getList.push("repeating_proficiencies_" + id + "_name");
- getList.push("repeating_proficiencies_" + id + "_prof_type");
- });
- getAttrs(getList, function(v) {
- _.each(ids, function(id) {
- proficiencies[capitalize(v["repeating_proficiencies_" + id + "_prof_type"])].push(v["repeating_proficiencies_" + id + "_name"]);
- });
- setAttrs({previous_proficiencies: JSON.stringify(proficiencies)});
- });
- });
- });
- });
- });
- get_repeating_data(function(repeating) {
- console.log("REPEATING");
- console.log(repeating);
- setAttrs({previous_repeating: JSON.stringify(repeating)});
- });
-});
-
-on("mancerchange:lp-race mancerchange:lp-subrace mancerchange:lp-background", function(eventinfo) {
- getCompendiumPage(eventinfo.newValue, function(results) {});
-});
-
-on("page:lp-levels", function(eventinfo) {
- const mancerdata = getCharmancerData();
- const previous = mancerdata["lp-welcome"].values["previous_attributes"] ? JSON.parse(mancerdata["lp-welcome"].values["previous_attributes"]) : {};
- let levelclass = ["class1"];
- let set = {};
- let update = {};
- let baseclass = previous["class"];
- let classcompend = ["Classes:"] + previous["class"];
- let custom_lock = 0;
-
- if(previous["custom_class"] && previous["custom_class"] == 1) {
- baseclass = previous["cust_classname"];
- classcompend = "Rules:Classes";
- custom_lock = 1;
- set["class1_addlevel"] = 0;
- };
-
- set["lockcustomclass"] = custom_lock;
- set["class1"] = 'Classes:' + baseclass;
- set["class1_currentlevel"] = previous["base_level"];
- update["class1_selector"] = '
' + baseclass + ' ';
- if (previous["subclass"] && previous["custom_class"] === "0") {
- update[`subclass1_selector`] = `
` + previous["subclass"] + `
`;
- if((mancerdata["lp-levels"] && mancerdata["lp-levels"].values["class1_subclass"] !== "Subclasses" + previous["subclass"])
- || !mancerdata["lp-levels"]) set["class1_subclass"] = "Subclasses:" + previous["subclass"];
- };
- const multiclass = parseInt(previous["multiclass1_flag"]) + parseInt(previous["multiclass2_flag"]) + parseInt(previous["multiclass3_flag"]);
- set["multiclass"] = mancerdata["lp-levels"] && mancerdata["lp-levels"].values["multiclass"] ? mancerdata["lp-levels"].values["multiclass"] : multiclass;
- set["multiclass_initial"] = multiclass;
-
- for (x = 1; x <= 3; x++) {
- const x1 = x + 1;
- if(previous[`multiclass${x}_flag`] === "1") {
- set[`class${x1}`] = "Classes:" + previous[`multiclass${x}`];
- set[`class${x1}_currentlevel`] = previous[`multiclass${x}_lvl`];
- update[`class${x1}_selector`] = `
${previous[`multiclass${x}`]} `;
- if (previous[`multiclass${x}_subclass`]) {
- set[`class${x1}_subclass`] = "Subclasses:" + previous[`multiclass${x}_subclass`];
- update[`subclass${x1}_selector`] = `
` + previous[`multiclass${x}_subclass`] + `
`;
- };
- levelclass.push(`class${x1}`);
- } else {
- set[`class${x1}_currentlevel`] = 0;
- };
-
- //This is handling classes that have been multiclassed into while in the leveler
- if (mancerdata["lp-levels"] && mancerdata["lp-levels"].values[`class${x1}`] && parseInt(mancerdata["lp-levels"].values[`class${x1}_addlevel`]) > 0 && !levelclass.includes(`class${x1}`)) {
- levelclass.push(`class${x1}`);
- };
- };
-
- setAttrs(set, () => { update_hp(true, levelclass) });
- setCharmancerText(update);
-
- changeCompendiumPage("sheet-levels-info", classcompend);
-});
-
-on("mancerchange:class1 mancerchange:class2 mancerchange:class3 mancerchange:class4", function(eventinfo) {
- if(eventinfo.sourceType !== "worker") deleteCharmancerData(["lp-choices", "lp-asi", "lp-spells", "lp-summary"]);
- const mancerdata= getCharmancerData();
- const leveldata = mancerdata["lp-levels"];
- const levelclass= eventinfo.sourceAttribute;
- const previous = mancerdata["lp-welcome"].values["previous_attributes"] ? JSON.parse(mancerdata["lp-welcome"].values["previous_attributes"]) : {};
-
- getCompendiumPage(eventinfo.newValue, function(p) {
- p = removeDuplicatedPageData(p);
- const data = p.data;
- const class_name = eventinfo.newValue && eventinfo.newValue.split(":").length > 1 && eventinfo.newValue.split(":")[0] === "Classes" ? eventinfo.newValue.split(":")[1] : false;
- const subclass_name = data["Subclass Name"];
- let set = {};
- let update = {};
-
- if (levelclass === "class1" && (!previous["custom_class"] || previous["custom_class"] == 0)) {
- set[`${levelclass}_addlevel`] = leveldata.values[`${levelclass}_addlevel`] ? leveldata.values[`${levelclass}_addlevel`] : 1;
- } else {
- set[`${levelclass}_addlevel`] = leveldata.values[`${levelclass}_addlevel`] ? leveldata.values[`${levelclass}_addlevel`] : 0;
- };
-
- set[`${levelclass}_hitdie`] = data["Hit Die"];
- update[`sub${levelclass}_name`] = `
${subclass_name} `;
-
- //Need to add a check here if a previous subclass value exists, skip this part if so.
- if(class_name) {
- var subOptions = {show_source: true};
- let reset = {};
- reset[levelclass + "_subclass"] = "
Choose ";
- //setCharmancerText(reset)
-
- (eventinfo.sourceType != "player") ? subOptions.silent = true : subOptions.selected = "";
-
- setCharmancerOptions(levelclass + "_subclass","Category:Subclasses data-Parent:" + class_name, subOptions, function(values) {
- });
- };
-
- const presets = [leveldata.values.class1, leveldata.values.class2, leveldata.values.class3, leveldata.values.class4];
- for (x = 2; x <= 4; x++) {
- disableCharmancerOptions(`class${x}`, presets);
- };
-
- setCharmancerText(update);
- setAttrs(set, function() {
- let set = {};
- set[eventinfo.sourceAttribute] = eventinfo.newValue;
- setAttrs(set, {silent: true});
- });
- });
-});
-
- //Trigger a change event when subclass changes
-["class1", "class2", "class3", "class4"].forEach(levelclass => {
- on(`mancerchange:${levelclass}_subclass`, (eventinfo) => {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"].values;
- const repeating = mancerdata["lp-levels"].repeating || [];
- let set = {};
-
- if(eventinfo.sourceType !== "worker") deleteCharmancerData(["lp-choices", "lp-asi", "lp-spells", "lp-summary"]);
- getCompendiumPage(eventinfo.newValue, function(data) {
- data = removeDuplicatedPageData(data);
- updateClassLevel(undefined, eventinfo.sourceAttribute.slice(0, 6));
- });
-
- //This will update the results inputs with new hp values if the subclass is Draconic
- if (eventinfo.sourceType !== "worker") {
- const newValue = (eventinfo.newValue) ? eventinfo.newValue : " ";
- const previousValue = (eventinfo.previousValue) ? eventinfo.previousValue : " ";
- let repids = [], updateArray = [];
- _.each(repeating, (repid) => {
- if (repid.includes(`_${levelclass}-`)) { updateArray.push(repid); };
- });
- _.each(updateArray, (repid) => {
- if (newValue.includes("Draconic Bloodline") || previousValue.includes("Draconic Bloodline")) { repids.push(repid); };
- });
-
- if (repids.length > 0) {
- updateButtons(levelclass, repids);
- updateResults(levelclass, repids, eventinfo);
- };
- };
-
- setAttrs(set);
- });
-});
-
-on("mancerchange:class1_addlevel mancerchange:class2_addlevel mancerchange:class3_addlevel mancerchange:class4_addlevel", function(eventinfo) {
- if(eventinfo.sourceType !== "worker") deleteCharmancerData(["lp-choices", "lp-asi", "lp-spells", "lp-summary"]);
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"];
- const levelclass = eventinfo.sourceAttribute.slice(0, 6);
- const classlevel = (parseInt(eventinfo.newValue) || 0) + (parseInt(leveldata.values[`${levelclass}_currentlevel`]) || 0);
- const subclasslevel = (leveldata.data[`${levelclass}`] && leveldata.data[`${levelclass}`]["data-Subclass Level"]) ? parseInt(leveldata.data[`${levelclass}`]["data-Subclass Level"]) : 3;
- let set = {};
- let update = {};
- if(eventinfo.currentStep === "lp-levels") updateClassLevel(mancerdata, levelclass);
-
- set[`${levelclass}_classlevel`] = classlevel;
- if (classlevel >= subclasslevel) {
- update[`sub${levelclass}_warning`] = ``;
- showChoices([`sub${levelclass}`]);
- } else {
- update[`sub${levelclass}_warning`] = `
Subclass chosen at level ${subclasslevel}. Your total level is ${classlevel}.
`;
- hideChoices([`sub${levelclass}`]);
- };
-
- const level = (leveldata.values[`${levelclass}_currentlevel`] === undefined) ? 0 : leveldata.values[`${levelclass}_currentlevel`];
- update[`${levelclass}_update`] = `level ${level} + `;
- update[`${levelclass}_tot`] = `= level ${classlevel}`;
-
- setCharmancerText(update);
- setAttrs(set);
-});
-
-const updateClassLevel = function(mancerdata, levelclass) {
- mancerdata = mancerdata || getCharmancerData();
- const leveling = getLevelingData(mancerdata);
- const blobs = getAllLpBlobs(mancerdata, true);
- const spells = getNewPowers(mancerdata, leveling, blobs);
- let set = {};
- let update = {};
- let asi = false;
-
- for(let x = 0; x <= 4; x++) {
- update["class" + x + "_features"] = "";
- update["subclass" + x + "_features"] = "";
- }
-
- _.each(leveling, function(thislevel) {
- _.each(["", "sub"], function(prefix) {
- let thiskey = "class" + thislevel.classnumber;
- let final = [];
- if(prefix === "sub") thiskey += "_subclass";
- _.each(blobs.names[thiskey], function(blobname) {
- if(blobname.substr(0,30) == "Ability Score Increase - Level") {
- asi = true;
- final.push("Ability Score Increase");
- } else if ((thislevel[prefix + "class"].blobs[blobname].Title || thislevel[prefix + "class"].blobs[blobname].Description || thislevel[prefix + "class"].blobs[blobname].Traits) && !thislevel[prefix + "class"].blobs[blobname].Group) {
- final.push(thislevel[prefix + "class"].blobs[blobname].Title || blobname);
- }
- });
- update[prefix + "class" + thislevel.classnumber + "_features"] = _.uniq(final).join(", ");
- });
- });
-
- set.asi = asi.toString();
- set.spells = spells.toString();
-
- setCharmancerText(update);
- setAttrs(set, () => {
- update_hp(false, [`${levelclass}`]);
- recalcButtons(undefined, "lp-levels");
- });
-};
-
-//Build a function to update the level & class each time they change
-on("mancerchange:class1_classlevel mancerchange:class2_classlevel mancerchange:class3_classlevel mancerchange:class4_classlevel", function(eventinfo) {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"];
- const class1levels = parseInt(leveldata.values["class1_classlevel"]) || 0, class2levels = parseInt(leveldata.values["class2_classlevel"]) || 0, class3levels = parseInt(leveldata.values["class3_classlevel"]) || 0, class4levels = parseInt(leveldata.values["class4_classlevel"]) || 0;
- const characterlevel = class1levels + class2levels + class3levels + class4levels;
- let update = {};
- let set = {};
- let end = [];
-
- for (x = 1; x <= 4; x++) {
- let name = (leveldata.values[`class${x}`]) ? leveldata.values[`class${x}`].slice(8) : "";
- let lvl = parseInt(leveldata.values[`class${x}_classlevel`]) || 0;
- (lvl > 0 && x === 1) ? end.push(`${name} ${lvl}`) : (lvl > 0 && x > 1) ? end.push(` ${name} ${lvl}`) : false;
- };
-
- update["levels_message"] = `
Character will be level ${characterlevel} (${end})
`;
- set[`characterlevel`] = characterlevel;
-
- setAttrs(set);
- setCharmancerText(update);
-});
-
-const recalcHpByLevel = (section) => {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"].values;
- const repeating = mancerdata["lp-levels"].repeating || [];
- let set = {};
- const sections = section ? [section] : ["class1", "class2", "class3", "class4"];
-
- _.each(sections, (levelclass) => {
- let thishp = 0;
- let first = true;
- let rollflag = "";
- _.each(repeating, function(repid) {
- if(repid.split("_")[2].split("-")[0] == levelclass && leveldata[`${repid}_result`]) {
- let thisflag = leveldata[`${repid}_rollflag`] || "average";
- thishp += parseInt(leveldata[`${repid}_result`]);
- if(first) {
- rollflag = thisflag;
- first = false;
- }
- if(rollflag !== thisflag) rollflag = "none";
- }
- });
- set[`${levelclass}_hp_flag`] = rollflag;
- set[`${levelclass}_addhp`] = thishp;
- });
- setAttrs(set, () => {recalcLpData()});
-};
-
-const update_hp = (firstTime, levelclass) => {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"].values;
- const repeating = mancerdata["lp-levels"].repeating || [];
-
- const updateByLevel = (firstTime, levelclass) => {
- _.each(levelclass, (levelclass) => {
- const current = leveldata[`${levelclass}_currentlevel`] ? parseInt(leveldata[`${levelclass}_currentlevel`]) : 0,
- addlevel = leveldata[`${levelclass}_addlevel`] ? parseInt(leveldata[`${levelclass}_addlevel`]) : 0;
- let levelarray = [], addarray = [], removearray = [], existing = [];
-
- for(let x = current+1; x<=current+addlevel; x++) {
- levelarray.push(`${levelclass}-${x}`);
- }
- addarray = levelarray;
- if(!firstTime) {
- _.each(repeating, function(id) {
- addarray = _.without(addarray, id.split("_")[2]);
- });
- }
- _.each(repeating, function(id) {
- if(id.split("_")[2].split("-")[0] == levelclass && !levelarray.includes(id.split("_")[2]) && !existing.includes(id.split("_")[2])) {
- removearray.push(id);
- existing.push(id.split("_")[2]);
- };
- });
-
- if(addarray.length > 0) {
- const last = addarray[addarray.length - 2];
- let set = {}, update = {}, rowid = "", repids = [];
- _.each(repeating, (repid) => {
- if(repid.split("_")[2] == `${levelclass}hprow`) rowid = repid;
- });
- _.each(addarray, (repname) => {
- addRepeatingSection(rowid, "hpbylevel", repname, function(repid) {
- repids.push(repid);
- if (repid.includes(last) || addarray.length == 1) {
- updateResults(levelclass, repids);
- updateButtons(levelclass, repids);
- };
- update[`${repid} label`] = `Level ${_.last(repname.split("-"))}`;
- if(repname == _.last(addarray)) {
- setCharmancerText(update);
- setAttrs(set, () => {
- clearRepeatingSectionById(removearray, () => {
- recalcHpByLevel(levelclass);
- });
- });
- }
- });
- });
- } else {
- clearRepeatingSectionById(removearray, () => {
- recalcHpByLevel(levelclass);
- });
- };
- });
- };
-
- if(firstTime) {
- addRepeatingSection("class1_by-levels", "row", "class1hprow", function() {
- addRepeatingSection("class2_by-levels", "row", "class2hprow", function() {
- addRepeatingSection("class3_by-levels", "row", "class3hprow", function() {
- addRepeatingSection("class4_by-levels", "row", "class4hprow", function() {
- updateByLevel(true, levelclass);
- });
- });
- });
- });
- } else {
- updateByLevel(false, levelclass);
- };
-};
-
-const updateButtons = (levelclass, repids) => {
- getAttrs(["licensedsheet"], function(v) {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"].values;
- const addlevel = leveldata[`${levelclass}_addlevel`] ? parseInt(leveldata[`${levelclass}_addlevel`]) : 0;
- const hitdie = leveldata[`${levelclass}_hitdie`];
- let average = getDieAvg(hitdie), set = {}, bonus = hpBonus(levelclass), hpbonus = bonus[0], bonusSource = bonus[1];
- const templateBonus = (hpbonus > 0) ? `+${hpbonus}[${bonusSource}]` : "";
- const licensedsheet = (v.licensedsheet && v.licensedsheet === "1") ? "licensedsheet" : "";
-
- _.each(repids, (repid) => {
- set[`roll_${repid}_rollhp`] = `@{wtype}&{template:mancerhproll} {{title=Roll for HP Level ${_.last(repid.split(`${levelclass}-`))}}} {{r1=[[1${hitdie}${templateBonus}]]}} {{licensedsheet=${licensedsheet}}}`;
- set[`roll_${repid}_averagehp`] = `@{wtype}&{template:mancerhproll} {{title=Average for HP Level ${_.last(repid.split(`${levelclass}-`))}}} {{a1=[[${average}${templateBonus}]]}} {{licensedsheet=${licensedsheet}}}`;
-
- if (addlevel && hitdie) {
- let dice = [];
- //Set the roll buttons
- for (x = 1; x <= addlevel; x++) { dice.push(`{{r${x}=[[1${hitdie}${templateBonus}]]}}`); };
- set[`roll_${levelclass}_rollhp`] = `@{wtype}&{template:mancerhproll} {{title=Roll for HP}} ` + dice.join()
-
- //Set the average hp button
- set[`roll_${levelclass}_averagehp`] = `@{wtype}&{template:mancerhproll} {{title=Average for HP}}{{a1=[[${average}${templateBonus}]]}} {{licensedsheet=${licensedsheet}}}`
- };
- });
-
- setAttrs(set);
- });
-};
-
-const hpBonus = (levelclass) => {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"].values;
-
- //HP Bonus from subclass hp mods like Draconic Bloodline for Sorcerers
- const prev_repeat = JSON.parse(mancerdata["lp-welcome"].values["previous_repeating"]), hpmod = prev_repeat["hpmod"], subclass = leveldata[`${levelclass}_subclass`];;
- let hpbonus = 0, bonusSource = [];
- _.each(hpmod, (mod) => {
- if (mod["levels"] === "base" && subclass && subclass.includes(mod["source"])) {
- bonusSource.push(mod["source"]);
- hpbonus += parseInt(mod["mod"]);
- };
- });
-
- //Multiclassing into Sorcerer Draconic needs to update buttons
- if (subclass && subclass.includes("Draconic Bloodline") && !bonusSource.includes("Draconic Bloodline")) {
- bonusSource.push("Draconic Bloodline");
- hpbonus += parseInt(1);
- };
-
- return [hpbonus, bonusSource];
-};
-
-const updateResults = (levelclass, repids, eventinfo) => {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"].values;
- const hitdie = leveldata[`${levelclass}_hitdie`];
- let average = getDieAvg(hitdie), bonus = hpBonus(levelclass), hpbonus = bonus[0], set = {};
-
- _.each(repids, (repid) => {
- console.log(repid);
- if (!leveldata[`${repid}_result`]) {
- set[`${repid}_result`] = parseInt(average) + parseInt(hpbonus);
- } else if (eventinfo && (eventinfo.newValue).includes("Draconic Bloodline")) {
- set[`${repid}_result`] = parseInt(leveldata[`${repid}_result`]) + parseInt(hpbonus);
- } else if (eventinfo && (eventinfo.previousValue).includes("Draconic Bloodline")) {
- set[`${repid}_result`] = parseInt(leveldata[`${repid}_result`]) - 1;
- } else {
- false
- };
- });
-
- setAttrs(set);
-};
-
-const getDieAvg = (hitdie) => {
- if(!hitdie) return 0;
- const size = hitdie.slice(1);
- let num = [], sum = 0;
-
- //Push an array of numbers
- for(x = 1; x <= size; x++) { num.push(x); };
-
- //Add up the nummbers above
- for(i = 0; i < num.length; i++) { sum += num[i]; };
-
- return Math.ceil(sum / num.length);
-};
-
-//Roll & Average buttons inside the repeating hp section for each level
-["class1", "class2", "class3", "class4"].forEach(levelclass => {
- on(`mancerroll:repeating_${levelclass}hprow`, (eventinfo) => {
- const source = eventinfo.sourceAttribute, flag = source.includes("rollhp") ? "roll" : "average";
- let set = {};
-
- set[`${eventinfo.sourceSection}_result`] = eventinfo.roll[0].result;
- set[`${eventinfo.sourceSection}_rollflag`] = flag;
- setAttrs(set, () => {recalcHpByLevel()})
- });
-});
-
-//Roll & Average top level buttons for each class
-["class1", "class2", "class3", "class4"].forEach(levelclass => {
- on(`mancerroll:${levelclass}_rollhp mancerroll:${levelclass}_averagehp`, (eventinfo) => {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"].values;
- const repeating = mancerdata["lp-levels"].repeating || [];
- const source = eventinfo.sourceAttribute, flag = source.includes("rollhp") ? "roll" : "average";
- let set = {}, sum = 0, rows = "", num = 0;
-
- repeating.forEach(row => {
- if (row.includes(`${levelclass}-`) && source.includes("rollhp")) {
- set[row + "_result"] = eventinfo.roll[`${num}`].result;
- set[row + "_rollflag"] = flag;
- num += 1;
- } else if (row.includes(`${levelclass}-`) && source.includes("average")) {
- set[row + "_result"] = eventinfo.roll[0].result;
- set[row + "_rollflag"] = flag;
- } else {
- false
- };
- });
-
- //Add up the results for rollhp or multiply the average option by added levels
- if (source.includes("rollhp")) {
- _.each(eventinfo.roll, function(roll) {
- sum += parseInt(roll.result);
- });
- } else {
- sum = parseInt(eventinfo.roll[0].result) * leveldata[`${levelclass}_addlevel`];
- };
-
- // Set addhp to the total
- set[`${levelclass}_addhp`] = sum;
-
- //Set hp_flag to be roll or average so the CSS will highlight the appropriate button
- set[`${levelclass}_hp_flag`] = flag;
-
- setAttrs(set, function() { recalcLpData(); });
- });
-});
-
-on("clicked:multiclass_add clicked:multiclass_remove", function(eventinfo) {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"];
- const levelclass = "class" + (parseInt(leveldata.values["multiclass"]) + 1);
- const repeating = mancerdata["lp-levels"].repeating || [];
- let set = {};
- let update = {};
-
- if (eventinfo.sourceAttribute === "multiclass_add") {
- (leveldata.values["multiclass"] < 3) ? set["multiclass"] = parseInt(leveldata.values["multiclass"]) + 1 : false;
- update["add_multiclass"] = `
+ `;
- //set[`${levelclass}_addlevel`] = 1;
- } else {
- if (leveldata.values["multiclass"] > leveldata.values["multiclass_initial"]) {
- const multiclass = parseInt(leveldata.values["multiclass"]);
- let rows = "";
-
- set["multiclass"] = multiclass - 1;
- update["add_multiclass"] = `
+ `;
-
- repeating.forEach(row => {
- if (row.includes(`${levelclass}-`)) {
- set[row + "_result"] = "";
- };
- });
-
- set[`${levelclass}_addhp`] = 0;
- set[`${levelclass}_hp_flag`] = "";
- } else {
- false
- };
- };
-
- setAttrs(set, function() { recalcLpData(); });
- setCharmancerText(update);
-});
-
-on("mancerchange:class1_addhp mancerchange:class2_addhp mancerchange:class3_addhp mancerchange:class4_addhp", function(eventinfo) {
- if (eventinfo.sourceType === "player") {
- const mancerdata = getCharmancerData(), levelclass = eventinfo.sourceAttribute.slice(0, 6);
- const repeating = mancerdata["lp-levels"].repeating || [];
- let set = {};
-
- repeating.forEach(row => {
- if (row.includes(`${levelclass}-`)) {
- set[row + "_result"] = "";
- };
- });
-
- set[`${levelclass}_hp_flag`] = "";
-
- setAttrs(set);
- };
-});
-
-on("mancerchange:multiclass", function () {
- const mancerdata = getCharmancerData();
- const leveldata = mancerdata["lp-levels"];
- const tot = isNaN(parseInt(leveldata.values["multiclass"])) ? 1 : parseInt(leveldata.values["multiclass"]) + 1;
- let update = {};
- let presets = [];
-
- for(var x=1; x<=tot-1; x++) {
- if(leveldata.values["class" + x]) presets.push(_.last(leveldata.values["class" + x].split(":")))
- }
- setCharmancerOptions("class" + tot, "Category:Classes", {disable: presets, category: "Classes"});
- update["multiclass_message"] = `
Multiclass (${tot}/4) `;
- setCharmancerText(update);
-});
-
-on("clicked:class1 clicked:class2 clicked:class3 clicked:class4 clicked:class1_subclass clicked:class2_subclass clicked:class3_subclass clicked:class4_subclass", function(eventinfo) {
- const mancerdata = getCharmancerData();
- const source = eventinfo.sourceAttribute;
- const page = mancerdata["lp-levels"].values[`${source}`];
-
- changeCompendiumPage("sheet-levels-info", page);
- getCompendiumPage(page, function(p) {
- });
-});
-
-var getLevelingData = function(mancerdata) {
- mancerdata = mancerdata || getCharmancerData();
- var leveling = [];
- if(!mancerdata["lp-levels"]) return leveling;
- var multiclass = mancerdata["lp-levels"].values.multiclass ? parseInt(mancerdata["lp-levels"].values.multiclass) : 0;
- for(var x=1; x<=multiclass + 1; x++) {
- if(mancerdata["lp-levels"].data["class" + x] && mancerdata["lp-levels"].values["class" + x + "_addlevel"] && mancerdata["lp-levels"].values["class" + x + "_addlevel"] != "0") {
- var thisclass = {};
- var maxspell = 0;
- thisclass.class = mancerdata["lp-levels"].data["class" + x];
- thisclass.subclass = mancerdata["lp-levels"].data["class" + x + "_subclass"] || {};
- thisclass.classname = _.last(mancerdata["lp-levels"].values["class" + x].split(":"));
- thisclass.subclassname = mancerdata["lp-levels"].values["class" + x + "_subclass"] ? _.last(mancerdata["lp-levels"].values["class" + x + "_subclass"].split(":")) : "";
- thisclass.currentlevel = mancerdata["lp-levels"].values["class" + x + "_currentlevel"] ? parseInt(mancerdata["lp-levels"].values["class" + x + "_currentlevel"]) : 0;
- thisclass.addlevel = parseInt(mancerdata["lp-levels"].values["class" + x + "_addlevel"]);
- thisclass.addhp = mancerdata["lp-levels"].values["class" + x + "_addhp"] ? parseInt(mancerdata["lp-levels"].values["class" + x + "_addhp"]) : 0;
- thisclass.classnumber = x;
- if(thisclass.subclass["Spellcasting Ability"]) {
- thisclass.spellcasting = thisclass.subclass["Spellcasting Ability"];
- } else if(thisclass.class["Spellcasting Ability"]) {
- thisclass.spellcasting = thisclass.class["Spellcasting Ability"];
- }
- _.each(thisclass.class.blobs, function(blob) {
- if(blob["Spell Slots"] && parseInt(blob.Level) <= (thisclass.currentlevel + thisclass.addlevel)) {
- _.each(JSON.parse(blob["Spell Slots"]), function(slots, name) {
- if(parseInt(_.last(name.split(" "))) > maxspell) maxspell = parseInt(_.last(name.split(" ")));
- });
- }
- });
- thisclass.maxspell = maxspell;
- leveling.push(thisclass);
- }
- }
- return leveling;
-};
-
-var getLpRaceData = function(mancerdata, leveldata) {
- mancerdata = mancerdata || getCharmancerData();
- leveldata = leveldata || getLevelingData(mancerdata);
- let results = {};
- let currentlevel = 0;
- let addlevel = 0;
- _.each(leveldata, function(level) {
- addlevel += level.addlevel;
- currentlevel += level.currentlevel;
- });
- currentlevel = currentlevel === 0 ? 1 : currentlevel;
- _.each(["race", "background"], function(section) {
- results[section] = {addlevel: addlevel, currentlevel: currentlevel};
- results[section][section] = mancerdata["lp-welcome"].data["lp-" + section] || {};
- results[section]["sub" + section] = mancerdata["lp-welcome"].data["lp-sub" + section] || {};
- results[section].type = section;
- results[section].name = _.last(mancerdata["lp-welcome"].values["lp-" + section].split(":")) || "";
- results[section].name += mancerdata["lp-welcome"].values["lp-sub" + section] ? " - " + _.last(mancerdata["lp-welcome"].values["lp-sub" + section].split(":")) : "";
- });
- return results;
-};
-
-var getLpBlobs = function(data, include_asi, verbose) {
- const type = data.type || "class";
- var asi = type == "class" ? data[type]["data-Ability Score Levels"] : [];
- var allblobs = {};
- allblobs[type] = {};
- allblobs["sub" + type] = {};
- _.times(data.addlevel, function(x) {
- var thislevel = data.currentlevel + x + 1;
- allblobs[type] = _.extend(allblobs[type], filterBlobs(data[type].blobs, {"Level": "" + thislevel, multiclass: true}));
- allblobs["sub" + type] = _.extend(allblobs["sub" + type], filterBlobs(data["sub" + type].blobs, {"Level": "" + thislevel, multiclass: true}));
- if(asi.includes("" + thislevel) && include_asi) {
- allblobs[type]["Ability Score Increase - Level " + thislevel] = {Level: thislevel, parentSection: type};
- data[type].blobs["Ability Score Increase - Level " + thislevel] = {
- Level: thislevel,
- Title: ("Ability Score Increase - Level " + thislevel)
- };
- }
- });
- allblobs[type] = _.extend(allblobs[type], filterBlobs(data[type].blobs, {"Level": "every", multiclass: true}));
- allblobs["sub" + type] = _.extend(allblobs["sub" + type], filterBlobs(data["sub" + type].blobs, {"Level": "every", multiclass: true}));
- var remove = {};
- remove[type] = [];
- remove["sub" + type] = [];
- //Figure out which blobs are just the same feature at a different level, add them to a list to remove (unless we're useing the verbose option)
- if(!verbose) {
- _.each(allblobs, function(blobs, section) {
- _.each(blobs, function(blob, name) {
- var basename = name.split("(")[0];
- blob.Level = parseInt(blob.Level);
- if(basename.trim().toLowerCase() == "spell slots") {
- remove[section].push(name);
- } else if(basename.trim().toLowerCase() != "proficiencies") {
- _.each(allblobs, function(otherblobs, othersection) {
- _.each(otherblobs, function(otherblob, othername) {
- if(name != othername && basename == othername.split("(")[0]) {
- if(blob.Level > parseInt(otherblob.Level)) {
- remove[section].push(othername);
- } else {
- remove[section].push(name);
- }
- }
- })
- });
- }
- });
- });
- }
- //remove any blobs that are the same feature
- _.each(remove, function(removeArray, section) {
- _.each(_.uniq(removeArray), function(thisblob) {
- delete allblobs[section][thisblob];
- });
- });
- //here we build the final list of blobs that will be added
- var filteredblobs = {};
- filteredblobs[type] = [];
- filteredblobs["sub" + type] = [];
- _.each(allblobs, function(blobs, section) {
- _.each(blobs, function(blob, name) {
- var thisblob = {
- Level: blob.Level,
- name: name
- };
- filteredblobs[section].push(thisblob);
- });
- });
- _.each(filteredblobs, function(bloblist) {
- bloblist = _.sortBy(bloblist, "Level");
- })
- filteredblobs.allblobs = _.extend(data[type].blobs, data["sub" + type].blobs);
- return filteredblobs;
-};
-
-var getAllLpBlobs = function(mancerdata, include_asi) {
- const pickBlobs = function(theseblobs, allblobs, key, section) {
- blobs.names[key] = _.pluck(theseblobs, "name") || [];
- if(mancerdata["lp-choices"]) {
- _.each(mancerdata["lp-choices"].values, function(value, id) {
- if((value + "").split(":")[0] == "Blob" && id.split("_")[2].split("--")[0] == section) {
- blobs.names[key].push(value.split(":")[1]);
- };
- });
- };
- _.each(blobs.names[key], function(blobname){
- _.each(filterBlobs(allblobs, {"name": blobname, multiclass: true}), function(blob, blobname) {
- blobs.all.push(blob);
- blobs.sorted[key] = blobs.sorted[key] ? blobs.sorted[key] : [];
- blobs.sorted[key].push(blob);
- });
- });
- };
- mancerdata = mancerdata || getCharmancerData();
- const leveldata = getLevelingData(mancerdata);
- const racedata = getLpRaceData(mancerdata, leveldata);
- var blobs = {all: [], sorted: {}, names: {}};
- _.each(leveldata, function(level) {
- var name = "class" + level.classnumber;
- var theseblobs = getLpBlobs(level, include_asi, true);
- pickBlobs(theseblobs.class, level.class.blobs, name, "class-" + level.classnumber);
- if(level.subclass) {
- pickBlobs(theseblobs.subclass, level.subclass.blobs, name + "_subclass", "subclass-" + level.classnumber);
- };
- });
- _.each(racedata, function(level) {
- var name = level.type;
- var theseblobs = getLpBlobs(level, include_asi, true);
- pickBlobs(theseblobs[name], level[name].blobs, name, name);
- if(level["sub" + name]) {
- pickBlobs(theseblobs["sub" + name], level["sub" + name].blobs, "sub" + name, "sub" + name);
- };
- });
- return blobs;
-};
-
-on("page:lp-choices", function(eventinfo) {
- const resortBlobs = function(blobs, section) {
- _.each(blobs[section], function(x) { x.parentSection = section });
- _.each(blobs["sub" + section], function(x) { x.parentSection = "sub" + section});
- let filteredblobs = _.sortBy(blobs[section].concat(blobs["sub" + section]), "Level");
- let resorted = [];
- _.each(filteredblobs, function(blob) {
- if(blob.name.split(" ")[0] == "Proficiencies") {
- resorted.unshift(blob);
- } else {
- resorted.push(blob);
- }
- });
- return resorted;
- }
- const mancerdata = getCharmancerData();
- const leveling = getLevelingData(mancerdata);
- const racedata = getLpRaceData(mancerdata, leveling);
- _.each(racedata, function(data, section) {
- const blobs = getLpBlobs(data, true);
- const relevant = resortBlobs(blobs, section);
- if(relevant.length > 0) {
- addRepeatingSection("choices", "row", function(thisrow) {
- let update = {};
- update[thisrow] = "
" + removeExpansionInfo(data.name) + "";
- update[thisrow] += data.addlevel > 1 ? " Levels " + (data.currentlevel + 1) + " - " + (data.currentlevel + data.addlevel) : " Level " + (data.currentlevel + 1);
- update[thisrow] += " ";
- setCharmancerText(update);
- _.each(relevant, function(blob, y) {
- handleBlobs(blobs.allblobs, {
- filters: {multiclass: true},
- slide: "lp-choices",
- section: blob.parentSection + "--" + blob.Level,
- element: thisrow,
- thisblob: blob.name,
- maxlevel: data.currentlevel + data.addlevel,
- parent: section
- });
- if(y === (relevant.length -1)) {
- recalcLpData();
- }
- });
- });
- };
- });
- _.each(leveling, function(data) {
- var x = data.classnumber;
- var blobs = getLpBlobs(data, true);
- addRepeatingSection("choices", "row", function(classrow) {
- var classname = data.subclassname ? removeExpansionInfo(data.subclassname) + " " + removeExpansionInfo(data.classname) : removeExpansionInfo(data.classname);
- var update = {};
- update[classrow] = "
" + classname + "";
- update[classrow] += data.addlevel > 1 ? " Levels " + (data.currentlevel + 1) + " - " + (data.currentlevel + data.addlevel) : " Level " + (data.currentlevel + 1);
- update[classrow] += " ";
- setCharmancerText(update);
- resorted = resortBlobs(blobs, "class");
- _.each(resorted, function(blob, y) {
- handleBlobs(blobs.allblobs, {
- filters: {multiclass: true},
- slide: "lp-choices",
- section: blob.parentSection + "-" + x + "--" + blob.Level,
- element: classrow,
- thisblob: blob.name,
- maxlevel: data.currentlevel + data.addlevel,
- parent: "class" + data.classnumber + (blob.parentSection === "class" ? "" : "_subclass")
- });
- if(y === (resorted.length -1)) {
- recalcLpData();
- }
- });
- });
- });
- if(leveling[0] && leveling[0].classname) {
- changeCompendiumPage("sheet-class-info", "Classes:" + leveling[0].classname);
- }
-});
-
-on("page:lp-asi", function(eventinfo) {
- var mancerdata = getCharmancerData();
- var leveling = getLevelingData(mancerdata);
- var asis = [];
- var update = {};
- var multiclass = mancerdata["lp-levels"].values.multiclass ? parseInt(mancerdata["lp-levels"].values.multiclass) : 0;
- for(var x=1; x<=multiclass + 1; x++) {
- if(mancerdata["lp-levels"].data["class" + x]) {
- var thisclass = {};
- thisclass.class = mancerdata["lp-levels"].data["class" + x];
- thisclass.classname = _.last(mancerdata["lp-levels"].values["class" + x].split(":"));
- thisclass.currentlevel = parseInt(mancerdata["lp-levels"].values["class" + x + "_currentlevel"]);
- thisclass.addlevel = parseInt(mancerdata["lp-levels"].values["class" + x + "_addlevel"]);
- leveling["class" + x] = thisclass;
- }
- }
- _.each(leveling, function(data) {
- var asi = data.class["data-Ability Score Levels"];
- _.times(data.addlevel, function(x) {
- var thislevel = data.currentlevel + x + 1;
- if(asi.includes("" + thislevel)) {
- asis.push(data.classname + " Level " + thislevel);
- }
- });
- });
- _.each(asis, function(asi) {
- addRepeatingSection("choices", "asi-row", function(rowid) {
- update[rowid + " .sheet-title"] = "Ability Score Increase: " + removeExpansionInfo(asi);
- setCharmancerOptions(rowid + "_feat", "Category:Feats");
- updateAbilityLock(rowid);
- if(asi == _.last(asis)) {
- setCharmancerText(update);
- }
- })
- })
-});
-
-var getKnownLpPowers = function(mancerdata) {
- mancerdata = mancerdata || getCharmancerData();
- var leveldata = getLevelingData(mancerdata);
- var previousspells = mancerdata["lp-welcome"].values["spellinfo"] ? JSON.parse(mancerdata["lp-welcome"].values["spellinfo"]) : {};
- var spelldata = {};
- var totallevel = 0;
- var prevtotallevel = 0;
- _.each(previousspells, function(spell) {
- spelldata[spell.spellname] = {level: spell.spelllevel};
- if(spell.spellclass) spelldata[spell.spellname].spellclass = spell.spellclass;
- if(spell.spellclass && spell.spellclass.toLowerCase() == "racial") spelldata[spell.spellname].known = "Racial";
- if(spell.spellsource) spelldata[spell.spellname].known = spell.spellsource;
- });
- _.each(leveldata, function(level) {
- totallevel += level.currentlevel + level.addlevel;
- prevtotallevel += level.currentlevel;
- });
- //Gather known spells
- _.each(mancerdata, function(page, pagename) {
- if(pagename.split("-")[0] == "lp") {
- let choices = [];
- let choicepage = ["lp-welcome", "lp-levels"].includes(pagename) ? (mancerdata["lp-choices"] ? mancerdata["lp-choices"].values : []) : page.values;
- _.each(choicepage, function(val) {
- if((val + "").split(":")[0] === "Blob") choices.push(val.split(":")[1]);
- });
- _.each(page.data, function(data, dataname) {
- var thislevel = 0;
- var prevlevel = 0;
- var thisclass = {};
- if(dataname.substring(0,5) == "class") {
- thisclass = _.findWhere(leveldata, {classnumber: parseInt(dataname[5])});
- thislevel = thisclass ? thisclass.currentlevel + thisclass.addlevel : 0;
- prevlevel = 0;
- } else {
- thislevel = totallevel;
- prevlevel = prevtotallevel;
- }
- _.each(data.blobs, function(blob, blobname) {
- if(blob.Multiclass != "no" && ((parseInt(blob.Level) <= thislevel || blob.Level == "all") && !blob.Group) || choices.includes(blobname)) {
- if(blob.Powers) {
- var blobspells = JSON.parse(blob.Powers);
- _.each(blobspells, function(blobspell) {
- if(blobspell.Known) {
- _.each(blobspell.Known, function(spell) {
- spelldata[spell] = spelldata[spell] || {level: blobspell.Level};
- spelldata[spell].known = blobspell.Source || data.Category.substring(0, data.Category.length - 2);
- spelldata[spell].spellclass = thisclass.classname;
- if(dataname.substring(0,5) != "class") {
- spelldata[spell].known = data.Category.substring(0, data.Category.length - 1);
- spelldata[spell].spellclass = data.Category == "Races" ? "Racial" : data.Category.substring(0, data.Category.length - 1);
- }
- if(blobspell.Ability) {
- spelldata[spell].ability = blobspell.Ability;
- } else if(thisclass.class && thisclass.class["Spellcasting Ability"]) {
- spelldata[spell].ability = thisclass.class["Spellcasting Ability"];
- } else if (thisclass.subclass && thisclass.subclass["Spellcasting Ability"]) {
- spelldata[spell].ability = thisclass.subclass["Spellcasting Ability"];
- }
- });
- }
- });
- }
- }
- });
- });
- //Gater spells from class features
- _.each(page.values, function(value, name) {
- if(name.substr(-18) === "_utilityrow_spells") {
- console.log("UTILITYROW SPELLS!");
- console.log(JSON.parse(value));
- spelldata = _.extend(spelldata, JSON.parse(value));
- }
- });
- }
- });
- /**/
- return spelldata;
-};
-
-var getNewPowers = function(mancerdata, leveldata, blobs) {
- mancerdata = mancerdata || getCharmancerData();
- leveldata = leveldata || getCharmancerData();
- blobs = blobs || getAllLpBlobs(mancerdata, false);
- var result = false;
- _.each(leveldata, function(level) {
- var prevlevel = level.currentlevel;
- var thislevel = level.addlevel + prevlevel;
- var thisclass = {class: level.classname, number: level.classnumber, newlevel: thislevel, additional: []};
- var prevknown = 0;
- var currentknown = 0;
- var prevprimes = 0;
- var currentprimes = 0;
- var spelladd = 0;
- thisclass.newspells = 0;
- _.each(["class", "subclass"], function(section) {
- if(level[section]) {
- _.each(level[section].blobs, function(blob) {
- if(blob.Level == thislevel) {
- if(blob["Powers Known"]) {
- currentknown = parseInt(blob["Powers Known"]);
- if(level.class["data-Spell Replace"]) result = true;
- }
- if(blob.Primes) {
- thisclass.primes = true;
- currentprimes = parseInt(blob.Primes);
- }
- if(blob["Powers Prepared"]) {
- result = true;
- }
- }
- if(blob.Level == prevlevel || (prevlevel === 0 && blob.Level == 1)) {
- if(blob["Powers Known"]) {
- prevknown = prevlevel === 0 ? 0 : parseInt(blob["Powers Known"]);
- if(prevlevel === 0) thisclass.newspells = parseInt(blob["Powers Known"]);
- }
- if(blob.Primes) {
- thisclass.primes = true;
- prevprimes = prevlevel === 0 ? 0 : parseInt(blob.Primes);
- }
- }
- if(level[section]["data-Spell Add"]) {
- spelladd = parseInt(level[section]["data-Spell Add"]);
- }
- });
- }
- });
- if(spelladd) {
- thisclass.newspells += prevlevel === 0 ? spelladd * (thislevel - prevlevel -1) : spelladd * (thislevel - prevlevel);
- } else {
- thisclass.newspells = currentknown - prevknown;
- }
- thisclass.newprimes = currentprimes - prevprimes;
- _.each(["", "_subclass"], function(section) {
- if(blobs.sorted[`class${level.classnumber}${section}`]) {
- _.each(blobs.sorted[`class${level.classnumber}${section}`], function(blob) {
- if(blob.Powers) {
- let spells = JSON.parse(blob.Powers);
- _.each(spells, function(spell) {
- if(spell.Choose) {
- result = true;
- }
- });
- }
- });
- }
- });
- if(thisclass.newprimes || thisclass.newspells) result = true;
- });
- return result;
-};
-
-on("page:lp-spells", function(eventinfo) {
- var mancerdata = getCharmancerData();
- var queries = [];
- var blobs = getAllLpBlobs(mancerdata, false);
- var leveldata = getLevelingData(mancerdata);
- var classes = [];
- var knownprimes = 0;
- var knownspells = 0;
- var newprimes = 0;
- var newspells = 0;
- var replace = 0;
- var totallevel = 0;
- var spellmaxlevel = 0;
- var prepared = true;
- var prevspells = mancerdata["lp-welcome"].values["spellinfo"] ? JSON.parse(mancerdata["lp-welcome"].values["spellinfo"]) : {};
- var spelldata = getKnownLpPowers(mancerdata);
- var abilities = getAbilityTotals(mancerdata, blobs);
- _.each(spelldata, function(spell, spellname) {
- if(spell.level == "prime") {
- knownprimes++;
- } else {
- knownspells++;
- }
- });
- recalcLpData(blobs);
- //Gather spell data about each class
- _.each(leveldata, function(level) {
- var prevlevel = level.currentlevel;
- var thislevel = level.addlevel + prevlevel;
- var thisclass = {class: level.classname, number: level.classnumber, newlevel: thislevel, additional: []};
- var toSwap = level.class["data-Spell Replace"] ? parseInt(level.class["data-Spell Replace"]) : 0;
- var prevknown = 0;
- var currentknown = 0;
- var prevprimes = 0;
- var currentprimes = 0;
- var spelladd = 0;
- thisclass.list = [thisclass.class];
- totallevel += thislevel;
- thisclass.newspells = 0;
- _.each(["class", "subclass"], function(section) {
- if(level[section]) {
- if(level[section]["data-Spell List"]) thisclass.list = [level[section]["data-Spell List"]];
- if(level[section]["Spellcasting Ability"]) thisclass.ability = level[section]["Spellcasting Ability"];
- _.each(level[section].blobs, function(blob) {
- if(blob.Level == thislevel) {
- if(blob["Spell Slots"]) {
- var slots = JSON.parse(blob["Spell Slots"]);
- thisclass.maxlevel = JSON.parse(_.last(_.last(_.keys(slots).sort()).split(" ")));
- spellmaxlevel = Math.max(thisclass.maxlevel, spellmaxlevel);
- }
- if(blob["Powers Known"]) {
- currentknown = parseInt(blob["Powers Known"]);
- }
- if(blob.Primes) {
- thisclass.primes = true;
- currentprimes = parseInt(blob.Primes);
- }
- if(blob["Powers Prepared"]) {
- var splitted = blob["Powers Prepared"].split("+").map((x) => {return x.trim()});
- thisclass.prepared = 0;
- _.each(splitted, function(term, x) {
- if(isNaN(parseInt(term))) {
- thisclass.prepared += abilities[term.toLowerCase() + "_mod"] ? abilities[term.toLowerCase() + "_mod"] : 0;
- } else {
- thisclass.prepared += parseInt(term);
- }
- });
- thisclass.prepared = Math.max(thisclass.prepared, 1);
- }
- }
- if(blob.Level == prevlevel || (prevlevel === 0 && blob.Level == 1)) {
- if(blob["Powers Known"]) {
- prevknown = prevlevel === 0 ? 0 : parseInt(blob["Powers Known"]);
- if(prevlevel === 0) thisclass.newspells = parseInt(blob["Powers Known"]);
- }
- if(blob.Primes) {
- thisclass.primes = true;
- prevprimes = prevlevel === 0 ? 0 : parseInt(blob.Primes);
- if(knownprimes < prevprimes) prevprimes = knownprimes;
- }
- }
- if(blob.Level == "every" || blob.Level == thislevel) {
- if(blob["Additional Spell List"]) thisclass.list.push(blob["Additional Spell List"]);
- }
- if(level[section]["data-Spell Add"]) {
- spelladd = parseInt(level[section]["data-Spell Add"]);
- }
- });
- }
- });
- if(spelladd) {
- thisclass.newspells += prevlevel === 0 ? spelladd * (thislevel - prevlevel -1) : spelladd * (thislevel - prevlevel);
- } else {
- thisclass.newspells = currentknown - prevknown;
- }
- if(thisclass.prepared) thisclass.newspells = thisclass.prepared;
- thisclass.newprimes = currentprimes - prevprimes;
- thisclass.replace = toSwap * (thislevel - prevlevel);
- _.each(["", "_subclass"], function(section) {
- if(blobs.sorted[`class${level.classnumber}${section}`]) {
- _.each(blobs.sorted[`class${level.classnumber}${section}`], function(blob) {
- if(blob.Powers) {
- let spells = JSON.parse(blob.Powers);
- _.each(spells, function(spell) {
- if(spell.Choose && spell.Level === "0") {
- thisclass.newprimes += parseInt(spell.Choose);
- }
- });
- }
- });
- }
- });
- if(thisclass.newprimes || thisclass.newspells) classes.push(thisclass);
- });
- if(classes.length > 0) {
- var existinglist = _.pluck(prevspells, "spellname");
- var knownlist = _.keys(spelldata);
- //Look through all the data to see if there's any expanded lists
- _.each(mancerdata, function(page, pagename) {
- if(pagename.split("-")[0] == "lp") {
- _.each(page.data, function(data, dataname) {
- var thislevel = 0;
- if(dataname.substring(0,5) == "class") {
- var thisclass = _.findWhere(leveldata, {classnumber: parseInt(dataname[5])});
- thislevel = thisclass ? thisclass.currentlevel + thisclass.addlevel : 0;
- } else {
- thislevel = totallevel;
- }
- _.each(data.blobs, function(blob, blobname) {
- if((parseInt(blob.Level) <= thislevel || blob.Level == "every") && blob.Multiclass != "no") {
- if(blob.Powers) {
- var blobspells = JSON.parse(blob.Powers);
- _.each(blobspells, function(thisspell) {
- if(parseInt(thisspell.Level) <= spellmaxlevel) {
- if(thisspell["Expanded List"]) {
- knownlist = knownlist.concat(thisspell["Expanded List"]);
- }
- }
- });
- }
- }
- });
- })
- }
- });
- if(knownlist) {
- queries.push("Category:Powers Name:" + knownlist.join("|"));
- }
- _.each(classes, function(thisclass) {
- if(thisclass.maxlevel || thisclass.newprimes) {
- newprimes += thisclass.newprimes || 0;
- newspells += thisclass.newspells;
- replace += thisclass.replace;
- if(!thisclass.prepared) prepared = false;
- thisquery = "Category:Powers Classes:*" + _.uniq(thisclass.list).join("|*") + " Level:";
- if(thisclass.primes) thisquery += "0|"
- for(var x = 1; x <= thisclass.maxlevel; x++) {
- thisquery += x;
- if(x != thisclass.maxlevel) thisquery += "|";
- }
- _.each(thisclass.additional, function(lvl) {
- thisquery += "|" + lvl;
- });
- queries.push(thisquery);
- }
- });
- var toSet = {};
- toSet.knownprimes = knownprimes;
- toSet.knownspells = knownspells;
- toSet.newprimes = newprimes;
- toSet.newspells = newspells;
- toSet.replace = replace;
- setAttrs(toSet);
- var update = {};
- update["spells-summary"] = "";
- if(newprimes != 0 || knownprimes != 0) update["spells-summary"] = "
";
- _.times(spellmaxlevel, function(x) {
- update["spells-summary"] += "
";
- });
- if(classes.length > 1) {
- update["primeinfo"] = "";
- _.each(classes, function(thisclass) {
- if(thisclass.newspells) {
- update["primeinfo"] += "
You can add " + thisclass.newprimes + " " + thisclass.class + " primes.
";
- }
- });
- }
- setCharmancerText(update);
- getCompendiumQuery(queries, (data) => {
- data = removeDuplicatedPageData(data);
- let byLevel = {};
- _.each(data, (spell) => {
- let classes = [];
- if (spell.data.Classes) {
- classes = spell.data.Classes;
- //Ravinca introduced Powers without Classes
- } else {
- ["class1", "class2", "class3", "class4"].forEach(levelclass => {
- //Get the class name out of values & confirm its a spellcaster using data Spellcasting Ability
- const name = (mancerdata["lp-levels"].values[`${levelclass}`]) ? mancerdata["lp-levels"].values[`${levelclass}`].split("Classes:")[1] : false;
- const ability =
- //Check if the class has a Spellcasting Ability attribute
- (mancerdata["lp-levels"].data[`${levelclass}`] && mancerdata["lp-levels"].data[`${levelclass}`]["Spellcasting Ability"]) ? true :
- //Check if the subclass has a Spellcasting Ability attribute
- (mancerdata["lp-levels"].data[`${levelclass}_subclass`] && mancerdata["lp-levels"].data[`${levelclass}_subclass`]["Spellcasting Ability"]) ? true :
- //Set to false if the class is not a spellcaster
- false;
- if (name && ability) {
- //Spell casters have thier class name pushed to the array above
- classes.push(name);
- };
- });
-
- if (classes.length > 0) {
- classes = classes.join(', ');
- };
- };
-
- /* This will set the information for populating the spell list */
- if (classes.length > 0) {
- byLevel[spell.data.Level] = byLevel[spell.data.Level] || [];
- byLevel[spell.data.Level].push({
- name: spell.name,
- classes: classes.split(",").map(x => x.trim()),
- level: parseInt(spell.data.Level)
- });
- };
- });
- addSpellSections(byLevel, {
- newspells: newspells,
- newprimes: newprimes,
- replace: replace,
- prepared: prepared,
- classes: classes,
- spelldata: spelldata,
- existinglist: existinglist
- });
- });
- }
-});
-
-const addSpellSections = function(byLevel, settings) {
- settings = settings || {};
- let newspells = settings.newspells || 0;
- let newprimes = settings.newprimes || 0;
- let replace = settings.replace || 0;
- let prepared = settings.prepared || false;
- let classes = settings.classes || [];
- let spelldata = settings.spelldata || [];
- let existinglist = settings.existinglist || [];
- let spellnumber = 0;
- //D&D 5e Lvl+ Mancer: Powers tab "Level undefined" (UC605)
- //When invoking Lvl+ from an incomplete manually levelled character, an undefined lv is generated due to missing information.
- //This code prevents an incomplete list from being displayed.
- //By Miguel
- if('undefined' in byLevel) {
- delete byLevel.undefined;
- }
- _.each(byLevel, function(level) {
- spellnumber += level.length;
- });
- byLevel["0"] = byLevel["0"] || [];
- addRepeatingSection("choices", "row", "spellsrow", function(spellsrow) {
- let toSet = {};
- let update = {};
- _.each(byLevel, function(spells, x) {
- addRepeatingSection(spellsrow, "spell-holder", "spell-holder-" + x, function(levelrow) {
- if(x == "0") {
- if(newspells > 0) {
- if(classes.length > 1) {
- update[levelrow + " .sheet-spellstext .sheet-summary"] = "";
- _.each(classes, function(thisclass) {
- if(thisclass.newspells) {
- update[levelrow + " .sheet-spellstext .sheet-summary"] += "
You can add " + thisclass.newspells + " " + thisclass.class + " spells.
";
- }
- });
- } else {
- update[levelrow + " .sheet-spellstext .sheet-summary"] = "
You can add " + newspells + " new spells.
";
- }
- }
- if(replace > 0) {
- if(classes.length > 1) {
- update[levelrow + " .sheet-replacetext .sheet-summary"] = "";
- _.each(classes, function(thisclass) {
- if(thisclass.replace) {
- update[levelrow + " .sheet-replacetext .sheet-summary"] += "
You can replace " + thisclass.replace + " " + thisclass.class + " spells.
";
- }
- });
- } else {
- update[levelrow + " .sheet-replacetext .sheet-summary"] = "
You can replace " + replace + " spells.
";
- }
- showChoices([levelrow + " .sheet-replace-info"]);
- }
- } else {
- update[levelrow + " .sheet-spellinfo"] = "";
- }
- update[levelrow + " label .sheet-title"] = x == "0" ? "Primes" : "Level " + x;
- update[levelrow + " label .sheet-title"] += "
r "
- if(x == "0" && newprimes == 0) {
- toSet[levelrow + "_show"] = "1";
- update[levelrow + " .sheet-controller"] = "1";
- }
- if(spells.length === 0) hideChoices([levelrow + " label"]);
- spells = _.sortBy(spells, "name");
- setCharmancerText(update);
- _.each(spells, function(spell) {
- addRepeatingSection(levelrow + " .sheet-container", "spell-item", function(spellid) {
- var update = {};
- toSet[spellid + "_name"] = spell.name;
- toSet[spellid + "_level"] = x;
- update[spellid + " .sheet-name"] = spell.name;
- update[spellid + " .sheet-classes"] = "";
- if(x == "0" && newprimes == 0) update[spellid + " .sheet-hardlock"] = "locked";
- var spellclasses = [];
- _.each(classes, function(thisclass, y) {
- if(spell.classes.includes(thisclass.list) && spell.level <= thisclass.maxlevel) {
- spellclasses.push({class: thisclass.class, ability: thisclass.ability});
- if(classes.length > 1) {
- update[spellid + " .sheet-classes"] += "
" + thisclass.class + " ";
- }
- }
- });
- if(spellclasses.length == 1 || classes.length == 1) {
- toSet[spellid + "_class"] = spellclasses[0] ? spellclasses[0].class : classes[0].class;
- toSet[spellid + "_ability"] = spellclasses[0] ? spellclasses[0].ability : classes[0].ability;
- }
- _.each(spelldata, function(thisspell, spellname) {
- if(spellname == spell.name) {
- toSet[spellid + "_checked"] = "1";
- if(!prepared || x == "0") {
- toSet[spellid + "_existing"] = "1";
- if(x == "0" || replace == 0) update[spellid + " .sheet-hardlock"] = "locked";
- }
- if(thisspell.known) {
- toSet[spellid + "_checked"] = "1";
- toSet[spellid + "_existing"] = "1";
- toSet[spellid + "_source"] = thisspell.known;
- update[spellid + " .sheet-classes"] = "
" + thisspell.known + " Spell ";
- update[spellid + " .sheet-hardlock"] = "locked";
- }
- if(thisspell.spellclass) toSet[spellid + "_class"] = thisspell.spellclass;
- if(thisspell.ability) toSet[spellid + "_ability"] = thisspell.ability;
- }
- });
- if(settings.selected && settings.selected.includes(spell.name)) {
- toSet[spellid + "_checked"] = "1";
- }
- if(settings.locked && settings.locked.includes(spell.name)) {
- toSet[spellid + "_checked"] = "1";
- toSet[spellid + "_existing"] = "1";
- update[spellid + " .sheet-hardlock"] = "locked";
- }
- spellnumber--;
- setCharmancerText(update);
- if(spellnumber <= 0) {
- setAttrs(toSet, {silent: true}, function() {
- updateSpellSummary("all", undefined, settings.page);
- });
- }
- });
- });
- });
- });
- });
-};
-
-const updateSpellSummary = function(sourcelevel, data, thispage) {
- var mancerdata = data || getCharmancerData();
- var spellpage = thispage ? mancerdata[thispage] : mancerdata["lp-spells"];
- var replist = spellpage.repeating || [];
- var primesection = replist.find((x) => {return x.includes("_spell-holder-0")});
- var update = {};
- var sections = [];
- var perlevel = {};
- var allowed = 0;
- var allowedreplace = 0;
- //first, list spells you already know
- _.each(replist, function(repid) {
- if(spellpage.values[repid + "_existing"]) {
- var selector = "spells-summary .sheet-level_" + spellpage.values[repid + "_level"] + " .sheet-list";
- update[selector] = update[selector] || "";
- update[selector] += spellpage.values[repid + "_checked"] ? "
" : "";
- update[selector] += spellpage.values[repid + "_name"] + " ";
- }
- });
- //then, list new spells you've checked
- _.each(replist, function(repid) {
- if(spellpage.values[repid + "_checked"] && !spellpage.values[repid + "_existing"]) {
- var selector = "spells-summary .sheet-level_" + spellpage.values[repid + "_level"] + " .sheet-list";
- update[selector] = update[selector] || "";
- update[selector] += "" + spellpage.values[repid + "_name"] + " ";
- }
- });
- if(sourcelevel == "0") {
- sections.push(primesection);
- allowed = spellpage.values.newprimes || 0;
- } else {
- update[primesection + " .sheet-spellstext .sheet-levels"] = "";
- for(var x=1; x <= 9; x++) {
- var thissection = replist.find((y) => {return y.includes("_spell-holder-" + x)});
- allowed = spellpage.values.newspells;
- allowedreplace = spellpage.values.replace;
- if(thissection) {
- perlevel[x + ""] = {number: 0, section: thissection, replaced: false};
- sections.push(thissection);
- }
- }
- }
- getRepeatingSections(replist.find((x) => {return x.includes("spellsrow")}), function(repeating) {
- var toSet = {};
- var spellids = [];
- var newspells = 0;
- var replaced = 0;
- _.each(repeating.tree, function(spells, levelrow) {
- if(sections.includes(levelrow)) {
- spellids = spellids.concat(_.keys(spells));
- }
- });
- _.each(spellids, function(id) {
- if(spellpage.values[id + "_checked"] && !spellpage.values[id + "_existing"]) {
- newspells++;
- if(perlevel[spellpage.values[id + "_level"]]) perlevel[spellpage.values[id + "_level"]].number++;
- }
- if(!spellpage.values[id + "_checked"] && spellpage.values[id + "_existing"]) {
- replaced++;
- if(perlevel[spellpage.values[id + "_level"]]) perlevel[spellpage.values[id + "_level"]].replaced = true;
- }
- });
- //now lock/unlock spells depending on if we've selected as many as we're allowed
- _.each(spellids, function(id) {
- if(!spellpage.values[id + "_checked"]) {
- update[id + " .sheet-lock"] = newspells >= (allowed + replaced) ? "locked" : "";
- } else if(spellpage.values[id + "_checked"] && spellpage.values[id + "_existing"]) {
- update[id + " .sheet-lock"] = allowedreplace <= replaced ? "locked" : "";
- }
- });
- if(sourcelevel == "0") {
- var known = (thispage != "lp-spellchoice" && spellpage.values.knownprimes) ? spellpage.values.knownprimes : 0;
- update[primesection + " label .sheet-number"] = (known + newspells) + " / " + (known + allowed);
- } else {
- if(thispage != "lp-spellchoice") {
- update[primesection + " .sheet-spellstext .sheet-total"] = newspells + " / " + (allowed + replaced) + " spells chosen.";
- if(replaced > 0) {
- update[primesection + " .sheet-spellstext .sheet-total"] += " (" + allowed + " new, " + replaced + " replaced)";
- }
- if(allowedreplace > 0) {
- update[primesection + " .sheet-replacetext .sheet-total"] = replaced + " / " + allowedreplace + " spells replaced.";
- }
- }
- _.each(perlevel, function(info, level) {
- if(thispage != "lp-spellchoice") update[primesection + " .sheet-spellstext .sheet-levels"] += "" + info.number + " Level " + level + " spells added.
";
- update[info.section + " label .sheet-number"] = "";
- if(info.number > 0) update[info.section + " label .sheet-number"] = "+" + info.number;
- if(info.replaced) {
- showChoices([info.section + " .sheet-spellheader .sheet-title span"]);
- } else {
- hideChoices([info.section + " .sheet-spellheader .sheet-title span"]);
- }
- });
- }
- setCharmancerText(update);
- if(sourcelevel == "all") updateSpellSummary("0", mancerdata, thispage);
- setCharmancerText({pagelock: "unlock"})
- });
-};
-
-on("clicked:repeating_spell-item", function(eventinfo) {
- if(eventinfo.sourceAttribute.indexOf("spell-item_info") === -1) return;
- var mancerdata = getCharmancerData();
- changeCompendiumPage("sheet-spells-info", "Powers:" + mancerdata[eventinfo.currentStep].values[eventinfo.sourceSection + "_name"], "card_only");
-});
-
-on("mancerchange:repeating_spellsrow", function(eventinfo) {
- var mancerdata = getCharmancerData();
- if(eventinfo.sourceAttribute && _.last(eventinfo.sourceAttribute.split("_")) == "show") {
- var update = {};
- update[eventinfo.sourceSection + " .sheet-controller"] = eventinfo.newValue || "";
- setCharmancerText(update);
- } else {
- updateSpellSummary(mancerdata[eventinfo.currentStep].values[eventinfo.sourceSection + "_level"], mancerdata, eventinfo.currentStep);
- }
-});
-
-on("mancerchange:repeating_asi-row", function(eventinfo) {
- var trigger = eventinfo.sourceAttribute.substr(39);
- if(trigger == "switch") {
- var update = {};
- update[eventinfo.sourceSection + " .sheet-switch"] = eventinfo.newValue == "feat" ? "feat" : "";
- setCharmancerText(update);
- } else if(trigger == "feat") {
-
- } else {
- updateAbilityLock(eventinfo.sourceSection);
- //This will lock other ASI when leveling up multiple levels at once
- //By Miguel
- var repeatingData = getCharmancerData()['lp-asi'].repeating || [];
- for(data in repeatingData) {
- if(repeatingData[data].indexOf('_asi-row') > -1) {
- updateAbilityLock(repeatingData[data]);
- }
- }
- }
- recalcLpData();
-});
-
-on("clicked:repeating_asi-row", function(eventinfo) {
- var mancerdata = getCharmancerData();
- var thischange = eventinfo.sourceAttribute.substr(0, eventinfo.sourceAttribute.length - 2);
- var currentvalue = mancerdata["lp-asi"].values[thischange] ? parseInt(mancerdata["lp-asi"].values[thischange]) : 0;
- var totalincrease = 0;
- var update = {};
- var lockinfo = {};
- _.each(abilityList, function(ability) {
- var thisincrease = mancerdata["lp-asi"].values[eventinfo.sourceSection + "_" + ability.toLowerCase()] || 0;
- totalincrease += parseInt(thisincrease);
- });
- if(_.last(eventinfo.sourceAttribute) == "u" && totalincrease < 2 && currentvalue < 2) {
- update[thischange] = currentvalue + 1;
- mancerdata["lp-asi"].values[thischange] = currentvalue + 1;
- } else if(_.last(eventinfo.sourceAttribute) == "d" && currentvalue > 0) {
- update[thischange] = currentvalue - 1;
- mancerdata["lp-asi"].values[thischange] = currentvalue - 1;
- }
- setAttrs(update, function() {
- recalcLpData();
- });
-});
-
-var updateAbilityLock = function(sourceSection, mancerdata) {
- mancerdata = mancerdata || getCharmancerData();
- var abilities = getAbilityTotals(mancerdata);
- var totalincrease = 0;
- var update = {};
- //First, get the total increase for this section
- _.each(abilityList, function(ability) {
- var thisincrease = mancerdata["lp-asi"].values[sourceSection + "_" + ability.toLowerCase()] || 0;
- totalincrease += parseInt(thisincrease);
- });
- //Then, figure out what to lock (based on increase)
- _.each(abilityList, function(ability) {
- var thisincrease = mancerdata["lp-asi"].values[sourceSection + "_" + ability.toLowerCase()] || 0;
- update[sourceSection + " .sheet-" + ability.toLowerCase() + "_lock-down"] = thisincrease > 0 ? "" : "lock";
- update[sourceSection + " .sheet-" + ability.toLowerCase() + "_lock-up"] = thisincrease < 2 && totalincrease < 2 ? "" : "lock";
- });
- //Now, figure out if any stats are maxed out
- _.each(abilityList, function(ability) {
- if(abilities[ability.toLowerCase()] >= abilities[ability.toLowerCase() + "_maximum"]) {
- update[sourceSection + " .sheet-" + ability.toLowerCase() + "_lock-up"] = "lock";
- };
- });
- setCharmancerText(update);
-};
-
-on("page:lp-summary", function() {
- var mancerdata = getCharmancerData();
- var abilities = getAbilityTotals(mancerdata);
- var previous = mancerdata["lp-welcome"].values["previous_attributes"] ? JSON.parse(mancerdata["lp-welcome"].values["previous_attributes"]) : {};
- var spelldata = mancerdata["lp-welcome"].values["spellinfo"] ? JSON.parse(mancerdata["lp-welcome"].values["spellinfo"]) : {};
- var lcAbilities = abilityList.map(function(x) {return x.toLowerCase()});
- var update = {};
- update["before div"] = "Class: ";
- if(previous.subclass) update["before div"] += previous.subclass + " ";
- update["before div"] += previous.class + " " + previous.base_level;
- for(var x=1; x<=3; x++) {
- if(previous["multiclass" + x + "_flag"] != "0") {
- update["before div"] += ", " + previous["multiclass" + x] + " " + previous["multiclass" + x + "_lvl"];
- }
- };
- update["before div"] += "
";
- update["before div"] += "
Hit Points: " + previous.hp_max + "
";
- update["before div"] += "";
- _.each(lcAbilities, function(ability) {
- update["before div"] += "
";
- update["before div"] += "" + abilities[ability + "_previous"] + " ";
- update["before div"] += "(";
- update["before div"] += abilities[ability + "_previous_mod"] >= 0 ? "+" + abilities[ability + "_previous_mod"] : abilities[ability + "_previous_mod"];
- update["before div"] += " )";
- });
- update["before div"] += "
";
- update["after div"] = "Class: ";
- for(var x=1; x<=4; x++) {
- if(mancerdata["lp-levels"].values["class" + x]) {
- if(x !== 1) update["after div"] += ", "
- if(mancerdata["lp-levels"].values["class" + x + "_subclass"]) {
- if((x == 1 && !previous.subclass) || (x != 1 && previous["multiclass" + x + "_flag"] != "0" && !previous["multiclass" + x + "_subclass"])) {
- update["after div"] += "";
- } else {
- update["after div"] += "";
- }
- update["after div"] += removeExpansionInfo(mancerdata["lp-levels"].values["class" + x + "_subclass"].split(":")[1]) + " ";
- }
- if(x != 1 && previous["multiclass" + x + "_flag"] != "0" && !previous["multiclass" + x + "_subclass"]) {
- update["after div"] += "";
- } else {
- update["after div"] += "";
- }
- update["after div"] += removeExpansionInfo(mancerdata["lp-levels"].values["class" + x].split(":")[1]) + " ";
- if(mancerdata["lp-levels"].values["class" + x + "_addlevel"]) {
- update["after div"] += "";
- } else {
- update["after div"] += "";
- }
- var prevlevel = 0;
- if(x == 1) {
- prevlevel = parseInt(previous["base_level"]);
- } else {
- prevlevel = previous["multiclass" + x + "_flag"] == "0" ? 0 : parseInt(previous["multiclass" + x + "_lvl"])
- }
- update["after div"] += (prevlevel + parseInt(mancerdata["lp-levels"].values["class" + x + "_addlevel"])) + " ";
- }
- };
- update["after div"] += "
";
- update["after div"] += "
Hit Points: " + getHpTotal(mancerdata) + "
";
- update["after div"] += "";
- _.each(lcAbilities, function(ability) {
- update["after div"] += abilities[ability] == abilities[ability + "_previous"] ? "
" : "
"
- update["after div"] += "
";
- update["after div"] += abilities[ability] == abilities[ability + "_previous"] ? "" : "";
- update["after div"] += abilities[ability] + " (";
- update["after div"] += abilities[ability + "_mod"] == abilities[ability + "_previous_mod"] ? "" : "";
- update["after div"] += abilities[ability + "_mod"] >= 0 ? "+" + abilities[ability + "_mod"] : abilities[ability + "_mod"];
- update["after div"] += " ) ";
- });
- update["after div"] += "
";
-
- //Powers
- let selectedPowers = getGainedPowers();
- update["spell_info"] = "
You haven't gained any spells
";
- if(selectedPowers.length > 0) update["spell_info"] = '
You have learnt these spells: '+ selectedPowers.sort().join(", ") +'
';
-
- let gainedFeatures = getGainedFeatures();
- update["feature_info"] = (gainedFeatures.length > 0) ? '
You have gained these class features: '+ gainedFeatures.sort().join(", ") +'
' :
- "You haven't gained any class features.";
-
- setCharmancerText(update);
- showChoices(["apply_changes"]);
- console.log(mancerdata["lp-levels"].values);
- console.log(abilities);
- console.log(previous);
-});
-
-on("clicked:lp-choices_next", function(eventinfo) {
- const mancerdata = getCharmancerData();
- if(mancerdata["lp-levels"].values.asi === "true") {
- changeCharmancerPage("lp-asi");
- } else if(mancerdata["lp-levels"].values.spells === "true") {
- changeCharmancerPage("lp-spells");
- } else {
- changeCharmancerPage("lp-summary");
- }
-});
-on("clicked:lp-asi_next", function(eventinfo) {
- const mancerdata = getCharmancerData();
- if(mancerdata["lp-levels"].values.spells === "true") {
- changeCharmancerPage("lp-spells");
- } else {
- changeCharmancerPage("lp-summary");
- }
-});
-on("clicked:lp-spells_back", function(eventinfo) {
- const mancerdata = getCharmancerData();
- if(mancerdata["lp-levels"].values.asi === "true") {
- changeCharmancerPage("lp-asi");
- } else {
- changeCharmancerPage("lp-choices");
- }
-});
-on("clicked:lp-summary_back", function(eventinfo) {
- const mancerdata = getCharmancerData();
- if(mancerdata["lp-levels"].values.spells === "true") {
- changeCharmancerPage("lp-spells");
- } else if(mancerdata["lp-levels"].values.asi === "true") {
- changeCharmancerPage("lp-asi");
- } else {
- changeCharmancerPage("lp-choices");
- }
-});
-
-//Fixing Bard's Magical Secrets (UC-10)
-//By Miguel
-//The ways this was being handled before, binded to clicked:repeating_utilityrow_launch, was not being triggered due to the way the DOM is built.
-on("clicked:repeating_utilityrow", function(eventinfo) {
- if(eventinfo.triggerName.indexOf('utilityrow_launch') === -1) return;
- const mancerdata = getCharmancerData();
- var querysettings = {};
- var spelldata = getKnownLpPowers(mancerdata);
- var leveldata = _.findWhere(getLevelingData(mancerdata), {classnumber: parseInt(mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_parent`][5])});
- var query = "";
- let newspells = 0;
- let newprimes = 0;
- var spellnames = [];
- var current = [];
- var locked = [];
- var update = {};
- update[`${eventinfo.sourceSection} .sheet-warning`] = "";
- try {
- querysettings = JSON.parse(mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_info`]);
- } catch(e) {
- querysettings = mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_info`];
- };
- if(mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_result`]) current = mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_result`].split(", ");
- if(mancerdata["lp-spells"] && mancerdata["lp-spells"].repeating) {
- _.each(mancerdata["lp-spells"].repeating, function(repid) {
- if(mancerdata["lp-spells"].values[`${repid}_checked`]) {
- spelldata[mancerdata["lp-spells"].values[`${repid}_name`]] = {
- level: mancerdata["lp-spells"].values[`${repid}_level`],
- spellclass: mancerdata["lp-spells"].values[`${repid}_class`]
- }
- }
- });
- }
- _.each(current, function(currentspell) {
- delete spelldata[currentspell];
- })
- if(querysettings.Known) {
- if(querysettings.Level + "" === "0") {
- newprimes = 1;
- } else {
- newspells = 1;
- }
- _.each(spelldata, function(spell, spellname) {
- if(!querysettings.Level || (querysettings.Level && querysettings.Level == spell.level)) spellnames.push(spellname);
- });
- if(spellnames.length > 0) {
- query = "Category:Powers Name:" + spellnames.join("|");
- } else {
- update[`${eventinfo.sourceSection} .sheet-warning`] = `You do not currently know any level ${querysettings.Level} spells.`;
- setCharmancerText(update);
- }
- } else {
- query = "Category:Powers";
- if(querysettings.Level) {
- let levels = [querysettings.Level];
- if(querysettings.Level == "max") {
- levels = [];
- for(let x=1; x<=leveldata.maxspell; x++) {
- levels.push(x);
- }
- }
- query += " Level:" + levels.join("|");
- };
- if(querysettings.List && querysettings.List.toLowerCase() !== "any") {
- query += " Classes:*" + querysettings.List;
- };
- if(querysettings.Level + "" === "0") {
- newprimes = querysettings.Number ? parseInt(querysettings.Number) : 1;
- } else {
- newspells = querysettings.Number ? parseInt(querysettings.Number) : 1;
- }
- locked = _.keys(spelldata);
- }
- if(query) {
- setCharmancerText(update);
- changeCharmancerPage("lp-spellchoice", function() {
- getCompendiumQuery([query], function(data) {
- data = removeDuplicatedPageData(data);
- let byLevel = {};
- let filters = {};
- let filtered = [];
- let toSet = {};
- let update = {};
- update["instructions"] = querysettings.HelpText;
- console.log(data);
- _.each(querysettings, function(setting, key) {
- if(!["Level","List","Number","Type","ButtonText","HelpText", "Known", "Class"].includes(key)) {
- filters[key] = setting;
- }
- });
- console.log(filters);
- if(querysettings.Known) {
- delete querysettings.Level;
- }
- delete querysettings.Known;
- _.each(data, function(spell) {
- let match = true;
- _.each(filters, function(value, name) {
- if(spell.data[name] !== value) match = false;
- })
- if(match) filtered.push(spell);
- });
- console.log(filtered);
- _.each(filtered, function(spell) {
- if(spell.data.Classes) {
- byLevel[spell.data.Level] = byLevel[spell.data.Level] || [];
- byLevel[spell.data.Level].push({
- name: spell.name,
- classes: spell.data.Classes.split(",").map(x => x.trim()),
- level: parseInt(spell.data.Level)
- });
- }
- });
- toSet.newspells = newspells;
- toSet.newprimes = newprimes;
- toSet.valid = "now";
- toSet.source = eventinfo.sourceSection;
- setCharmancerText(update);
- setAttrs(toSet, function() {
- addSpellSections(byLevel, {
- newprimes: newprimes,
- newspells: newspells,
- page: "lp-spellchoice",
- selected: current,
- locked: locked
- });
- });
- });
- });/**/
- }
-});
-
-//TODO: Investigate if the duplicated event below listener can be removed
-//By Miguel
-on("clicked:repeating_utilityrow_launch", function(eventinfo) {
- const mancerdata = getCharmancerData();
- var querysettings = {};
- var spelldata = getKnownLpPowers(mancerdata);
- var leveldata = _.findWhere(getLevelingData(mancerdata), {classnumber: parseInt(mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_parent`][5])});
- var query = "";
- let newspells = 0;
- let newprimes = 0;
- var spellnames = [];
- var current = [];
- var locked = [];
- var update = {};
- update[`${eventinfo.sourceSection} .sheet-warning`] = "";
- try {
- querysettings = JSON.parse(mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_info`]);
- } catch(e) {
- querysettings = mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_info`];
- };
- if(mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_result`]) current = mancerdata["lp-choices"].values[`${eventinfo.sourceSection}_result`].split(", ");
- if(mancerdata["lp-spells"] && mancerdata["lp-spells"].repeating) {
- _.each(mancerdata["lp-spells"].repeating, function(repid) {
- if(mancerdata["lp-spells"].values[`${repid}_checked`]) {
- spelldata[mancerdata["lp-spells"].values[`${repid}_name`]] = {
- level: mancerdata["lp-spells"].values[`${repid}_level`],
- spellclass: mancerdata["lp-spells"].values[`${repid}_class`]
- }
- }
- });
- }
- _.each(current, function(currentspell) {
- delete spelldata[currentspell];
- })
- if(querysettings.Known) {
- if(querysettings.Level + "" === "0") {
- newprimes = 1;
- } else {
- newspells = 1;
- }
- _.each(spelldata, function(spell, spellname) {
- if(!querysettings.Level || (querysettings.Level && querysettings.Level == spell.level)) spellnames.push(spellname);
- });
- if(spellnames.length > 0) {
- query = "Category:Powers Name:" + spellnames.join("|");
- } else {
- update[`${eventinfo.sourceSection} .sheet-warning`] = `You do not currently know any level ${querysettings.Level} spells.`;
- setCharmancerText(update);
- }
- } else {
- query = "Category:Powers";
- if(querysettings.Level) {
- let levels = [querysettings.Level];
- if(querysettings.Level == "max") {
- levels = [];
- for(let x=1; x<=leveldata.maxspell; x++) {
- levels.push(x);
- }
- }
- query += " Level:" + levels.join("|");
- };
- if(querysettings.List && querysettings.List.toLowerCase() !== "any") {
- query += " Classes:*" + querysettings.List;
- };
- if(querysettings.Level + "" === "0") {
- newprimes = querysettings.Number ? parseInt(querysettings.Number) : 1;
- } else {
- newspells = querysettings.Number ? parseInt(querysettings.Number) : 1;
- }
- locked = _.keys(spelldata);
- }
- if(query) {
- setCharmancerText(update);
- changeCharmancerPage("lp-spellchoice", function() {
- getCompendiumQuery([query], function(data) {
- data = removeDuplicatedPageData(data);
- let byLevel = {};
- let filters = {};
- let filtered = [];
- let toSet = {};
- let update = {};
- update["instructions"] = querysettings.HelpText;
- console.log(data);
- _.each(querysettings, function(setting, key) {
- if(!["Level","List","Number","Type","ButtonText","HelpText", "Known", "Class"].includes(key)) {
- filters[key] = setting;
- }
- });
- console.log(filters);
- if(querysettings.Known) {
- delete querysettings.Level;
- }
- delete querysettings.Known;
- _.each(data, function(spell) {
- let match = true;
- _.each(filters, function(value, name) {
- if(spell.data[name] !== value) match = false;
- })
- if(match) filtered.push(spell);
- });
- console.log(filtered);
- _.each(filtered, function(spell) {
- if(spell.data.Classes) {
- byLevel[spell.data.Level] = byLevel[spell.data.Level] || [];
- byLevel[spell.data.Level].push({
- name: spell.name,
- classes: spell.data.Classes.split(",").map(x => x.trim()),
- level: parseInt(spell.data.Level)
- });
- }
- });
- toSet.newspells = newspells;
- toSet.newprimes = newprimes;
- toSet.valid = "now";
- toSet.source = eventinfo.sourceSection;
- setCharmancerText(update);
- setAttrs(toSet, function() {
- addSpellSections(byLevel, {
- newprimes: newprimes,
- newspells: newspells,
- page: "lp-spellchoice",
- selected: current,
- locked: locked
- });
- });
- });
- });/**/
- }
-});
-
-on("page:lp-spellchoice", function() {
- const mancerdata = getCharmancerData();
- if(mancerdata["lp-spellchoice"] && mancerdata["lp-spellchoice"].values.valid === "now") {
- changeCharmancerPage("lp-choices", function() {
- deleteCharmancerData(["lp-spellchoice"]);
- });
- }
-});
-
-on("mancerchange:repeating_utilityrow_result", function(eventinfo) {
- if(eventinfo.sourceSection) {
- const mancerdata = getCharmancerData();
- let update = {};
- console.log(`${eventinfo.sourceSection}_title`);
- update[`${eventinfo.sourceSection} label span .sheet-result`] = eventinfo.newValue;
- console.log(update);
- setCharmancerText(update);
- }
-});
-
-on("clicked:lp-spellchoice_back", function(eventinfo) {
- const mancerdata = getCharmancerData();
- const leveldata = getLevelingData(mancerdata);
- let result = [];
- let source = mancerdata["lp-spellchoice"].values.source;
- let newspells = false;
- let spellsettings = {};
- if(mancerdata["lp-choices"].values[`${source}_info`]) {
- spellsettings = JSON.parse(mancerdata["lp-choices"].values[`${source}_info`]);
- }
- _.each(mancerdata["lp-spellchoice"].repeating, function(repid) {
- if(mancerdata["lp-spellchoice"].values[`${repid}_checked`] && !mancerdata["lp-spellchoice"].values[`${repid}_existing`]) result.push(mancerdata["lp-spellchoice"].values[`${repid}_name`]);
- });
- if(mancerdata["lp-choices"].values[`${source}_type`] !== "trait") {
- const thisclass = _.findWhere(leveldata, {classnumber: parseInt(mancerdata["lp-choices"].values[`${source}_parent`][5])});
- newspells = {}
- _.each(mancerdata["lp-spellchoice"].repeating, function(repid) {
- if(mancerdata["lp-spellchoice"].values[`${repid}_checked`] && !mancerdata["lp-spellchoice"].values[`${repid}_existing`]) {
- let thisspell = {
- ability: thisclass.spellcasting,
- spellclass: thisclass.classname,
- level: mancerdata["lp-spellchoice"].values[`${repid}_level`] === "0" ? "prime" : mancerdata["lp-spellchoice"].values[`${repid}_level`]
- }
- if(spellsettings.Type) thisspell.known = spellsettings.Type;
- newspells[mancerdata["lp-spellchoice"].values[`${repid}_name`]] = thisspell;
- }
- });
- }
- changeCharmancerPage("lp-choices", function() {
- deleteCharmancerData(["lp-spellchoice"]);
- let set = {};
- set[`${source}_result`] = result.join(", ");
- if(newspells) set[`${source}_spells`] = JSON.stringify(newspells);
- setAttrs(set);
- });
-});
-
-on("mancerfinish:lp-mancer", function(eventinfo) {
- console.log("****************************************");
- console.log("****** STARTING FINISH FUNCTION ******");
- console.log("****************************************");
- var doAllDrops = function(dropArray, callback) {
- getAttrs(["character_id"], function(v) {
- _.each(allAbilities, function(ability) {
- v[ability + "_base"] = abilities[ability];
- v[ability + "_mod"] = abilities[ability];
- });
- v.base_level = set["base_level"];
- v["multiclass1_lvl"] = initial["multiclass1_lvl"];
- v["multiclass2_lvl"] = initial["multiclass2_lvl"];
- v["multiclass3_lvl"] = initial["multiclass3_lvl"];
- v.npc = "0";
- v["class_resource_name"] = previous["class_resource_name"];
- v["other_resource_name"] = previous["other_resource_name"];
- v.speed = previous.speed;
- var update = {};
- var callbacks = [];
- var totalDrops = dropArray.length;
- var x = 0;
- callbacks.push(set_level);
- callbacks.push(update_race_display);
- _.each(dropArray, function(page) {
- page.data.Category = page.data.Category ? page.data.Category.replace("@@!!@@", "") : "";
- var dropUpdate = processDrop(page, v, repeating, true);
- callbacks = callbacks.concat(dropUpdate.callbacks);
- repeating.prof_names = _.uniq(repeating.prof_names.concat(dropUpdate.prof_names));
- update = _.extend(update, dropUpdate.update);
- x++;
- setCharmancerText({"mancer_progress" :'
'});
- });
-
- callbacks.push( function() {update_ac();} );
- callbacks.push( function() {update_weight();} );
- callbacks.push(callback);
- console.log(update);
- setAttrs(update, {silent: true}, function() {
- setCharmancerText({"mancer_progress" :'
'});
- _.each(callbacks, function(callback) {
- callback();
- });
- });/**/
- });
- };
- var getOtherDrops = function(pagedata) {
- var results = [];
- if(pagedata["data-Equipment"]) {
- console.log("ADDING ADDITIONAL ITEMS:");
- var json = {};
- try {
- json = JSON.parse(pagedata["data-Equipment"]);
- } catch(e) {
- json = pagedata["data-Equipment"];
- }
- var newItems = makeItemData(json.default);
- results = results.concat(newItems);
- }
- if(pagedata["data-Bundle"]) {
- console.log("ADDING ADDITIONAL ITEMS (FROM BUNDLE):");
- var json = {};
- try {
- json = JSON.parse(pagedata["data-Bundle"]);
- } catch(e) {
- json = pagedata["data-Bundle"];
- }
- var newItems = makeItemData(json);
- results = results.concat(newItems);
- }
- return results;
- };
- var getAllPages = function(pageArray, callback) {
- if(pageArray.length < 1) {
- callback();
- return;
- }
- var getNames = [];
- _.each(pageArray, function(page){
- if(page.name) {
- getNames.push(page.name);
- } else {
- getNames.push(page);
- }
- });
- getCompendiumPage(getNames, function(data) {
- data = removeDuplicatedPageData(data);
- var nextGet = [];
- if (getNames.length === 1) { data = {0:data} }; //Fix single spell selections failing.
- _.each(data, function(page, index) {
- var pagedata = false;
- _.each(pageArray, function(arrayData) {
- if(arrayData.name.toLowerCase() == (page.data.Category + ":" + page.name).toLowerCase()) {
- pagedata = arrayData;
- }
- });
- if(pagedata && pagedata.data) {
- page.data = _.extend(page.data, pagedata.data);
- }
- if(!page.id) page.data.Source = "Charactermancer";
- page.name = page.name.replace(/@@!!@@/g,""); // Hacky bugfix to prevent custom names from matching unavailable content
- nextGet = nextGet.concat(getOtherDrops(page.data));
- if(page.data["data-Starting Cubil"] && !noEquipmentDrop) {
- set["cu"] += parseInt(page.data["data-Starting Money"]);
- }
- allPageData.push(page);
- });
-
- if(nextGet.length > 0) {
- console.log("DOING ANOTHER GET!!");
- getAllPages(nextGet, callback);
- } else {
- callback();
- }
-
- });
- };
- var startTime = Date.now();
- var allPageData = [];
- var data = eventinfo.data;
- var blobs = getAllLpBlobs(data, true);
- var leveldata = getLevelingData(data);
- var racedata = getLpRaceData(data, leveldata);
- var abilities = getAbilityTotals(data, blobs);
- var previous = data["lp-welcome"].values["previous_attributes"] ? JSON.parse(data["lp-welcome"].values["previous_attributes"]) : {};
- var repeating = data["lp-welcome"].values["previous_repeating"] ? JSON.parse(data["lp-welcome"].values["previous_repeating"]) : {};
- var spelldata = data["lp-welcome"].values["spellinfo"] ? JSON.parse(data["lp-welcome"].values["spellinfo"]) : {};
- var customtraits = {race: [], subrace: [], class: [], subclass: [], background: []};
- var profs = getProficiencies(data, "lp-finish", blobs);
- var removesections = [];
- var loudset = {};
- var set = {};
- var initial = {};
- var allDrops = [];
- var currentDrop = 0;
- var totalDrops = 1;
- var allSkills = ["athletics", "acrobatics", "sleight_of_hand", "stealth", "astrophysics", "lore", "investigation", "xenobiology", "computers", "mechanics", "insight", "medicine", "perception", "survival", "deception", "intimidation", "performance", "persuasion", "piloting"];
- var allAbilities = abilityList.map(function(x) {return x.toLowerCase()});
- set["lp-mancer_status"] = "";
- console.log(blobs);
- // Build new blobs for traits with inputs, collect custom traits and languages
- _.each(["lp-choices", "lp-asi"], function(pagename) {
- var slide = data[pagename];
- if(slide) {
- console.log(slide);
- _.each(slide.values, function(value, name) {
- if(name.substr(-11) == "trait_input") {
- let sectionid = name.substring(0, name.length - 6);
- let thisblob = {};
- let thistrait = {};
- let classnumber = _.last(slide.values[sectionid + "_section"].split("--")[0].split("-"));
- let sectionname = "class" + classnumber;
- if(slide.values[sectionid + "_section"].includes("subclass")) sectionname += "_subclass";
- let thissection = _.findWhere(leveldata, {classnumber: parseInt(classnumber)});
- thistrait.Name = slide.values[sectionid + "_name"].replace(/{{Input}}/g, value);
- thistrait.Desc = slide.values[sectionid + "_desc"] ? slide.values[sectionid + "_desc"].replace(/{{Input}}/g, value) : "";
- thisblob.Traits = JSON.stringify([thistrait]);
- blobs.names[sectionname].push(sectionid);
- thissection[slide.values[sectionid + "_section"].includes("subclass") ? "subclass" : "class"].blobs[sectionid] = thisblob;
- }
- if(name.split("_")[2] == "custom" && name.substr(-10) == "trait_name") {
- var sectionid = name.substring(0, name.length - 5);
- var thistrait = {};
- thistrait.Name = slide.values[sectionid + "_name"];
- thistrait.Desc = slide.values[sectionid + "_desc"] ? slide.values[sectionid + "_desc"] : "";
- customtraits[name.split("_")[3]].push(thistrait);
- }
- if(value == "custom" && name.substr(-18) == "proficiency_choice") {
- var sectionid = name.substring(0, name.length - 7);
- if(slide.values[sectionid + "_custom"] && slide.values[sectionid + "_type"]) {
- profs.all[slide.values[sectionid + "_type"]].push(slide.values[sectionid + "_custom"])
- }
- }
- if(name.substr(-17) === "utilityrow_result") {
- let sectionid = name.substring(0, name.length - 7);
- let thissection = _.findWhere(leveldata, {classnumber: parseInt(slide.values[sectionid + "_parent"][5])});
- let section = slide.values[sectionid + "_parent"].includes("subclass") ? "subclass" : "class";
- if(thissection[section].blobs[slide.values[sectionid + "_blob"]].Traits) thissection[section].blobs[slide.values[sectionid + "_blob"]].Traits = thissection[section].blobs[slide.values[sectionid + "_blob"]].Traits.replace(/{{Input}}/g, value);
- }
- });
- }
- });
- _.each(leveldata, function(level) {
- var name = "class" + level.classnumber;
- var mc = "multiclass" + (level.classnumber - 1);
- var thisclass = {name: removeExpansionInfo(level.classname), data: level.class};
- //if this is an mc class, add mc data
- if(name != "class1") thisclass.data.multiclass = mc;
- thisclass.data.theseblobs = blobs.names[name];
- allPageData.push(thisclass);
- if(level.subclass) {
- var thissubclass = {name: removeExpansionInfo(level.subclassname), data: level.subclass};
- //if this is an mc subclass, add mc data
- if(name != "class1") thissubclass.data.multiclass = mc;
- thissubclass.data.theseblobs = blobs.names[name + "_subclass"];
- allPageData.push(thissubclass);
- }
- //set up the setAttrs for this class
- if(name === "class1") {
- set["base_level"] = parseInt(previous["base_level"]) + level.addlevel;
- } else {
- initial[mc + "_lvl"] = previous[mc + "_flag"] === "0" ? level.addlevel : parseInt(previous[mc + "_lvl"]) + level.addlevel;
- }
- });
- _.each(racedata, function(level, label) {
- _.each(["", "sub"], function(prefix) {
- let section = prefix + label;
- if(previous[section] && blobs.names[section] && blobs.names[section].length > 0) {
- let thisDrop = {name: previous[section], data: {Category: section[0].toUpperCase() + section.substring(1, section.length) + "s"}};
- thisDrop.data.blobs = data["lp-welcome"].data["lp-" + section].blobs;
- thisDrop.data.theseblobs = blobs.names[section];
- allPageData.push(thisDrop);
- }
- });
- });
- //Set up proficiency drops
- _.each(["Armor", "Language", "Tool", "Weapon"], function(proftype) {
- _.each(profs.all[proftype], function(prof) {
- if(prof) {
- var profdata = {name: "Proficiencies:" + prof, data: {Type: proftype}}
- if(profs.all.Expertise.includes(prof)) {
- profdata.data["toolbonus_base"] = "(@{pb}*2)";
- allDrops.unshift(profdata);
- } else {
- allDrops.push(profdata);
- }
- };
- });
- });
- console.log(profs.all);
- //Set up expertise drops
- _.each(_.uniq(profs.all.Skill.concat(profs.all.Expertise)), function(prof) {
- var profName = prof.toLowerCase().replace(/ /g, "_");
- initial[profName + "_prof"] = "(@{pb}*@{" + profName + "_type})";
- if(profs.all.Expertise.indexOf(prof) != -1) {
- set[profName + "_type"] = 2;
- }
- });
- //Set up Ability scores
- initial["hp"] = getHpTotal(data, blobs);
- initial["hp_max"] = initial["hp"];
- _.each(allAbilities, function(ability) {
- loudset[ability + "_base"] = abilities[ability];
- loudset[ability + "_maximum"] = abilities[ability + "_maximum"];
- });
- //Set up spell drops
- if(data["lp-spells"] && data["lp-spells"].repeating) {
- _.each(data["lp-spells"].repeating, function(repid) {
- if(data["lp-spells"].values[repid + "_checked"]) {
- var spelldata = {name: "Powers:" + data["lp-spells"].values[repid + "_name"], data: {}};
- if(data["lp-spells"].values[repid + "_ability"]) spelldata.data["spellcasting_ability"] = data["lp-spells"].values[repid + "_ability"];
- if(data["lp-spells"].values[repid + "_class"]) spelldata.data["spellclass"] = data["lp-spells"].values[repid + "_class"];
- if(data["lp-spells"].values[repid + "_source"]) spelldata.data["spellsource"] = data["lp-spells"].values[repid + "_source"];
- allDrops.push(spelldata);
- }
- if(data["lp-spells"].values[repid + "_existing"] && !data["lp-spells"].values[repid + "_checked"]) {
- var lvl = data["lp-spells"].values[repid + "_level"];
- var id = "";
- _.each(repeating["spell-" + lvl], function(spell, spellid) {
- if(spell.spellname.toLowerCase() == data["lp-spells"].values[repid + "_name"].toLowerCase()) {
- id = spellid;
- if(spell.spellattackid) removesections.push("repeating_attack_" + spell.spellattackid);
- };
- });
- removesections.push("repeating_spell-" + lvl + "_" + id);
- }
- });
- } else {
- //If there was no spell page, need to drop any new "known" spells
- _.each(blobs.sorted, function(section, name) {
- _.each(section, function(blob) {
- if(blob.Powers) {
- spells = JSON.parse(blob.Powers);
- _.each(spells, function(spell) {
- if(spell.Known) {
- _.each(spell.Known, function(spellname) {
- var thisspell = {name: "Powers:" + spellname, data: {}};
- var thisclass = name.substring(0,5) === "class" ? _.last(data["lp-levels"].values[name.split("_")[0]].split(":")) : "Racial";
- if(spell.Ability) thisspell.data["spellcasting_ability"] = spell.Ability;
- if(spell.Source) thisspell.data["spellsource"] = spell.Source;
- thisspell.data["spellclass"] = thisclass;
- allDrops.push(thisspell);
- });
- };
- });
- };
- });
- });
- };
- //Gater spells from class features
- _.each(data, function(page, pagename) {
- if(pagename.split("-")[0] == "lp") {
- _.each(page.values, function(value, name) {
- if(name.substr(-18) === "_utilityrow_spells") {
- let featurespells = JSON.parse(value);
- _.each(featurespells, function(spell, spellname) {
- var thisspell = {name: "Powers:" + spellname, data: {}};
- if(spell.ability) thisspell.data["spellcasting_ability"] = spell.ability;
- if(spell.known) thisspell.data["spellsource"] = spell.known;
- if(spell.spellclass) thisspell.data["spellclass"] = spell.spellclass;
- allDrops.push(thisspell);
- })
- }
- });
- }
- });
- //unset charmancer step
- set["lpmancer_status"] = "";
- set["charactermancer_step"] = "lp-welcome";
- console.log(allDrops);
- console.log(allPageData);
- _.each(removesections, function(rowid) {
- removeRepeatingRow(rowid);
- });
- setCharmancerText({"mancer_progress" :'
'});
- //first set is silent to prevent unwanted sheet workers
- setAttrs(initial, {silent:true}, function() {
- setCharmancerText({"mancer_progress" :'
'});
- //reset remaining attributes, and set ability scores/custom info
- setAttrs(loudset, function() {
- setCharmancerText({"mancer_progress" :'
'});
- getAllPages(allDrops, function() {
- setCharmancerText({"mancer_progress" :'
'});
- doAllDrops(allPageData, function() {
- console.log("DOING THE FINAL SET!!");
- setAttrs(set, function() {
- setCharmancerText({"mancer_progress" :'
'});
- organize_section_proficiencies();
- update_skills(allSkills);
- update_attacks("all");
- deleteCharmancerData(["lp-welcome", "lp-levels", "lp-choices", "lp-asi", "lp-spells","lp-summary"]);
- var endTime = Date.now();
- console.log("Elapsed time: ");
- console.log((endTime-startTime)/1000);
- finishCharactermancer();
- });
- });
- });
- });
- });
-});
const classRelatedAttrs = ['class', 'subclass', 'base_level', 'multiclass1_flag', 'multiclass1', 'multiclass1_subclass', 'multiclass1_lvl', 'multiclass2_flag','multiclass2', 'multiclass2_subclass', 'multiclass2_lvl', 'multiclass3_flag', 'multiclass3', 'multiclass3_subclass', 'multiclass3_lvl'];
const getTalentPointsAndMastery = callback => {
@@ -10753,24 +3628,66 @@ const getTalentPointsAndMastery = callback => {
});
};
+const setTalentPointsAndMastery = () => {
+ getTalentPointsAndMastery((talentPoints, mastery) => {
+ console.log('CALCULATING TALENT POINTS AND ESPER MASTERY');
+ let update = {
+ tp_max:talentPoints,
+ mastery_6th: 0,
+ mastery_7th: 0,
+ mastery_8th: 0,
+ mastery_9th: 0
+ }
+ for(let i=0; i
{
on(`change:${attr}`, evenInfo => {
- getTalentPointsAndMastery((talentPoints, mastery) => {
- console.log('CALCULATING TALENT POINTS AND ESPER MASTERY');
- let update = {
- tp_max:talentPoints,
- mastery_6th: 0,
- mastery_7th: 0,
- mastery_8th: 0,
- mastery_9th: 0
- }
- for(let i=0; i=1; i--) {
+ damagec = damagec.replace(`${i}d`, `${i*2}d`);
+ }
+ damagec = damagec.replace(/\bd(?=[0-9])/g, '2d');
+ return damagec;
+};
+var addShipDamageType = function(damage, type) {
+ if(!damage || !type) return damage;
+ return `${damage} [${type}]`;
+}
+on("change:repeating_weapon-systems", eventinfo => {
+ if(!eventinfo.sourceType || eventinfo.sourceType != 'player' || eventinfo.sourceAttribute.includes('atkdmg')) return;
+ const id = SheetUtils.getUID(eventinfo.triggerName);
+ const pre = `repeating_weapon-systems_${id}`;
+ const weaponAttributes = ['gunner', 'weapon', 'range', 'tohit', 'damage', 'dmgtype', 'special', 'ammo', 'recharge'].map(attr => { return `${pre}_${attr}`; });
+ getAttrs(weaponAttributes, values => {
+ if(values[`${pre}_damage`]) {
+ const damage = addShipDamageType(values[`${pre}_damage`], values[`${pre}_dmgtype`]);
+ const damagec = addShipDamageType(calcShipAtkdmgc(values[`${pre}_damage`]), values[`${pre}_dmgtype`]);
+ const atkdmg = `@{wtype}&{template:dmg} {{rname=@{weapon}}} {{attack=1}} {{range=@{range}}} {{damage=1}} {{dmg1flag=1}} {{dmg1=[[${damage}]]}} {{dmg1type=${values[`${pre}_dmgtype`]}}} {{desc=@{special}}} @{pc_ship_name} {{licensedsheet=@{licensedsheet}}}`;
+ const atkdmgc = `@{wtype}&{template:dmg} {{rname=@{weapon}}} {{attack=1}} {{range=@{range}}} {{damage=1}} {{dmg1flag=1}} {{dmg1=[[${damagec}]]}} {{dmg1type=${values[`${pre}_dmgtype`]}}} {{desc=@{special}}} @{pc_ship_name} {{licensedsheet=@{licensedsheet}}}`;
+ const update = {
+ [`${pre}_atkdmg`]: atkdmg,
+ [`${pre}_atkdmgc`]: atkdmgc,
+ }
+ setAttrs(update, {silent: true});
+ }
+ });
+});
+
+
//# sourceURL=espergenesis.js
diff --git a/Esper_Genesis_5E/src/charactermancer/l1/class.html b/Esper_Genesis_5E/src/charactermancer/l1/class.html
new file mode 100644
index 0000000000..1e61e4916a
--- /dev/null
+++ b/Esper_Genesis_5E/src/charactermancer/l1/class.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+ Choose a class:
+
+ Choose
+ Custom
+
+ i
+
+
+
+ Custom Class Name:
+
+
+
+
+
+
+
+
+
+
+
+ Back
+ Back to Top
+ Next
+
+
+
Where would you like to go, Traveler?
+
Discard and exit
+
Save and Exit
+
Continue Charactermancer
+
Discard and Exit will discard all choices you’ve made in Charactermancer and let you edit your character sheet directly.
+
+
+
diff --git a/Esper_Genesis_5E/src/charactermancer/l1/l1.html b/Esper_Genesis_5E/src/charactermancer/l1/l1.html
index ecef1b17d3..9e8aa76784 100644
--- a/Esper_Genesis_5E/src/charactermancer/l1/l1.html
+++ b/Esper_Genesis_5E/src/charactermancer/l1/l1.html
@@ -1,6 +1,5 @@
-
@@ -33,7 +32,6 @@
Ability Score Increase:
-
-
- Choose
- Strength
- Dexterity
- Constitution
- Intelligence
- Wisdom
- Charisma
-
-
- Choose
- Strength
- Dexterity
- Constitution
- Intelligence
- Wisdom
- Charisma
-
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
Strength:
@@ -149,25 +178,56 @@
Subrace Ability Score Increase:
-
-
- Choose
- Strength
- Dexterity
- Constitution
- Intelligence
- Wisdom
- Charisma
-
-
- Choose
- Strength
- Dexterity
- Constitution
- Intelligence
- Wisdom
- Charisma
-
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
+ Choose
+ Strength
+ Dexterity
+ Constitution
+ Intelligence
+ Wisdom
+ Charisma
+
+
Strength:
@@ -198,8 +258,8 @@
-
Additional Primes :
-
- Prime List (if different from default class list) :
-
+ Additional Cantrips :
+
+ Cantrip List (if different from default class list) :
+
Choose
- Adept
- Cybermancer
- Engineer
- Hunter
- Melder
- Sentinel
+ Artificer
+ Bard
+ Cleric
+ Druid
+ Paladin
+ Ranger
+ Sorcerer
+ Warlock
+ Wizard
- Additional Level 1 Powers :
+ Additional Level 1 Spells :
Spell List (if different from default class list) :
Choose
- Adept
- Cybermancer
- Engineer
- Hunter
- Melder
- Sentinel
+ Artificer
+ Bard
+ Cleric
+ Druid
+ Paladin
+ Ranger
+ Sorcerer
+ Warlock
+ Wizard
@@ -402,7 +473,6 @@
-
@@ -424,7 +494,9 @@
Select your choices:
- (4d6, drop lowest)
+
+ (4d6, drop lowest)
+
Clear Assignment
@@ -467,6 +539,14 @@
Charisma:
+
+ Honor:
+
+
+
+ Sanity:
+
+
@@ -499,6 +579,14 @@
Charisma:
+
+ Honor:
+
+
+
+ Sanity:
+
+
@@ -525,7 +613,6 @@
@@ -639,14 +726,14 @@
-
-
+
+
You have not yet selected a class.
@@ -654,7 +741,7 @@
You have created a custom class; you can add equipment to the character sheet after you have finished the Charactermancer.
-
+
Pick your equipment:
Class : ( )
@@ -666,24 +753,24 @@
Choose
Class Equipment
- Starting Wealth (Core)
+ Starting Wealth (PHB)
-
-
+
+
Equipment from Class
( )
- Starting Cubil:
+ Starting Gold:
-
+
-
@@ -739,8 +826,8 @@
Equipment from Background
(
)
-
- You have chosen starting cubil and do not get equipment from your background.
+
+ You have chosen starting gold and do not get equipment from your background.
@@ -793,18 +880,17 @@
-
-
Cosmic forces are a mystery to you.
-
Your character doesn't have spells at this level. Click "Next" to review your character!
+
The Arcane is a mystery to you.
+
Your character doesn't have spells at this level. Click “Next” to review your character!
Back
@@ -828,7 +914,6 @@
+
+
Eldritch Invocations :
+
+
+ Choose
+
+
+
@@ -1014,7 +1107,6 @@
-
Powers
+
Spells
@@ -108,6 +108,8 @@
I
II
III
+
IV
+
V
@@ -336,12 +338,12 @@
-
+
-
+
y
@@ -350,12 +352,11 @@
Mod.
-
-
+
-
+
PS
DX
CN
@@ -365,19 +366,34 @@
- Effort
+ Targets
+
+
+
+ Effort
+
+
Subconscious
Conscious
+
+
- No.
+ Save
-
-
+
+
+ PS
+ DX
+ CN
+ IN
+ MS
+ CH
+
Duration
@@ -385,12 +401,99 @@
+
+
+
+ Effect
+
+
+
+ None
+ AC Critical
+ Burn
+ Cold
+ Comp. A
+ Comp. C
+ Critical
+ Delirium
+ Disintegrate
+ Domination
+ Electrical
+ Fatal
+ Field Negate
+ Fumes
+ Heat
+ Hits +1RF
+ Ignites
+ Ignores AC
+ Intercept
+ Irritant
+ Knock Down
+ Knock Out
+ Mutate
+ Paralysis
+ Poison
+ Power Drain
+ Radiation
+ Scatter
+ Seeker
+ Short Out
+ Slam
+ Sonic
+ Stun
+ Subsonics
+ Tangle
+
+
+
Critical
+
+
+ None
+ AC Critical
+ Burn
+ Cold
+ Comp. A
+ Comp. C
+ Critical
+ Delirium
+ Disintegrate
+ Domination
+ Electrical
+ Fatal
+ Field Negate
+ Fumes
+ Heat
+ Hits +1 RF
+ Ignites
+ Ignores AC
+ Intercept
+ Irritant
+ Knock Down
+ Knock Out
+ Mutate
+ Paralysis
+ Poison
+ Power Drain
+ Radiation
+ Scatter
+ Seeker
+ Short Out
+ Slam
+ Sonic
+ Stun
+ Subsonics
+ Tangle
+
+
Description
+
Show description on roll
+
+
@@ -400,10 +503,10 @@
Attacks
-
+
Name
-
+
Mod.
@@ -412,17 +515,17 @@
Dmg.
-
-
+
Add attack rank to damage
+
+
Notes
@@ -868,7 +993,7 @@
+
Add attack rank to damage
+
+
Notes
@@ -1798,13 +1947,142 @@
Ability Scores
-
Reset
Roll
+
+ Input
+
+
+
+
+
+
Physical Abilities
+
+
+
+
+
+
+
Mental Abilities
+
+
+
+
+
+
+
+
Hit Points
@@ -2084,500 +2362,584 @@
})();
-
-//------ Functions ---------
+ //------ Functions ---------
-const update_ability = function(name) {
- console.log('update_ability: '+name);
- let update = {};
- getAttrs([name+'_rolled', name+'_advanced', name+'_tmp'], (v) => {
- console.log(v);
- update[name] = (parseInt(v[name+'_rolled']) || 0 ) + (parseInt(v[name+'_advanced']) || 0 ) + (parseInt(v[name+'_tmp']) || 0 );
- console.log(update);
- setAttrs(update, {silent: false});
- });
+const update_ability = function (name) {
+ console.log("update_ability: " + name);
+ let update = {};
+ getAttrs([name + "_rolled", name + "_advanced", name + "_tmp"], (v) => {
+ console.log(v);
+ update[name] =
+ (parseInt(v[name + "_rolled"]) || 0) +
+ (parseInt(v[name + "_advanced"]) || 0) +
+ (parseInt(v[name + "_tmp"]) || 0);
+ console.log(update);
+ setAttrs(update, { silent: false });
+ });
};
// @todo: this should probably just pick up equipped shields, rather than having a specific shield setting.
-const getShieldCS = function(shield_size, shield_material) {
- console.log('getShieldCS');
- console.log(shield_size);
- console.log(shield_material);
- let CS_physical = 0, CS_energy = 0, CS_mental = 0;
-
- CS_physical =
- parseInt(shield_size) > 2 ? -2 :
- parseInt(shield_size) > 1 ? -1 :
- 0;
-
- CS_physical =
- parseInt(shield_material) === 1 ? CS_physical :
- parseInt(shield_material) === 2 ? CS_physical :
- parseInt(shield_material) === 3 ? CS_physical-1 :
- parseInt(shield_material) === 4 ? CS_physical-1 :
- parseInt(shield_material) === 5 ? CS_physical-2 :
- parseInt(shield_material) === 6 ? CS_physical :
- CS_physical;
- CS_energy = parseInt(shield_material) === 6 ? CS_physical -3 : CS_physical;
- return {CS_physical, CS_energy, CS_mental};
+const getShieldCS = function (shield_size, shield_material) {
+ console.log("getShieldCS");
+ console.log(shield_size);
+ console.log(shield_material);
+ let CS_physical = 0,
+ CS_energy = 0,
+ CS_mental = 0;
+
+ CS_physical =
+ parseInt(shield_size) > 2 ? -2 : parseInt(shield_size) > 1 ? -1 : 0;
+
+ CS_physical =
+ parseInt(shield_material) === 1
+ ? CS_physical
+ : parseInt(shield_material) === 2
+ ? CS_physical
+ : parseInt(shield_material) === 3
+ ? CS_physical - 1
+ : parseInt(shield_material) === 4
+ ? CS_physical - 1
+ : parseInt(shield_material) === 5
+ ? CS_physical - 2
+ : parseInt(shield_material) === 6
+ ? CS_physical
+ : CS_physical;
+ CS_energy = parseInt(shield_material) === 6 ? CS_physical - 3 : CS_physical;
+ return { CS_physical, CS_energy, CS_mental };
};
-const update_ac = function() {
- console.log('update_ac');
- let update = {};
- let dr_total = 0;
- let ac_total = 0;
- let count = 0;
- let enc_attrs = ['shield_CS'];
+const update_ac = function () {
+ console.log("update_ac");
+ let update = {};
+ let dr_total = 0;
+ let ac_total = 0;
+ let count = 0;
+ let enc_attrs = ["shield_CS"];
+ getSectionIDs("repeating_armour", (armourIds) => {
+ _.each(armourIds, (currentID, i) => {
+ enc_attrs.push(`repeating_armour_${currentID}_weight`);
+ enc_attrs.push(`repeating_armour_${currentID}_count`);
+ enc_attrs.push(`repeating_armour_${currentID}_equipped`);
+ });
+ getAttrs(enc_attrs, (v) => {});
+ });
+};
+
+const update_enc = function () {
+ console.log("update_enc");
+ let update = {};
+ let wtotal = 0;
+ let DR_physical = 0;
+ let DR_energy = 0;
+ let CS = {};
+ let RFtotal = 0;
+ let CS_physical = 0;
+ let CS_mental = 0;
+ let CS_energy = 0;
+ let count = 0;
+ let PSfactor = 1;
+ let spdfactor = 1;
+ let enc_attrs = [
+ "DR_physical",
+ "DR_energy",
+ "coin_gp",
+ "coin_nk",
+ "coin_sp",
+ "coin_dm",
+ "PS",
+ "PS_rolled",
+ "PS_advanced",
+ "PS_tmp",
+ "encumbrance",
+ "encumbrance_max",
+ "speed",
+ "speed_max",
+ "burden",
+ "burden_max",
+ ];
+ getSectionIDs("repeating_gear", (gearIds) => {
+ _.each(gearIds, (currentID, i) => {
+ enc_attrs.push(`repeating_gear_${currentID}_weight`);
+ enc_attrs.push(`repeating_gear_${currentID}_count`);
+ enc_attrs.push(`repeating_gear_${currentID}_equipped`);
+ });
+
getSectionIDs("repeating_armour", (armourIds) => {
- _.each(armourIds, (currentID, i) => {
- enc_attrs.push(`repeating_armour_${currentID}_weight`);
- enc_attrs.push(`repeating_armour_${currentID}_count`);
- enc_attrs.push(`repeating_armour_${currentID}_equipped`);
- });
- getAttrs(enc_attrs, (v) => {
-
- })
- });
-};
-
-const update_enc = function() {
- console.log('update_enc');
- let update = {};
- let wtotal = 0;
- let DR_physical = 0;
- let DR_energy = 0;
- let CS = {};
- let RFtotal = 0;
- let CS_physical = 0;
- let CS_mental = 0;
- let CS_energy = 0;
- let count = 0;
- let PSfactor = 1;
- let spdfactor = 1;
- let enc_attrs = ['DR_physical', 'DR_energy', 'coin_gp', 'coin_nk', 'coin_sp', 'coin_dm', 'PS', 'PS_rolled', 'PS_advanced', 'PS_tmp', 'encumbrance', 'encumbrance_max', 'speed', 'speed_max', 'burden', 'burden_max'];
- getSectionIDs("repeating_gear", (gearIds) => {
- _.each(gearIds, (currentID, i) => {
- enc_attrs.push(`repeating_gear_${currentID}_weight`);
- enc_attrs.push(`repeating_gear_${currentID}_count`);
- enc_attrs.push(`repeating_gear_${currentID}_equipped`);
- });
-
- getSectionIDs("repeating_armour", (armourIds) => {
- _.each(armourIds, (currentID, i) => {
- enc_attrs.push(`repeating_armour_${currentID}_weight`);
- enc_attrs.push(`repeating_armour_${currentID}_count`);
- enc_attrs.push(`repeating_armour_${currentID}_equipped`);
- enc_attrs.push(`repeating_armour_${currentID}_powered`);
- enc_attrs.push(`repeating_armour_${currentID}_enc_factor`);
- enc_attrs.push(`repeating_armour_${currentID}_spd_factor`);
- enc_attrs.push(`repeating_armour_${currentID}_PS_factor`);
- enc_attrs.push(`repeating_armour_${currentID}_shield_size`);
- enc_attrs.push(`repeating_armour_${currentID}_shield_material`);
- enc_attrs.push(`repeating_armour_${currentID}_CS_mental`);
- enc_attrs.push(`repeating_armour_${currentID}_DR_energy`);
- enc_attrs.push(`repeating_armour_${currentID}_DR_physical`);
- enc_attrs.push(`repeating_armour_${currentID}_RF_physical`);
- });
- getAttrs(enc_attrs, (v) => {
-
- console.log(v);
- if (v["speed_max"] === undefined) {
- v["speed_max"] = v['speed'];
- update["speed_max"] = v['speed'];
- }
- ["coin_gp", "coin_sp", "coin_nk", "coin_dm"].forEach((type)=> {
- let coinweight = (isNaN(parseInt(v[`${type}`], 10)) === false) ? parseInt(v[`${type}`], 10) : 0;
- // use roughly correct weights for different materials as per g/cm3
- if(type === 'coin_gp') {
- wtotal += coinweight / 100
- }
- if(type === 'coin_sp') {
- wtotal += coinweight / 200
- }
- if(type === 'coin_nk') {
- wtotal += coinweight / 250
- }
- if(type === 'coin_dm') {
- wtotal += coinweight / 1000
- }
- if(type === 'coin_dl') {
- wtotal += coinweight / 1000
- }
- if(type === 'coin_db') {
- wtotal += coinweight / 1000
- }
- });
-
- _.each(gearIds, (currentID, i) => {
- if (
- v[`repeating_gear_${currentID}_weight`]
- && v[`repeating_gear_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_gear_${currentID}_weight`], 10)) === false)
- {
- count = v[`repeating_gear_${currentID}_count`] && isNaN(parseFloat(v[`repeating_gear_${currentID}_count`])) === false ? parseFloat(v[`repeating_gear_${currentID}_count`]) : 1;
- wtotal = wtotal + (parseFloat(v[`repeating_gear_${currentID}_weight`]) * count);
- }
- });
-
- _.each(armourIds, (currentID, i) => {
- if (
- v[`repeating_armour_${currentID}_weight`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_weight`], 10)) === false)
- {
- count = v[`repeating_armour_${currentID}_count`] && isNaN(parseFloat(v[`repeating_armour_${currentID}_count`])) === false ? parseFloat(v[`repeating_armour_${currentID}_count`]) : 1;
- wtotal = wtotal + (parseFloat(v[`repeating_armour_${currentID}_weight`]) * count * (isNaN(parseFloat(v[`repeating_armour_${currentID}_enc_factor`])) === false ? parseFloat(v[`repeating_armour_${currentID}_enc_factor`]) : 0.5));
- PSfactor
- = isNaN(parseFloat(v[`repeating_armour_${currentID}_PS_factor`])) === false
- ? (v[`repeating_armour_${currentID}_PS_factor`] > PSfactor ? v[`repeating_armour_${currentID}_PS_factor`] : PSfactor)
- : PSfactor;
- spdfactor
- = isNaN(parseFloat(v[`repeating_armour_${currentID}_spd_factor`])) === false
- ? (v[`repeating_armour_${currentID}_spd_factor`] > spdfactor ? v[`repeating_armour_${currentID}_spd_factor`] : spdfactor)
- : spdfactor;
- }
- // update DR_physical
- if (
- v[`repeating_armour_${currentID}_DR_physical`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_DR_physical`], 10)) === false
- ) {
- DR_physical += parseInt(v[`repeating_armour_${currentID}_DR_physical`]);
- }
- // update DR_energy
- console.log('DR_energy: ', v[`repeating_armour_${currentID}_DR_energy`]);
- if (
- v[`repeating_armour_${currentID}_DR_energy`] !== undefined
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_DR_energy`], 10)) === false
- ) {
- DR_energy += parseInt(v[`repeating_armour_${currentID}_DR_energy`]);
- } else {
- DR_energy += DR_physical;
- }
-
- // update CS
- if (
- v[`repeating_armour_${currentID}_shield_size`]
- && v[`repeating_armour_${currentID}_shield_material`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- ) {
- CS = getShieldCS(v[`repeating_armour_${currentID}_shield_size`], v[`repeating_armour_${currentID}_shield_material`] );
- CS_physical += CS.CS_physical;
- CS_mental += CS.CS_mental;
- CS_energy += CS.CS_energy;
- }
- if (
- v[`repeating_armour_${currentID}_CS_mental`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- ) {
- console.log('HELMET: '+v[`repeating_armour_${currentID}_CS_mental`] )
- CS_mental += parseInt(v[`repeating_armour_${currentID}_CS_mental`]) ;
- }
-
- // update RF
- if (
- v[`repeating_armour_${currentID}_RF_physical`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_RF_physical`], 10)) === false
- ) {
- RFtotal += parseInt(v[`repeating_armour_${currentID}_RF_physical`]);
- console.log(CS_physical);
- }
- });
- // console.log(CS_physical);
- update["RF_physical"] = RFtotal;
- update["RF_energy"] = RFtotal;
- update["CS_physical"] = CS_physical;
- update["CS_energy"] = CS_energy;
- update["CS_mental"] = CS_mental;
- update["DR_physical"] = DR_physical;
- update["DR_energy"] = DR_energy;
- update["encumbrance"] = Math.round(wtotal * 10) / 10;
- let PS = (parseInt(v["PS_rolled"])
- + parseInt(v["PS_advanced"])
- + parseInt(v["PS_tmp"])) * PSfactor;
- update['PS'] = PS;
- update["burden"] =
- (wtotal > PS*5) ? "Crushing Weight" :
- (wtotal > PS*3) ? "Immobile" :
- (wtotal > PS*2) ? "Heavily Burdened" :
- (wtotal > PS*1) ? "Burdened" :
- "Normal";
- update["speed"] =
- (wtotal > PS*3) ? 0 :
- (wtotal > PS*2) ? Math.floor((parseInt(v["speed_max"]) / 3)) :
- (wtotal > PS*1) ? Math.floor((parseInt(v["speed_max"]) /3)*2) :
- parseInt(v["speed_max"]) * spdfactor;
- console.log(update);
- setAttrs(update, {silent: true});
- update_mod('PS');
- });
- });
- });
-};
-
-const update_mod = function(ability) {
- console.log('update_mod: '+ability);
- let update = {};
- let mod = 6;
- let total = 0;
- let ps_attrs = [ability];
- getAttrs(ps_attrs, (v) => {
+ _.each(armourIds, (currentID, i) => {
+ enc_attrs.push(`repeating_armour_${currentID}_weight`);
+ enc_attrs.push(`repeating_armour_${currentID}_count`);
+ enc_attrs.push(`repeating_armour_${currentID}_equipped`);
+ enc_attrs.push(`repeating_armour_${currentID}_powered`);
+ enc_attrs.push(`repeating_armour_${currentID}_enc_factor`);
+ enc_attrs.push(`repeating_armour_${currentID}_spd_factor`);
+ enc_attrs.push(`repeating_armour_${currentID}_PS_factor`);
+ enc_attrs.push(`repeating_armour_${currentID}_shield_size`);
+ enc_attrs.push(`repeating_armour_${currentID}_shield_material`);
+ enc_attrs.push(`repeating_armour_${currentID}_CS_mental`);
+ enc_attrs.push(`repeating_armour_${currentID}_DR_energy`);
+ enc_attrs.push(`repeating_armour_${currentID}_DR_physical`);
+ enc_attrs.push(`repeating_armour_${currentID}_RF_physical`);
+ });
+ getAttrs(enc_attrs, (v) => {
console.log(v);
- console.log(v[ability]);
- total += parseInt(v[ability]);
- if(total < 601) {
- mod = 5;
+ if (v["speed_max"] === undefined) {
+ v["speed_max"] = v["speed"];
+ update["speed_max"] = v["speed"];
}
- if(total < 121) {
- mod = 4;
- }
- if(total < 22) {
- mod = 3;
- }
- if(total < 19) {
- mod = 2;
- }
- if(total < 16) {
- mod = 1;
- }
- if(total < 12) {
- mod = 0;
- }
- if(total < 10) {
- mod = -1;
- }
- if(total < 7) {
- mod = -2;
- }
- if(total < 4) {
- mod = -3;
- }
- if(total < 0) {
- mod = -4;
- }
- if(total < -6) {
- mod = -5;
- }
- if(total < -26) {
- mod = -6;
- }
- update[ability+'_modifier'] = mod;
- setAttrs(update, {silent: true});
+ ["coin_gp", "coin_sp", "coin_nk", "coin_dm"].forEach((type) => {
+ let coinweight =
+ isNaN(parseInt(v[`${type}`], 10)) === false
+ ? parseInt(v[`${type}`], 10)
+ : 0;
+ // use roughly correct weights for different materials as per g/cm3
+ if (type === "coin_gp") {
+ wtotal += coinweight / 100;
+ }
+ if (type === "coin_sp") {
+ wtotal += coinweight / 200;
+ }
+ if (type === "coin_nk") {
+ wtotal += coinweight / 250;
+ }
+ if (type === "coin_dm") {
+ wtotal += coinweight / 1000;
+ }
+ if (type === "coin_dl") {
+ wtotal += coinweight / 1000;
+ }
+ if (type === "coin_db") {
+ wtotal += coinweight / 1000;
+ }
+ });
+
+ _.each(gearIds, (currentID, i) => {
+ if (
+ v[`repeating_gear_${currentID}_weight`] &&
+ v[`repeating_gear_${currentID}_equipped`] === "1" &&
+ isNaN(parseInt(v[`repeating_gear_${currentID}_weight`], 10)) ===
+ false
+ ) {
+ count =
+ v[`repeating_gear_${currentID}_count`] &&
+ isNaN(parseFloat(v[`repeating_gear_${currentID}_count`])) ===
+ false
+ ? parseFloat(v[`repeating_gear_${currentID}_count`])
+ : 1;
+ wtotal =
+ wtotal +
+ parseFloat(v[`repeating_gear_${currentID}_weight`]) * count;
+ }
+ });
+
+ _.each(armourIds, (currentID, i) => {
+ if (
+ v[`repeating_armour_${currentID}_weight`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(parseInt(v[`repeating_armour_${currentID}_weight`], 10)) ===
+ false
+ ) {
+ count =
+ v[`repeating_armour_${currentID}_count`] &&
+ isNaN(parseFloat(v[`repeating_armour_${currentID}_count`])) ===
+ false
+ ? parseFloat(v[`repeating_armour_${currentID}_count`])
+ : 1;
+ wtotal =
+ wtotal +
+ parseFloat(v[`repeating_armour_${currentID}_weight`]) *
+ count *
+ (isNaN(
+ parseFloat(v[`repeating_armour_${currentID}_enc_factor`])
+ ) === false
+ ? parseFloat(v[`repeating_armour_${currentID}_enc_factor`])
+ : 0.5);
+ PSfactor =
+ isNaN(
+ parseFloat(v[`repeating_armour_${currentID}_PS_factor`])
+ ) === false
+ ? v[`repeating_armour_${currentID}_PS_factor`] > PSfactor
+ ? v[`repeating_armour_${currentID}_PS_factor`]
+ : PSfactor
+ : PSfactor;
+ spdfactor =
+ isNaN(
+ parseFloat(v[`repeating_armour_${currentID}_spd_factor`])
+ ) === false
+ ? v[`repeating_armour_${currentID}_spd_factor`] > spdfactor
+ ? v[`repeating_armour_${currentID}_spd_factor`]
+ : spdfactor
+ : spdfactor;
+ }
+ // update DR_physical
+ if (
+ v[`repeating_armour_${currentID}_DR_physical`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(
+ parseInt(v[`repeating_armour_${currentID}_DR_physical`], 10)
+ ) === false
+ ) {
+ DR_physical += parseInt(
+ v[`repeating_armour_${currentID}_DR_physical`]
+ );
+ }
+ // update DR_energy
+ console.log(
+ "DR_energy: ",
+ v[`repeating_armour_${currentID}_DR_energy`]
+ );
+ if (
+ v[`repeating_armour_${currentID}_DR_energy`] !== undefined &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(
+ parseInt(v[`repeating_armour_${currentID}_DR_energy`], 10)
+ ) === false
+ ) {
+ DR_energy += parseInt(v[`repeating_armour_${currentID}_DR_energy`]);
+ } else {
+ DR_energy += DR_physical;
+ }
+
+ // update CS
+ if (
+ v[`repeating_armour_${currentID}_shield_size`] &&
+ v[`repeating_armour_${currentID}_shield_material`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1"
+ ) {
+ CS = getShieldCS(
+ v[`repeating_armour_${currentID}_shield_size`],
+ v[`repeating_armour_${currentID}_shield_material`]
+ );
+ CS_physical += CS.CS_physical;
+ CS_mental += CS.CS_mental;
+ CS_energy += CS.CS_energy;
+ }
+ if (
+ v[`repeating_armour_${currentID}_CS_mental`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1"
+ ) {
+ console.log(
+ "HELMET: " + v[`repeating_armour_${currentID}_CS_mental`]
+ );
+ CS_mental += parseInt(v[`repeating_armour_${currentID}_CS_mental`]);
+ }
+
+ // update RF
+ if (
+ v[`repeating_armour_${currentID}_RF_physical`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(
+ parseInt(v[`repeating_armour_${currentID}_RF_physical`], 10)
+ ) === false
+ ) {
+ RFtotal += parseInt(v[`repeating_armour_${currentID}_RF_physical`]);
+ console.log(CS_physical);
+ }
+ });
+ // console.log(CS_physical);
+ update["RF_physical"] = RFtotal;
+ update["RF_energy"] = RFtotal;
+ update["CS_physical"] = CS_physical;
+ update["CS_energy"] = CS_energy;
+ update["CS_mental"] = CS_mental;
+ update["DR_physical"] = DR_physical;
+ update["DR_energy"] = DR_energy;
+ update["encumbrance"] = Math.round(wtotal * 10) / 10;
+ let PS =
+ (parseInt(v["PS_rolled"]) +
+ parseInt(v["PS_advanced"]) +
+ parseInt(v["PS_tmp"])) *
+ PSfactor;
+ update["PS"] = PS;
+ update["burden"] =
+ wtotal > PS * 5
+ ? "Crushing Weight"
+ : wtotal > PS * 3
+ ? "Immobile"
+ : wtotal > PS * 2
+ ? "Heavily Burdened"
+ : wtotal > PS * 1
+ ? "Burdened"
+ : "Normal";
+ update["speed"] =
+ wtotal > PS * 3
+ ? 0
+ : wtotal > PS * 2
+ ? Math.floor(parseInt(v["speed_max"]) / 3)
+ : wtotal > PS * 1
+ ? Math.floor((parseInt(v["speed_max"]) / 3) * 2)
+ : parseInt(v["speed_max"]) * spdfactor;
+ console.log(update);
+ setAttrs(update, { silent: true });
+ update_mod("PS");
+ });
});
+ });
};
-
+const update_mod = function (ability) {
+ console.log("update_mod: " + ability);
+ let update = {};
+ let mod = 6;
+ let total = 0;
+ let ps_attrs = [ability];
+ getAttrs(ps_attrs, (v) => {
+ console.log(v);
+ console.log(v[ability]);
+ total += parseInt(v[ability]);
+ if (total < 601) {
+ mod = 5;
+ }
+ if (total < 121) {
+ mod = 4;
+ }
+ if (total < 22) {
+ mod = 3;
+ }
+ if (total < 19) {
+ mod = 2;
+ }
+ if (total < 16) {
+ mod = 1;
+ }
+ if (total < 12) {
+ mod = 0;
+ }
+ if (total < 10) {
+ mod = -1;
+ }
+ if (total < 7) {
+ mod = -2;
+ }
+ if (total < 4) {
+ mod = -3;
+ }
+ if (total < 0) {
+ mod = -4;
+ }
+ if (total < -6) {
+ mod = -5;
+ }
+ if (total < -26) {
+ mod = -6;
+ }
+ update[ability + "_modifier"] = mod;
+ setAttrs(update, { silent: true });
+ });
+};
//------ Events ---------
-on("sheet:opened", function(eventinfo) {
- console.log('sheet:opened');
+on("sheet:opened", function (eventinfo) {
+ console.log("sheet:opened");
});
-on("change:import", function(args) {
- console.log('sheet:import',args);
-
+on("change:import", function (args) {
+ console.log("sheet:import", args);
});
-on("change:PS_rolled", function(args) {
- console.log('change:PS_rolled')
- update_ability('PS');
+on("change:PS_rolled", function (args) {
+ console.log("change:PS_rolled");
+ update_ability("PS");
});
-on("change:PS_advanced", function(args) {
- console.log('change:PS_advanced')
- update_ability('PS');
+on("change:PS_advanced", function (args) {
+ console.log("change:PS_advanced");
+ update_ability("PS");
});
-on("change:PS_tmp", function(args) {
- console.log('change:PS_tmp')
- update_ability('PS');
+on("change:PS_tmp", function (args) {
+ console.log("change:PS_tmp");
+ update_ability("PS");
});
-on("change:PS", function(args) {
- console.log('PS changed');
- update_mod('PS');
- update_enc();
+on("change:PS", function (args) {
+ console.log("PS changed");
+ update_mod("PS");
+ update_enc();
});
-on("change:DX_rolled", function(args) {
- console.log('change:DX_rolled')
- update_ability('DX');
+on("change:DX_rolled", function (args) {
+ console.log("change:DX_rolled");
+ update_ability("DX");
});
-on("change:DX_advanced", function(args) {
- console.log('change:DX_advanced')
- update_ability('DX');
+on("change:DX_advanced", function (args) {
+ console.log("change:DX_advanced");
+ update_ability("DX");
});
-on("change:DX_tmp", function(args) {
- console.log('change:DX_tmp')
- update_ability('DX');
+on("change:DX_tmp", function (args) {
+ console.log("change:DX_tmp");
+ update_ability("DX");
});
-on("change:DX", function(args) {
- console.log('DX changed');
- update_mod('DX');
+on("change:DX", function (args) {
+ console.log("DX changed");
+ update_mod("DX");
});
-on("change:CN_rolled", function(args) {
- console.log('change:CN_rolled')
- update_ability('CN');
+on("change:CN_rolled", function (args) {
+ console.log("change:CN_rolled");
+ update_ability("CN");
});
-on("change:CN_advanced", function(args) {
- console.log('change:CN_advanced')
- update_ability('CN');
+on("change:CN_advanced", function (args) {
+ console.log("change:CN_advanced");
+ update_ability("CN");
});
-on("change:CN_tmp", function(args) {
- console.log('change:CN_tmp')
- update_ability('CN');
+on("change:CN_tmp", function (args) {
+ console.log("change:CN_tmp");
+ update_ability("CN");
});
-on("change:CN", function(args) {
- console.log('CN changed');
- update_mod('CN');
+on("change:CN", function (args) {
+ console.log("CN changed");
+ update_mod("CN");
});
-on("change:IN_rolled", function(args) {
- console.log('change:IN_rolled')
- update_ability('IN');
+on("change:IN_rolled", function (args) {
+ console.log("change:IN_rolled");
+ update_ability("IN");
});
-on("change:IN_advanced", function(args) {
- console.log('change:IN_advanced')
- update_ability('IN');
+on("change:IN_advanced", function (args) {
+ console.log("change:IN_advanced");
+ update_ability("IN");
});
-on("change:IN_tmp", function(args) {
- console.log('change:IN_tmp')
- update_ability('IN');
+on("change:IN_tmp", function (args) {
+ console.log("change:IN_tmp");
+ update_ability("IN");
});
-on("change:IN", function(args) {
- console.log('IN changed');
- update_mod('IN');
+on("change:IN", function (args) {
+ console.log("IN changed");
+ update_mod("IN");
});
-on("change:MS_rolled", function(args) {
- console.log('change:MS_rolled')
- update_ability('MS');
+on("change:MS_rolled", function (args) {
+ console.log("change:MS_rolled");
+ update_ability("MS");
});
-on("change:MS_advanced", function(args) {
- console.log('change:MS_advanced')
- update_ability('MS');
+on("change:MS_advanced", function (args) {
+ console.log("change:MS_advanced");
+ update_ability("MS");
});
-on("change:MS_tmp", function(args) {
- console.log('change:MS_tmp')
- update_ability('MS');
+on("change:MS_tmp", function (args) {
+ console.log("change:MS_tmp");
+ update_ability("MS");
});
-on("change:MS", function(args) {
- console.log('MS changed');
- update_mod('MS');
+on("change:MS", function (args) {
+ console.log("MS changed");
+ update_mod("MS");
});
-on("change:CH_rolled", function(args) {
- console.log('change:CH_rolled')
- update_ability('CH');
+on("change:CH_rolled", function (args) {
+ console.log("change:CH_rolled");
+ update_ability("CH");
});
-on("change:CH_advanced", function(args) {
- console.log('change:CH_advanced')
- update_ability('CH');
+on("change:CH_advanced", function (args) {
+ console.log("change:CH_advanced");
+ update_ability("CH");
});
-on("change:CH_tmp", function(args) {
- console.log('change:CH_tmp')
- update_ability('CH');
+on("change:CH_tmp", function (args) {
+ console.log("change:CH_tmp");
+ update_ability("CH");
});
-on("change:CH", function(args) {
- console.log('CH changed');
- update_mod('CH');
+on("change:CH", function (args) {
+ console.log("CH changed");
+ update_mod("CH");
});
-on("change:repeating_gear", function(args) {
- update_enc();
+on("change:repeating_gear", function (args) {
+ update_enc();
});
-on("change:repeating_armour", function(args) {
- console.log('change:repeating_armour');
- update_enc();
- // update_ac();
+on("change:repeating_armour", function (args) {
+ console.log("change:repeating_armour");
+ update_enc();
+ // update_ac();
});
-on("change:coin_gp", function(args) {
- update_enc();
+on("change:coin_gp", function (args) {
+ update_enc();
});
-on("change:coin_nk", function(args) {
- update_enc();
+on("change:coin_nk", function (args) {
+ update_enc();
});
-on("change:coin_dm", function(args) {
- update_enc();
+on("change:coin_dm", function (args) {
+ update_enc();
});
-on("change:coin_sp", function(args) {
- update_enc();
+on("change:coin_sp", function (args) {
+ update_enc();
});
-on("change:rollSwitch", function(args) {
- console.log(args);
- let update = {};
- if(args.newValue == "0") {
- update['PS_rolled'] = 0;
- update['IN_rolled'] = 0;
- update['CN_rolled'] = 0;
- update['IN_rolled'] = 0;
- update['MS_rolled'] = 0;
- update['CH_rolled'] = 0;
- } else {
- update['PS_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['DX_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['CN_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['IN_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['MS_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['CH_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- }
- setAttrs(update, {silent: true});
-
- update_ability('PS');
- update_ability('DX');
- update_ability('CN');
- update_ability('IN');
- update_ability('MS');
- update_ability('CH');
+on("change:rollSwitch", function (args) {
+ console.log(args);
+ let update = {};
+ if (args.newValue == "2") { return }
+ if (args.newValue == "1") {
+ update["PS_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["DX_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["CN_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["IN_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["MS_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["CH_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ }
+
+ if (args.newValue == "0") {
+ update["PS_rolled"] = 0;
+ update["DX_rolled"] = 0;
+ update["IN_rolled"] = 0;
+ update["CN_rolled"] = 0;
+ update["IN_rolled"] = 0;
+ update["MS_rolled"] = 0;
+ update["CH_rolled"] = 0;
+ }
+ setAttrs(update, { silent: true });
- update_mod('PS');
- update_mod('DX');
- update_mod('CN');
- update_mod('IN');
- update_mod('MS');
- update_mod('CH');
+ update_ability("PS");
+ update_ability("DX");
+ update_ability("CN");
+ update_ability("IN");
+ update_ability("MS");
+ update_ability("CH");
+ update_mod("PS");
+ update_mod("DX");
+ update_mod("CN");
+ update_mod("IN");
+ update_mod("MS");
+ update_mod("CH");
});
-
-on("change:hpRollSwitch", function(args) {
- let update = {};
- if(args.newValue == "0") {
- update['hp_max'] = 0;
- } else {
- let rank, CN;
- getAttrs(['character_rank', 'CN'], (v) => {
- rank = v['character_rank'];
- CN = v['CN'];
- });
-
- update['hp_max'] = dices.roll(`${CN}d6+${CN}`).total;
- setAttrs(update, {silent: true});
- }
+on("change:hpRollSwitch", function (args) {
+ console.log("change:hpRollSwitch");
+ console.log(args);
+ let update = {};
+ if (args.newValue == "0") {
+ console.log("set hp_max to zero");
+ update["hp_max"] = 0;
+ setAttrs(update, { silent: true });
+ } else {
+ let rank, CN;
+ getAttrs(["character_rank", "CN"], (v) => {
+ console.log("v", v);
+ rank = v["character_rank"];
+ CN = v["CN"];
+ update["hp_max"] = dices.roll(`${CN}d6+${CN}`).total;
+ setAttrs(update, { silent: true });
+ });
+ }
});
+
\ No newline at end of file
diff --git a/GammaWorld3e/sheet.json b/GammaWorld3e/sheet.json
index 04bf56360e..0cbb2b6e9f 100644
--- a/GammaWorld3e/sheet.json
+++ b/GammaWorld3e/sheet.json
@@ -3,7 +3,7 @@
"css": "styles.css",
"authors": "Noel da Costa",
"roll20userid": "3920005",
- "instructions": "# Instructions/r/r## Using the sheet/r/r### Overview/r/rThis sheet is for use with the GammaWorld 3rd edition rules./r/r### Abilities/r/r3e required that character abilities be rolled randomly. This is currently a requirement on the sheet -Â you can't edit your attributes directly. To roll your character's abilities, click on the `Roll-up` tab, here you can roll attributes and hitpoints. If you wish to re-roll you need to first click `Reset`./r/r- Adv. - This represents your character's advancement through XP. If you take your ability scores up with XP add the amount in this field./r- Tmp. - Any temporary modifiers to an ability score should be entered in this field/r- Mod. - The ability modifier is calculated automatically/r/r### Combat Stats/r/r#### Defence/r/rNote that this is a slight departure from the original character sheets included with the rules in that it splits defence ratings across `energy`, `physical` and `mental`. These were implied in the rules but not fully represented on the PnP character sheet. These are calculated values based on Gear, Armour and Mutation entries./r/r- _CS_: Column Shift/r- _RF_: Result Factor/r- _DR_: Damage Reduction",
+ "instructions": "This sheet is for use with the GammaWorld 3rd edition rules. Character abilities must be rolled randomly, this is currently a requirement on the sheet - you cannot edit your attributes directly. To roll your character's abilities, click on the `Roll-up` tab, here you can roll attributes and hitpoints. If you wish to re-roll you need to first click `Reset`. Note that this is a slight departure from the original character sheets included with the rules in that it splits defence ratings across `energy`, `physical` and `mental`. These were implied in the rules but not fully represented on the PnP character sheet. These are calculated values based on Gear, Armour and Mutation entries. CS: Column Shift RF: Result Factor DR: Damage Reduction",
"preview": "GW3-sheet.png",
"legacy": true
}
\ No newline at end of file
diff --git a/GammaWorld3e/src/api-scripts/companion.js b/GammaWorld3e/src/api-scripts/companion.js
index 1574992bdf..396083ca71 100644
--- a/GammaWorld3e/src/api-scripts/companion.js
+++ b/GammaWorld3e/src/api-scripts/companion.js
@@ -48,8 +48,7 @@ function empty(mixedVar) {
return false;
}
-// @license: GammaWorld compendium not included for licensing reasons, but you can create your own, contact me for advice on how
-// import compendium from './compendium'
+import compendium from "./compendium";
var GW3Companion =
GW3Companion ||
@@ -63,10 +62,12 @@ var GW3Companion =
// Styling for the chat responses.
const styles = {
reset: "padding: 0; margin: 0;",
+ menuborder:
+ "border: 0px solid transparent; border-radius: 4px; padding: 6px; background: red;",
menu:
- "background-color: #fff; border: 1px dashed #ae2400; padding: 5px 5px 10px 5px; border-radius: 5px;",
+ "background-color: #f1f1f1; border: 5px solid transparent; padding: 6px 5px 10px 5px; border-radius: 4px;",
button:
- "background-color: #000; border: 1px solid #292929; border-radius: 3px; padding: 5px; color: #fff; text-align: center;",
+ "background-color: #000; border: 1px solid #292929; border-radius: 3px; padding: 5px; color: #f1f1f1; text-align: center;",
list: "list-style: none;",
float: {
right: "float: right;",
@@ -83,6 +84,10 @@ var GW3Companion =
fullWidth: "width: 100%;",
underline: "text-decoration: underline;",
strikethrough: "text-decoration: strikethrough",
+ border:
+ "margin-top: 1rem; border: 1px solid #aaa; padding: 1rem; border-radius: 5px;",
+ description:
+ "font-weight: normal; margin-top: 5px; border: 1px solid grey; padding: 1rem; border-radius: 5px; background-color: #aaa; color: white;",
effect:
"font-weight: bold; margin-top: 5px; border: 1px solid grey; padding: 1rem; border-radius: 5px; background-color: #aaa; color: white;",
},
@@ -217,6 +222,7 @@ var GW3Companion =
log(msg);
log("GM issued " + script_name + " msg: " + msg.content);
log("GM issued " + script_name + " command: " + command);
+ log("state config", state[state_name].config.command);
if (command == state[state_name].config.command) {
switch (extracommand) {
case "reset":
@@ -294,10 +300,14 @@ var GW3Companion =
case "act":
log("ACT roll");
if (args.length > 0) {
+ log("args obj...");
log(args);
// Get main settings
let rankSetting = args.shift().split("|");
+ log("rankSetting...");
+ log(rankSetting);
let rank = rankSetting.shift();
+ log("rank: ", rank);
let roll1 = rankSetting[0];
let roll2 = rankSetting[1];
@@ -306,6 +316,7 @@ var GW3Companion =
log("parameters: ");
log(parameters);
log("act passed rank: " + rank);
+ log("roll1 & roll2...");
log(roll1);
log(roll2);
// log(value);
@@ -326,14 +337,21 @@ var GW3Companion =
break;
case "category":
log("category");
+ log("args length:" + args.length);
if (args.length > 0) {
let category = args.shift();
+ log("category: " + category);
let cost = 0;
data = getData();
+ if (!data) {
+ return;
+ }
+ log("got data");
listItems = [];
let items = Object.keys(data[category]);
let subcat = {};
let header = "";
+ log("got items");
_.each(items, (item) => {
// render type headers
if (data[category][item].type) {
@@ -394,8 +412,18 @@ var GW3Companion =
case "compendium":
log("compendium");
data = getData();
+ if (!data) {
+ return;
+ }
listItems = [];
- let categories = ["armour", "attacks", "gear", "mutations"];
+ let categories = [
+ "armour",
+ "attacks",
+ "gear",
+ "mutations",
+ "skills",
+ "talents",
+ ];
_.each(categories, (category) => {
button = makeButton(
ucFirst(category),
@@ -484,10 +512,20 @@ var GW3Companion =
}
return { colour, RF, background };
},
+ /**
+ * @param {object} msg the msg object from chat window
+ * @param {string} rank the rank column to roll against
+ * @param {object} parameters the message content parsed as key, value pairs
+ * @param {Number} roll1 the ability ACT roll (i.e. number from 1 - 100)
+ * @param {Number} roll2 the save ACT roll (i.e. number from 1 - 100)
+ */
rollAct = (msg, rank, parameters = {}, roll1, roll2) => {
const self = this;
log("rollACT: " + rank);
const data = getData();
+ if (!data) {
+ return;
+ }
let save,
rankHTML = "",
effectType = "effect",
@@ -497,7 +535,8 @@ var GW3Companion =
colorResult = {},
effectName = "",
category = parameters["category"],
- dmgTotalString = "";
+ dmgTotalString = "",
+ orig_rank = parseInt(rank);
rank = parseInt(rank);
rankHTML = `
${rank} `;
sendChat(msg.playerid, "/roll 2d100", function (ops) {
@@ -517,9 +556,9 @@ var GW3Companion =
log("roll1: " + roll1);
log("roll2: " + roll2);
if (parameters["mod"]) {
- // log('calculating rank based on mod');
+ // log('calculating rank based on modifier');
// log(parameters['character']);
- // log(`${parameters['mod']}_mod`);
+ // log(`${parameters['modifier']}_mod`);
// log(getAttrByName(parameters['character'], 'PS_modifier'));
const mod = parseInt(
@@ -532,9 +571,9 @@ var GW3Companion =
rank += mod;
}
if (parameters["character"]) {
+ character = getObj("character", parameters["character"]);
log("character: ");
log(character);
- character = getObj("character", parameters["character"]);
}
if (parameters["CS"]) {
log("calculating rank based on CS: " + parseInt(parameters["CS"]));
@@ -585,18 +624,92 @@ var GW3Companion =
// log(attribute);
// });
}
+
// minus target's DX mod for melee attacks
- if (
- parameters["category"] === "attacks" &&
- parameters["type"] === "melee"
- ) {
- let targetDXmod = getAttrByName(
- targetCharacter.id,
- "DX_modifier"
+ if (parameters["category"] === "attacks") {
+ let character_rank = parseInt(
+ getAttrByName(character.id, "character_rank")
);
- log("targetDXmod: " + targetDXmod);
- rankHTML += ` -
${targetDXmod} `;
- rank -= parseInt(targetDXmod);
+ log("character");
+ log(character);
+ log("talents");
+
+ rank += character_rank;
+ rankHTML += ` +
${character_rank} `;
+ if (parameters["type"] === "melee") {
+ let targetDXmod = getAttrByName(
+ targetCharacter.id,
+ "DX_modifier"
+ );
+ log("targetDXmod: " + targetDXmod);
+ rankHTML += ` -
${targetDXmod} `;
+ rank -= parseInt(targetDXmod);
+ }
+ if (parameters["type"] === "throwing") {
+ let throwingTalent = filterObjs(
+ (a) =>
+ a.get("type") === "attribute" &&
+ a.get("characterid") === character.id &&
+ /^repeating_talents_[^_]*_ref$/.test(a.get("name")) &&
+ a.get("current") === "throwing"
+ );
+ if (throwingTalent.length) {
+ rankHTML += ` +
${character_rank} `;
+ rank += character_rank;
+ }
+ }
+ if (parameters["type"] === "shooting") {
+ let shootingTalent = filterObjs(
+ (a) =>
+ a.get("type") === "attribute" &&
+ a.get("characterid") === character.id &&
+ /^repeating_talents_[^_]*_ref$/.test(a.get("name")) &&
+ a.get("current") === "shooting"
+ );
+ if (shootingTalent.length) {
+ rankHTML += ` +
${character_rank} `;
+ rank += character_rank;
+ }
+ }
+ if (parameters["type"] === "grappling") {
+ let grapplingTalent = filterObjs(
+ (a) =>
+ a.get("type") === "attribute" &&
+ a.get("characterid") === character.id &&
+ /^repeating_talents_[^_]*_ref$/.test(a.get("name")) &&
+ a.get("current") === "grappling"
+ );
+ if (grapplingTalent.length) {
+ rankHTML += ` +
${character_rank} `;
+ rank += character_rank;
+ }
+ }
+ if (parameters["type"] === "martialarts") {
+ let martialartsTalent = filterObjs(
+ (a) =>
+ a.get("type") === "attribute" &&
+ a.get("characterid") === character.id &&
+ /^repeating_talents_[^_]*_ref$/.test(a.get("name")) &&
+ a.get("current") === "martialarts"
+ );
+ if (martialartsTalent.length) {
+ rankHTML += ` +
${character_rank} `;
+ rank += character_rank;
+ }
+ }
+ if (parameters["type"] === "brawling") {
+ let brawlingTalent = filterObjs(
+ (a) =>
+ a.get("type") === "attribute" &&
+ a.get("characterid") === character.id &&
+ /^repeating_talents_[^_]*_ref$/.test(a.get("name")) &&
+ a.get("current") === "brawling"
+ );
+ if (brawlingTalent.length) {
+ rankHTML += ` +
${character_rank} `;
+ rank += character_rank;
+ }
+ }
}
}
@@ -617,7 +730,7 @@ var GW3Companion =
}
colorResult = getRollColour(roll1, row);
- // log('color: ' + colour);
+ log("colorResult: " + colorResult);
// log('background: ' + background);
// log('RC: ' + background);
// log('RF: ' + RF);
@@ -643,36 +756,53 @@ var GW3Companion =
"damage parameter: " +
parameters["dmg"] +
" - " +
- parameters["damage_type"]
+ parameters["dmg_type"]
);
- let baseDmg,
+ let baseDmg = 0,
DR = 0,
- soaked;
- if (parameters["dmg"] === "mutation") {
- baseDmg = parseInt(rank) / 2;
+ dmgAfterDRsoak = 0;
+ if (parameters["dmg"] === "mutation" || parameters["dmg"] === "M") {
+ baseDmg = parseInt(orig_rank) / 2;
} else if (parameters["dmg"].includes("/")) {
+ //- cater for damage ratings for different sizes
let dmg = parameters["dmg"].split("/");
log("dmg: ");
log(dmg);
let size =
getAttrByName(targetCharacter.id, "character_size") || 3;
log("size: " + size);
- baseDmg = parseInt(size) < 4 ? dmg[0] : dmg[1];
+ baseDmg =
+ parseInt(size) < 4 ? parseInt(dmg[0]) : parseInt(dmg[1]);
+ log("baseDmg after size: " + baseDmg);
+ if (_.isNaN(baseDmg)) baseDmg = 0;
} else {
baseDmg = parseInt(parameters["dmg"]);
+ if (_.isNaN(baseDmg)) baseDmg = 0;
}
+
+ if (parameters["category"] === "attacks") {
+ if (parameters["skilldmg"]) {
+ log("baseDmg orig_rank: " + orig_rank);
+ log("baseDmg before skilldmg: " + baseDmg);
+ baseDmg += parseInt(orig_rank);
+ log("baseDmg after skilldmg: " + baseDmg);
+ }
+ }
+
log("baseDMG: " + baseDmg);
log("RF: " + colorResult.RF);
DR = getAttrByName(targetCharacter.id, "DR_physical") || 0;
log("DR: " + DR);
+ log("DR in: " + parseInt(DR));
let dmgTotal = parseInt(colorResult.RF) * parseInt(baseDmg);
- if (DR) {
- soaked = dmgTotal + parseInt(DR);
- }
- soaked = soaked < 1 ? 0 : soaked;
+ if (_.isNaN(dmgTotal)) dmgTotal = 0;
+ dmgAfterDRsoak = dmgTotal;
+ dmgAfterDRsoak += parseInt(DR);
+ dmgAfterDRsoak = dmgAfterDRsoak < 1 ? 0 : dmgAfterDRsoak;
log("dmgTotal: " + dmgTotal);
- dmgTotalString = `Physical Damage:
${soaked} `;
+ log("dmgAfterDRsoak: " + dmgAfterDRsoak);
+ dmgTotalString = `Physical Damage:
${dmgAfterDRsoak} `;
}
content += makeResult(
@@ -698,35 +828,70 @@ var GW3Companion =
}
};
- // check save from item or from damage type
- if (parameters["damage_type"]) {
- if (data["damage_types"][parameters["damage_type"]]) {
- if (data["damage_types"][parameters["damage_type"]]["save"]) {
- save = data["damage_types"][parameters["damage_type"]].save;
+ // show ability description
+ if (parameters["describe"] === "on") {
+ const description = _.defaults(
+ data[parameters["category"]][parameters["id"]],
+ { description: false }
+ ).description;
+ if (description) {
+ content += `
${description}
`;
+ }
+ }
+
+ if (parameters["save"]) {
+ save = parameters["save"];
+ }
+ let effectsContent = "";
+ // override save type from damage type
+ if (parameters["dmg_type"]) {
+ log(
+ "Damage Type: " +
+ data["damage_types"][parameters["dmg_type"]].name
+ );
+ if (data["damage_types"][parameters["dmg_type"]]) {
+ if (data["damage_types"][parameters["dmg_type"]].save) {
+ save = data["damage_types"][parameters["dmg_type"]].save;
+ }
+ if (data["damage_types"][parameters["dmg_type"]].effect_crit) {
+ parameters["effect_crit"] =
+ data["damage_types"][parameters["dmg_type"]].effect_crit;
+ }
+ if (data["damage_types"][parameters["dmg_type"]].effect) {
+ parameters["effect"] =
+ data["damage_types"][parameters["dmg_type"]].effect;
+ }
+ if (data["damage_types"][parameters["dmg_type"]].description) {
+ content += `
Damage Type: ${
+ data["damage_types"][parameters["dmg_type"]].name
+ } ${
+ data["damage_types"][parameters["dmg_type"]].description
+ }
`;
}
}
}
if (parameters["effect"]) {
effectName = parameters["effect"];
+ log("effect name: " + effectName);
if (
!empty(data.effects) &&
!empty(data.effects[parameters["effect"]])
) {
- effectName = data.effects[parameters["effect"]].name;
+ effectDisplayName = data.effects[parameters["effect"]].name;
+ log("effect name: " + effectDisplayName);
// let result = getEffectResult(parameters['effect'], colorResult.background);
- content += `
Effect:
${effectName}
`;
+ content += `
Effect:
${effectDisplayName}
`;
} else if (
!empty(data.damage_types) &&
data.damage_types[parameters["effect"]]
) {
- log(
- "damage_type based on effect: " +
- parameters["effect"] +
- ", " +
- data.damage_types[parameters["effect"]]
- );
- content += `
Effect: Critical Effect: ${
data.effects[parameters["effect_crit"]].name
}
`;
- } else if (data.damage_types[parameters["effect_crit"]]) {
- log(data.damage_types);
- log(parameters["effect_crit"]);
- log(data.damage_types[parameters["effect_crit"]]);
- content += `
Critical Effect: ${
- data.damage_types[parameters["effect_crit"]].name
- }
`;
- save = data.damage_types[parameters["effect_crit"]].save;
}
+ // else if (data.damage_types[parameters["effect_crit"]]) {
+ // log("Crit effect according to Damage Type");
+ // log(data.damage_types);
+ // log(parameters["effect_crit"]);
+ // log(data.damage_types[parameters["effect_crit"]]);
+ // content += `
Critical Effect: ${
+ // data.damage_types[parameters["effect_crit"]].name
+ // }
`;
+ // save = data.damage_types[parameters["effect_crit"]].save;
+ // content += renderSaveRoll(
+ // save,
+ // targetCharacter,
+ // roll2,
+ // parameters,
+ // effectType,
+ // colorResult,
+ // effectName
+ // );
+ // }
}
}
-
- if (parameters["save"]) {
- save = save || parameters["save"];
- let saveScore = getAttrByName(targetCharacter.id, `${save}`);
- let effectsActRow = getActRow(saveScore);
- let effectsColorResult = getRollColour(roll2, effectsActRow);
- let effectsResult = { result: effectsColorResult.background };
- let result = "";
- log("effectType: " + effectType);
- log(parameters[effectType]);
- if (!empty(data.effects) && data.effects[parameters[effectType]]) {
- effectsResult = getEffectResult(
- parameters[effectType],
- effectsColorResult.background
- );
- }
- result = effectsResult.result;
- let success =
- parseInt(effectsColorResult.RF) >= parseInt(colorResult.RF);
- let successMessage = success
- ? `
success `
- : `
fail `;
- content += `
Save (${effectName}): ${result} ${successMessage}
`;
+ if (!empty(save)) {
+ content += renderSaveRoll(
+ save,
+ targetCharacter,
+ roll2,
+ parameters,
+ effectType,
+ colorResult,
+ effectsContent
+ );
+ } else {
+ log('Will not render Save as the "save" parameter was not set.');
}
send(msg, parameters, title, content);
});
},
+ renderSaveRoll = (
+ save,
+ targetCharacter,
+ roll2,
+ parameters,
+ effectType,
+ colorResult,
+ effectsContent
+ ) => {
+ const data = getData();
+ if (!data) {
+ return;
+ }
+ log("START renderSaveRoll");
+ let saveScore = getAttrByName(targetCharacter.id, `${save}`);
+ log("saveScore: " + saveScore);
+ let effectsActRow = getActRow(saveScore);
+ log("effectsActRow");
+ log(effectsActRow);
+ let effectsColorResult = getRollColour(roll2, effectsActRow);
+ let effectsResult = { result: effectsColorResult.background };
+ let result = "";
+ if (!empty(data.effects) && data.effects[parameters[effectType]]) {
+ effectsResult = getEffectResult(
+ parameters[effectType],
+ effectsColorResult.background
+ );
+ }
+ result = effectsResult.result;
+ let success =
+ parseInt(effectsColorResult.RF) >= parseInt(colorResult.RF);
+ let successMessage = success
+ ? `
success `
+ : `
fail `;
+
+ log("END renderSaveRoll");
+ let content = `
Save vs. ${save}: ${result} ${successMessage}
`;
+ if (!success) {
+ content += effectsContent;
+ }
+ return content;
+ },
getActRow = (rank) => {
log("getActRow");
rank = parseInt(rank);
@@ -799,27 +1009,27 @@ var GW3Companion =
A: [18, 74, 99, null, null, 100],
B: [17, 73, 98, 99, null, 100],
C: [16, 72, 97, 99, null, 100],
- "1": [15, 71, 96, 98, 99, 100],
- "2": [14, 69, 94, 97, 99, 100],
- "3": [13, 68, 93, 97, 97, 100],
- "4": [12, 66, 91, 96, 97, 100],
- "5": [11, 62, 87, 93, 97, 99],
- "6": [10, 60, 85, 92, 96, 99],
- "7": [9, 58, 83, 91, 96, 99],
- "8": [8, 56, 80, 89, 95, 99],
- "9": [7, 54, 78, 88, 93, 99],
- "10": [6, 52, 75, 86, 92, 99],
- "11": [5, 49, 71, 83, 91, 98],
- "12": [5, 47, 68, 81, 90, 98],
- "13": [4, 44, 65, 79, 89, 98],
- "14": [4, 42, 62, 77, 88, 98],
- "15": [4, 40, 58, 75, 87, 98],
- "16": [3, 37, 53, 72, 86, 97],
- "17": [3, 35, 49, 70, 85, 97],
- "18": [3, 33, 45, 68, 84, 97],
- "19": [3, 30, 41, 66, 83, 97],
- "20": [2, 26, 36, 63, 82, 96],
- "21": [2, 23, 32, 61, 81, 96],
+ 1: [15, 71, 96, 98, 99, 100],
+ 2: [14, 69, 94, 97, 99, 100],
+ 3: [13, 68, 93, 97, 97, 100],
+ 4: [12, 66, 91, 96, 97, 100],
+ 5: [11, 62, 87, 93, 97, 99],
+ 6: [10, 60, 85, 92, 96, 99],
+ 7: [9, 58, 83, 91, 96, 99],
+ 8: [8, 56, 80, 89, 95, 99],
+ 9: [7, 54, 78, 88, 93, 99],
+ 10: [6, 52, 75, 86, 92, 99],
+ 11: [5, 49, 71, 83, 91, 98],
+ 12: [5, 47, 68, 81, 90, 98],
+ 13: [4, 44, 65, 79, 89, 98],
+ 14: [4, 42, 62, 77, 88, 98],
+ 15: [4, 40, 58, 75, 87, 98],
+ 16: [3, 37, 53, 72, 86, 97],
+ 17: [3, 35, 49, 70, 85, 97],
+ 18: [3, 33, 45, 68, 84, 97],
+ 19: [3, 30, 41, 66, 83, 97],
+ 20: [2, 26, 36, 63, 82, 96],
+ 21: [2, 23, 32, 61, 81, 96],
X: [2, 20, 27, 59, 80, 96],
Y: [2, 17, 22, 56, 78, 95],
Z: [2, 13, 16, 51, 76, 94],
@@ -973,21 +1183,23 @@ var GW3Companion =
}
if (category === "attacks" || category === "ammo") {
if (category === "attacks") {
- let character_rank = parseInt(
- getAttrByName(character.id, "character_rank")
- );
- log("character rank:" + character_rank);
- if (character_rank === NaN) {
- log(
- "character rank was not found and thus the attack rank could not be accurately determined and will default to 1"
- );
- character_rank = 1;
- }
- let obj = Object.assign(objTemplate, {
- name: `repeating_${category}_${rowId}_rank`,
- current: character_rank,
- });
- createObj("attribute", obj);
+ //@deprecated: Attack ranks are distinct from Character ranks
+ // log("import attack");
+ // let character_rank = parseInt(
+ // getAttrByName(character.id, "character_rank")
+ // );
+ // log("character rank:" + character_rank);
+ // if (_.isNaN(character_rank)) {
+ // log(
+ // "character rank was not found and thus the attack rank could not be accurately determined and will default to 1"
+ // );
+ // character_rank = 1;
+ // }
+ // let obj = Object.assign(objTemplate, {
+ // name: `repeating_${category}_${rowId}_rank`,
+ // current: character_rank,
+ // });
+ // createObj("attribute", obj);
}
// also add it to gear
_.each(itemAttributes, (attributeValue, attributeName) => {
@@ -1138,13 +1350,13 @@ var GW3Companion =
sendChat(
script_name,
whisper +
- '
' +
title +
contents +
- "
",
+ "
",
null,
{
noarchive: true,
@@ -1160,13 +1372,13 @@ var GW3Companion =
sendChat(
`${type}|${id}`,
whisper +
- '
' +
title +
contents +
- "
",
+ "
",
null,
{
noarchive: true,
@@ -1261,6 +1473,10 @@ var GW3Companion =
}
},
getData = () => {
+ if (typeof compendium === "undefined") {
+ log("The compendium is not installed");
+ return false;
+ }
return compendium;
// return {}
};
diff --git a/GammaWorld3e/src/scss/partials/sheet.scss b/GammaWorld3e/src/scss/partials/sheet.scss
index 9ff30128fa..de3a03cc30 100644
--- a/GammaWorld3e/src/scss/partials/sheet.scss
+++ b/GammaWorld3e/src/scss/partials/sheet.scss
@@ -72,14 +72,19 @@ input.sheet-pageToggle:not([value="3"]) ~ .sheet-tab3 {
/**********************
Roll-up
***********************/
-input.sheet-rollSwitch:not([value="0"]) ~ .sheet-pre-rolled {
+input.sheet-rollSwitch[value="0"] ~ .sheet-tab-score-roll, input.sheet-rollSwitch[value="0"] ~ .sheet-tab-score-input {
display:none
}
-input.sheet-rollSwitch:not([value="1"]) ~ .sheet-post-rolled {
+input.sheet-rollSwitch[value="1"] ~ .sheet-tab-score-input {
display:none
}
+input.sheet-rollSwitch[value="2"] ~ .sheet-tab-score-roll {
+ display: none;
+}
+
+
/**********************
diff --git a/GammaWorld3e/src/sheet.html b/GammaWorld3e/src/sheet.html
new file mode 100644
index 0000000000..315b11be3b
--- /dev/null
+++ b/GammaWorld3e/src/sheet.html
@@ -0,0 +1,797 @@
+
Gamma World 3e PC Monster Roll-up Size:
Tiny Small Medium Large Huge
Type:
Pure Strain Human Mutated Human Mutated Animal Mutated Plant
Physical Abilities
Cur.
Orig.
Adv.
Tmp.
Mod.
Roll
Mental Abilities
Cur.
Orig.
Adv.
Tmp.
Mod.
Roll
Mutations y Mod.
PS DX CN IN MS CH
Targets
Effort
Subconscious Conscious
Effect
None AC Critical Burn Cold Comp. A Comp. C Critical Delirium Disintegrate Domination Electrical Fatal Field Negate Fumes Heat Hits +1RF Ignites Ignores AC Intercept Irritant Knock Down Knock Out Mutate Paralysis Poison Power Drain Radiation Scatter Seeker Short Out Slam Sonic Stun Subsonics Tangle
Critical
None AC Critical Burn Cold Comp. A Comp. C Critical Delirium Disintegrate Domination Electrical Fatal Field Negate Fumes Heat Hits +1 RF Ignites Ignores AC Intercept Irritant Knock Down Knock Out Mutate Paralysis Poison Power Drain Radiation Scatter Seeker Short Out Slam Sonic Stun Subsonics Tangle
Description
Show description on roll
Attacks y Type
Brawling Charging Grappling Distracting Dodging Evasion Feinting Martial Arts Melee Shooting Called Shot Firing into Crowd Parrying Throwing
Skill
Brawling Martial Arts Melee Riding Throwing
Effect
None AC Critical Burn Cold Comp. A Comp. C Critical Delirium Disintegrate Domination Electrical Fatal Field Negate Fumes Heat Hits +1RF Ignites Ignores AC Intercept Irritant Knock Down Knock Out Mutate Paralysis Poison Power Drain Radiation Scatter Seeker Short Out Slam Sonic Stun Subsonics Tangle
Critical
None AC Critical Burn Cold Comp. A Comp. C Critical Delirium Disintegrate Domination Electrical Fatal Field Negate Fumes Heat Hits +1 RF Ignites Ignores AC Intercept Irritant Knock Down Knock Out Mutate Paralysis Poison Power Drain Radiation Scatter Seeker Short Out Slam Sonic Stun Subsonics Tangle
Tech Lvl.
I II III IV V
Tech Rank
N A B C D E F G H I J
Add attack rank to damage
Notes
Armour y Notes
Tech Lvl.
None I II III IV V
Tech Rank
N A B C D E F G H I J
Powered
Sensors
Human Visual / Audio Infrared and Ultraviolet Microscopic Telescopic Audio Radar/ Sonar Communications Feeling Vibrations
Cells Type
Atomic Broadcast Chemical Hydrogen Nuclear Solar
Shield
Size
None Small Medium Large
Material
None Wood Leather Carapace Plastic Metal Duralloy
Gear Type
Tech Lvl.
Tech Rank
Power
Cost
No.
Wt.
√
Combat Stats HP
Wounds
Defence
Physical
Energy
Mental
Physical Abilities
Cur.
Orig.
Adv.
Tmp.
Mod.
Roll
Mental Abilities
Cur.
Orig.
Adv.
Tmp.
Mod.
Roll
Mutations y Mod.
PS DX CN IN MS CH
Effort
Subconscious Conscious
No.
Duration
Description
Attacks y Type
Brawling Charging Grappling Distracting Dodging Evasion Feinting Martial Arts Melee Shooting Called Shot Firing into Crowd Parrying Throwing
Skill
Brawling Martial Arts Melee Riding Throwing
Effect
None AC Critical Burn Cold Comp. A Comp. C Critical Delirium Disintegrate Domination Electrical Fatal Field Negate Fumes Heat Hits +1RF Ignites Ignores AC Intercept Irritant Knock Down Knock Out Mutate Paralysis Poison Power Drain Radiation Scatter Seeker Short Out Slam Sonic Stun Subsonics Tangle
Critical
None AC Critical Burn Cold Comp. A Comp. C Critical Delirium Disintegrate Domination Electrical Fatal Field Negate Fumes Heat Hits +1 RF Ignites Ignores AC Intercept Irritant Knock Down Knock Out Mutate Paralysis Poison Power Drain Radiation Scatter Seeker Short Out Slam Sonic Stun Subsonics Tangle
Tech Lvl.
I II III IV V
Tech Rank
N A B C D E F G H I J
Add attack rank to damage
Notes
\ No newline at end of file
diff --git a/GammaWorld3e/src/sheet.pug b/GammaWorld3e/src/sheet.pug
index ccf3e9e237..af3ff9a93d 100644
--- a/GammaWorld3e/src/sheet.pug
+++ b/GammaWorld3e/src/sheet.pug
@@ -29,7 +29,7 @@
.col-xs-3
label Rank:
.col-xs-3
- input(type="number" name="attr_character_rank" value=1)
+ input(type="number" name="attr_character_rank" title="@{character_rank}" value=1)
.col-xs-5
.row.middle-xs
.col-xs-2
@@ -77,6 +77,8 @@
option(value=1) I
option(value=2) II
option(value=3) III
+ option(value=4) IV
+ option(value=5) V
.row.top-xs
.col-xs-8
.row.underline
@@ -247,11 +249,11 @@
.col-xs-1
input(type="number" name="attr_rank")
.col-xs-1
- input(type="number" name="attr_dmg")
+ input(type="text" name="attr_dmg")
.col-xs-1
input(type="hidden" name="attr_id")
input(type="hidden" name="attr_ref")
- button(type='roll' name='roll_mutation' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|mutations save|@{save} effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} mod|@{mod} character|@{character_id} target_id|@{target|target1|token_id} ')
+ button(type='roll' name='roll_mutation' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref describe|@{describe} category|mutations save|@{save} effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} dmg_type|@{dmg_type} mod|@{modifier} character|@{character_id} target_id|@{target|target1|token_id} ')
//- button(type='roll' name='roll_mutation2' value='!gw act @{rank} title|@{name} character|@{character_id} target_id|@{target|token_id}')
//- button(type='roll' name='roll_mutation4' value='!gw act @{rank} title|@{name} character|@{character_id} target_id|@{target|target1|token_name}')
input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" )
@@ -260,12 +262,12 @@
.row.middle-xs
.col-xs-1
label Mod.
- .col-xs-1
- input(type="hidden" name="attr_save")
+ .col-xs-2
+ //- input(type="hidden" name="attr_save")
input(type="hidden" name="attr_effect")
input(type="hidden" name="attr_effect_crit")
input(type="hidden" name="attr_dmg_type")
- select(name="attr_mod")
+ select(name="attr_modifier")
option(value="PS") PS
option(value="DX") DX
option(value="CN") CN
@@ -273,43 +275,134 @@
option(value="MS") MS
option(value="CH") CH
.col-xs-2
- label Effort
+ label Targets
.col-xs-2
+ input(type="text" name="attr_number")
+ .col-xs-2
+ label Effort
+ .col-xs-3
select(name="attr_effort")
option(value="passive") Subconscious
option(value="active") Conscious
+ .row.middle-xs
.col-xs-1
- label No.
- .col-xs-1
- input(type="text" name="attr_number")
+ label Save
+ .col-xs-2
+ select(name="attr_save")
+ option(value="PS") PS
+ option(value="DX") DX
+ option(value="CN") CN
+ option(value="IN") IN
+ option(value="MS") MS
+ option(value="CH") CH
.col-xs-2
label Duration
.col-xs-2
input(type="text" name="attr_duration")
+ .row.middle-xs
+ .col-xs-1
+ label Effect
+ .col-xs-2
+ select(name="attr_effect" value=0)
+ option(value=0) None
+ option(value="accrit") AC Critical
+ option(value="burn") Burn
+ option(value="cold") Cold
+ option(value="compa") Comp. A
+ option(value="compc") Comp. C
+ option(value="critical") Critical
+ option(value="delirium") Delirium
+ option(value="disintegrate") Disintegrate
+ option(value="domination") Domination
+ option(value="electrical") Electrical
+ option(value="fatal") Fatal
+ option(value="fieldnegate") Field Negate
+ option(value="fumes") Fumes
+ option(value="heat") Heat
+ option(value="extrarf") Hits +1RF
+ option(value="ignites") Ignites
+ option(value="ignoresac") Ignores AC
+ option(value="intercept") Intercept
+ option(value="irritant") Irritant
+ option(value="knockdown") Knock Down
+ option(value="ko") Knock Out
+ option(value="mutate") Mutate
+ option(value="paralysis") Paralysis
+ option(value="poison") Poison
+ option(value="powerdrain") Power Drain
+ option(value="radiation") Radiation
+ option(value="scatter") Scatter
+ option(value="seeker") Seeker
+ option(value="shortout") Short Out
+ option(value="slam") Slam
+ option(value="sonic") Sonic
+ option(value="stun") Stun
+ option(value="subsonics") Subsonics
+ option(value="tangle") Tangle
+ .col-xs-2 Critical
+ .col-xs-2
+ select(name="attr_effect_crit" value=0)
+ option(value=0) None
+ option(value="accrit") AC Critical
+ option(value="burn") Burn
+ option(value="cold") Cold
+ option(value="compa") Comp. A
+ option(value="compc") Comp. C
+ option(value="critical") Critical
+ option(value="delirium") Delirium
+ option(value="disintegrate") Disintegrate
+ option(value="domination") Domination
+ option(value="electrical") Electrical
+ option(value="fatal") Fatal
+ option(value="fieldnegate") Field Negate
+ option(value="fumes") Fumes
+ option(value="heat") Heat
+ option(value="extrarf") Hits +1 RF
+ option(value="ignites") Ignites
+ option(value="ignoresac") Ignores AC
+ option(value="intercept") Intercept
+ option(value="irritant") Irritant
+ option(value="knockdown") Knock Down
+ option(value="ko") Knock Out
+ option(value="mutate") Mutate
+ option(value="paralysis") Paralysis
+ option(value="poison") Poison
+ option(value="powerdrain") Power Drain
+ option(value="radiation") Radiation
+ option(value="scatter") Scatter
+ option(value="seeker") Seeker
+ option(value="shortout") Short Out
+ option(value="slam") Slam
+ option(value="sonic") Sonic
+ option(value="stun") Stun
+ option(value="subsonics") Subsonics
+ option(value="tangle") Tangle
.col-xs-12
label Description
.col-xs-12
textarea(name="attr_description")
+ .col-xs-12 Show description on roll
+ input.short(type="checkbox" name="attr_describe" class="check-flag" )
.row.underline
.col-xs-12
h2 Attacks
.row.middle-xs
- .col-xs-3
+ .col-xs-5
label Name
- .col-xs-1
+ .col-xs-2
label Mod.
.col-xs-1
label Range
.col-xs-1
label Dmg.
- .col-xs-2
- label Rank
+ .col-xs-1
+ label Skill
fieldset.repeating_attacks
.row
- .col-xs-3
+ .col-xs-5
input(type="text" name="attr_name")
- .col-xs-1
- select(name="attr_mod")
+ .col-xs-2
+ select(name="attr_modifier")
option(value="PS") PS
option(value="DX") DX
option(value="CN") CN
@@ -324,8 +417,8 @@
input(type="hidden" name="attr_ref")
input(type="text" name="attr_rank")
.col-xs-1
- button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|attacks effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} mod|@{mod} skill|@{skill} tech|@{tech} type|@{type} character|@{character_id} target_id|@{target|target1|token_id}')
- //- button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} title|@{name} mod|@{mod} tech|@{tech} type|@{type} effect|@{effect} character|@{character_id}')
+ button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|attacks effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} skilldmg|@{skilldmg} mod|@{modifier} skill|@{skill} tech|@{tech} type|@{type} character|@{character_id} target_id|@{target|target1|token_id}')
+ //- button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} title|@{name} mod|@{modifier} tech|@{tech} type|@{type} effect|@{effect} character|@{character_id}')
input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" )
span y
.options
@@ -438,10 +531,29 @@
.row.middle-xs
.col-xs-2 Tech Lvl.
.col-xs-2
+ select(name="attr_tech")
+ option(value=1) I
+ option(value=2) II
+ option(value=3) III
+ option(value=4) IV
+ option(value=5) V
input(type="number" name="attr_tech")
.col-xs-2 Tech Rank
.col-xs-2
- input(type="text" name="attr_tech_rank")
+ select(name="attr_tech_rank")
+ option(value="N") N
+ option(value="A") A
+ option(value="B") B
+ option(value="C") C
+ option(value="D") D
+ option(value="E") E
+ option(value="F") F
+ option(value="G") G
+ option(value="H") H
+ option(value="I") I
+ option(value="J") J
+ .col-xs-12 Add attack rank to damage
+ input.short(type="checkbox" name="attr_skilldmg" class="check-flag" )
.col-xs-12 Notes
.col-xs-12
textarea(name="attr_notes")
@@ -671,7 +783,7 @@
option(value=5) V
.col-xs-1
select(name="attr_tech_rank")
- option(value="N") A
+ option(value="N") N
option(value="A") A
option(value="B") B
option(value="C") C
@@ -794,7 +906,7 @@
.row
.col-xs-5
label Name
- .col-xs-3
+ .col-xs-2
label Rank
.col-xs-3
label Mod.
@@ -802,10 +914,10 @@
.row
.col-xs-5
input(type="text" name="attr_name")
- .col-xs-3
+ .col-xs-2
input(type="number" name="attr_rank")
.col-xs-3
- select(name="attr_mod")
+ select(name="attr_modifier")
option(value="PS") PS
option(value="DX") DX
option(value="CN") CN
@@ -813,7 +925,14 @@
option(value="MS") MS
option(value="CH") CH
.col-xs-1
- button(type='roll' name='roll_skill' value='!gw act @{rank} title|@{name} mod|@{mod} character|@{character_id}')
+ button(type='roll' name='roll_skill' value='!gw act @{rank} title|@{name} mod|@{modifier} character|@{character_id}')
+ input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" )
+ span y
+ .options
+ .row
+ .col-xs-12 Description
+ .col-xs-12
+ textarea(name="attr_description")
.row.underline
.col-xs-12
h2 Talents
@@ -823,6 +942,7 @@
fieldset.repeating_talents
.row
.col-xs-8
+ input(type="hidden" name="attr_ref")
input(type="text" name="attr_name")
.col-xs-2
button(type='roll' name='roll_talent' value='!gw act @{character_rank} title|@{name} character|@{character_id}')
@@ -830,15 +950,18 @@
span y
.options
.row
- .col-xs-3 Affects:
- .col-xs-3
- input(type="text" name="attr_affects")
- .col-xs-3 Act Factor:
- .col-xs-3
- input(type="text" name="attr_act_factor")
- .col-xs-12 Notes
+ //- .col-xs-3 Affects:
+ //- .col-xs-3
+ //- input(type="text" name="attr_affects")
+ //- .col-xs-3 Act Factor:
+ //- .col-xs-3
+ //- input(type="text" name="attr_act_factor")
+ .col-xs-12 Description
.col-xs-12
- textarea(name="attr_notes")
+ textarea(name="attr_description")
+ //- .col-xs-12 Notes
+ //- .col-xs-12
+ //- textarea(name="attr_notes")
.row.underline
.col-xs-12
h2 Coins
@@ -1160,7 +1283,7 @@
.col-xs-1
input(type="number" name="attr_rank")
.col-xs-1
- input(type="number" name="attr_dmg")
+ input(type="text" name="attr_dmg")
.col-xs-1
input(type="hidden" name="attr_id")
button(type='roll' name='roll_mutation' value='!gw act @{rank} title|@{name} character|@{character_id}')
@@ -1171,7 +1294,7 @@
.col-xs-2
label Mod.
.col-xs-2
- select(name="attr_mod")
+ select(name="attr_modifier")
option(value="PS") PS
option(value="DX") DX
option(value="CN") CN
@@ -1208,13 +1331,13 @@
.col-xs-1
label Dmg.
.col-xs-2
- label Rank
+ label Skill
fieldset.repeating_attacks
.row
.col-xs-3
input(type="text" name="attr_name")
.col-xs-1
- select(name="attr_mod")
+ select(name="attr_modifier")
option(value="PS") PS
option(value="DX") DX
option(value="CN") CN
@@ -1226,9 +1349,11 @@
.col-xs-1
input(type="text" name="attr_dmg")
.col-xs-1
+ input(type="hidden" name="attr_ref")
input(type="text" name="attr_rank")
.col-xs-1
- button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} title|@{name} mod|@{mod} tech| type|@{type} effect|@{effect} character|@{character_id}')
+ button(type='roll' name='roll_attack' value='!gw act @{rank} CS|?{CS|0} id|@{ref} title|ref category|attacks effect|@{effect} effect_crit|@{effect_crit} dmg|@{dmg} skilldmg|@{skilldmg} mod|@{modifier} skill|@{skill} tech|@{tech} type|@{type} character|@{character_id} target_id|@{target|target1|token_id}')
+
input.short.options-flag(type="checkbox" name="attr_options-flag" class="options-flag" )
span y
.options
@@ -1341,10 +1466,28 @@
.row.middle-xs
.col-xs-2 Tech Lvl.
.col-xs-2
- input(type="number" name="attr_tech")
+ select(name="attr_tech")
+ option(value=1) I
+ option(value=2) II
+ option(value=3) III
+ option(value=4) IV
+ option(value=5) V
.col-xs-2 Tech Rank
.col-xs-2
- input(type="text" name="attr_tech_rank")
+ select(name="attr_tech_rank")
+ option(value="N") N
+ option(value="A") A
+ option(value="B") B
+ option(value="C") C
+ option(value="D") D
+ option(value="E") E
+ option(value="F") F
+ option(value="G") G
+ option(value="H") H
+ option(value="I") I
+ option(value="J") J
+ .col-xs-12 Add attack rank to damage
+ input.short(type="checkbox" name="attr_skilldmg" class="check-flag" )
.col-xs-12 Notes
.col-xs-12
textarea(name="attr_notes")
@@ -1354,18 +1497,119 @@
label Description
.col-xs-12
textarea(name="attr_description")
-
.tab3
.sheet-container
h2 Ability Scores
div.panel
- input.short.rollSwitch(type="hidden" value="0")
label.tab
input.short.rollSwitch(type="radio" value="0" name="attr_rollSwitch")
span Reset
label.tab
input.short.rollSwitch(type="radio" value="1" name="attr_rollSwitch")
span Roll
+ label.tab
+ input.short.rollSwitch(type="radio" value="2" name="attr_rollSwitch")
+ span Input
+ input.rollSwitch(type="hidden" name="attr_rollSwitch" value="2")
+ .tab-score-roll
+ .row
+ .col-xs-6
+ h2 Physical Abilities
+ .row
+ .col-xs-1
+ .col-xs-2(title="Initially Rolled Score") Score
+ .row.middle-xs
+ .col-xs-1
+ label.ability PS
+ .col-xs-1
+ span(name="attr_PS_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability DX
+ .col-xs-1
+ span(name="attr_DX_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability CN
+ .col-xs-1
+ span(name="attr_CN_rolled")
+
+ .col-xs-6.post
+ h2 Mental Abilities
+ .row
+ .col-xs-1
+ .col-xs-2(title="Initially Rolled Score") Score
+ .row.middle-xs
+ .col-xs-1
+ label.ability IN
+ .col-xs-1
+ span(name="attr_IN_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability MS
+ .col-xs-1
+ span(name="attr_MS_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability CH
+ .col-xs-1
+ span(name="attr_CH_rolled")
+ .tab-score-input
+ .row
+ .col-xs-6
+ h2 Physical Abilities
+ .row
+ .col-xs-1
+ .col-xs-2(title="Initially Rolled Score") Score
+ .row.middle-xs
+ .col-xs-1
+ label.ability PS
+ .col-xs-1
+ input.tab4(type="text" name="attr_PS_rolled" title="@{PS_rolled}")
+ .col-xs-1
+ span(name="attr_PS_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability DX
+ .col-xs-2
+ input.tab4(type="text" name="attr_DX_rolled" title="@{DX_rolled}")
+ .col-xs-1
+ span(name="attr_DX_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability CN
+ .col-xs-2
+ input.tab4(type="text" name="attr_CN_rolled" title="@{CN_rolled}")
+ .col-xs-1
+ span(name="attr_CN_rolled")
+
+ .col-xs-6.post
+ h2 Mental Abilities
+ .row
+ .col-xs-1
+ .col-xs-2(title="Initially Rolled Score") Score
+ .row.middle-xs
+ .col-xs-1
+ label.ability IN
+ .col-xs-2
+ input.tab4(type="text" name="attr_IN_rolled" title="@{IN_rolled}")
+ .col-xs-1
+ span(name="attr_IN_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability MS
+ .col-xs-2
+ input.tab4(type="text" name="attr_MS_rolled" title="@{MS_rolled}")
+ .col-xs-1
+ span(name="attr_MS_rolled")
+ .row.middle-xs
+ .col-xs-1
+ label.ability CH
+ .col-xs-2
+ input.tab4(type="text" name="attr_CH_rolled" title="@{CH_rolled}")
+ .col-xs-1
+ span(name="attr_CH_rolled")
+
h2 Hit Points
div.panel
input.short.hpRollSwitch(type="hidden" value="0")
diff --git a/GammaWorld3e/src/sheetworkers.js b/GammaWorld3e/src/sheetworkers.js
index de717db54f..de9043be1f 100644
--- a/GammaWorld3e/src/sheetworkers.js
+++ b/GammaWorld3e/src/sheetworkers.js
@@ -1,496 +1,579 @@
-
//------ Functions ---------
-const update_ability = function(name) {
- console.log('update_ability: '+name);
- let update = {};
- getAttrs([name+'_rolled', name+'_advanced', name+'_tmp'], (v) => {
- console.log(v);
- update[name] = (parseInt(v[name+'_rolled']) || 0 ) + (parseInt(v[name+'_advanced']) || 0 ) + (parseInt(v[name+'_tmp']) || 0 );
- console.log(update);
- setAttrs(update, {silent: false});
- });
+const update_ability = function (name) {
+ console.log("update_ability: " + name);
+ let update = {};
+ getAttrs([name + "_rolled", name + "_advanced", name + "_tmp"], (v) => {
+ console.log(v);
+ update[name] =
+ (parseInt(v[name + "_rolled"]) || 0) +
+ (parseInt(v[name + "_advanced"]) || 0) +
+ (parseInt(v[name + "_tmp"]) || 0);
+ console.log(update);
+ setAttrs(update, { silent: false });
+ });
};
// @todo: this should probably just pick up equipped shields, rather than having a specific shield setting.
-const getShieldCS = function(shield_size, shield_material) {
- console.log('getShieldCS');
- console.log(shield_size);
- console.log(shield_material);
- let CS_physical = 0, CS_energy = 0, CS_mental = 0;
-
- CS_physical =
- parseInt(shield_size) > 2 ? -2 :
- parseInt(shield_size) > 1 ? -1 :
- 0;
-
- CS_physical =
- parseInt(shield_material) === 1 ? CS_physical :
- parseInt(shield_material) === 2 ? CS_physical :
- parseInt(shield_material) === 3 ? CS_physical-1 :
- parseInt(shield_material) === 4 ? CS_physical-1 :
- parseInt(shield_material) === 5 ? CS_physical-2 :
- parseInt(shield_material) === 6 ? CS_physical :
- CS_physical;
- CS_energy = parseInt(shield_material) === 6 ? CS_physical -3 : CS_physical;
- return {CS_physical, CS_energy, CS_mental};
+const getShieldCS = function (shield_size, shield_material) {
+ console.log("getShieldCS");
+ console.log(shield_size);
+ console.log(shield_material);
+ let CS_physical = 0,
+ CS_energy = 0,
+ CS_mental = 0;
+
+ CS_physical =
+ parseInt(shield_size) > 2 ? -2 : parseInt(shield_size) > 1 ? -1 : 0;
+
+ CS_physical =
+ parseInt(shield_material) === 1
+ ? CS_physical
+ : parseInt(shield_material) === 2
+ ? CS_physical
+ : parseInt(shield_material) === 3
+ ? CS_physical - 1
+ : parseInt(shield_material) === 4
+ ? CS_physical - 1
+ : parseInt(shield_material) === 5
+ ? CS_physical - 2
+ : parseInt(shield_material) === 6
+ ? CS_physical
+ : CS_physical;
+ CS_energy = parseInt(shield_material) === 6 ? CS_physical - 3 : CS_physical;
+ return { CS_physical, CS_energy, CS_mental };
};
-const update_ac = function() {
- console.log('update_ac');
- let update = {};
- let dr_total = 0;
- let ac_total = 0;
- let count = 0;
- let enc_attrs = ['shield_CS'];
+const update_ac = function () {
+ console.log("update_ac");
+ let update = {};
+ let dr_total = 0;
+ let ac_total = 0;
+ let count = 0;
+ let enc_attrs = ["shield_CS"];
+ getSectionIDs("repeating_armour", (armourIds) => {
+ _.each(armourIds, (currentID, i) => {
+ enc_attrs.push(`repeating_armour_${currentID}_weight`);
+ enc_attrs.push(`repeating_armour_${currentID}_count`);
+ enc_attrs.push(`repeating_armour_${currentID}_equipped`);
+ });
+ getAttrs(enc_attrs, (v) => {});
+ });
+};
+
+const update_enc = function () {
+ console.log("update_enc");
+ let update = {};
+ let wtotal = 0;
+ let DR_physical = 0;
+ let DR_energy = 0;
+ let CS = {};
+ let RFtotal = 0;
+ let CS_physical = 0;
+ let CS_mental = 0;
+ let CS_energy = 0;
+ let count = 0;
+ let PSfactor = 1;
+ let spdfactor = 1;
+ let enc_attrs = [
+ "DR_physical",
+ "DR_energy",
+ "coin_gp",
+ "coin_nk",
+ "coin_sp",
+ "coin_dm",
+ "PS",
+ "PS_rolled",
+ "PS_advanced",
+ "PS_tmp",
+ "encumbrance",
+ "encumbrance_max",
+ "speed",
+ "speed_max",
+ "burden",
+ "burden_max",
+ ];
+ getSectionIDs("repeating_gear", (gearIds) => {
+ _.each(gearIds, (currentID, i) => {
+ enc_attrs.push(`repeating_gear_${currentID}_weight`);
+ enc_attrs.push(`repeating_gear_${currentID}_count`);
+ enc_attrs.push(`repeating_gear_${currentID}_equipped`);
+ });
+
getSectionIDs("repeating_armour", (armourIds) => {
- _.each(armourIds, (currentID, i) => {
- enc_attrs.push(`repeating_armour_${currentID}_weight`);
- enc_attrs.push(`repeating_armour_${currentID}_count`);
- enc_attrs.push(`repeating_armour_${currentID}_equipped`);
- });
- getAttrs(enc_attrs, (v) => {
-
- })
- });
-};
-
-const update_enc = function() {
- console.log('update_enc');
- let update = {};
- let wtotal = 0;
- let DR_physical = 0;
- let DR_energy = 0;
- let CS = {};
- let RFtotal = 0;
- let CS_physical = 0;
- let CS_mental = 0;
- let CS_energy = 0;
- let count = 0;
- let PSfactor = 1;
- let spdfactor = 1;
- let enc_attrs = ['DR_physical', 'DR_energy', 'coin_gp', 'coin_nk', 'coin_sp', 'coin_dm', 'PS', 'PS_rolled', 'PS_advanced', 'PS_tmp', 'encumbrance', 'encumbrance_max', 'speed', 'speed_max', 'burden', 'burden_max'];
- getSectionIDs("repeating_gear", (gearIds) => {
- _.each(gearIds, (currentID, i) => {
- enc_attrs.push(`repeating_gear_${currentID}_weight`);
- enc_attrs.push(`repeating_gear_${currentID}_count`);
- enc_attrs.push(`repeating_gear_${currentID}_equipped`);
- });
-
- getSectionIDs("repeating_armour", (armourIds) => {
- _.each(armourIds, (currentID, i) => {
- enc_attrs.push(`repeating_armour_${currentID}_weight`);
- enc_attrs.push(`repeating_armour_${currentID}_count`);
- enc_attrs.push(`repeating_armour_${currentID}_equipped`);
- enc_attrs.push(`repeating_armour_${currentID}_powered`);
- enc_attrs.push(`repeating_armour_${currentID}_enc_factor`);
- enc_attrs.push(`repeating_armour_${currentID}_spd_factor`);
- enc_attrs.push(`repeating_armour_${currentID}_PS_factor`);
- enc_attrs.push(`repeating_armour_${currentID}_shield_size`);
- enc_attrs.push(`repeating_armour_${currentID}_shield_material`);
- enc_attrs.push(`repeating_armour_${currentID}_CS_mental`);
- enc_attrs.push(`repeating_armour_${currentID}_DR_energy`);
- enc_attrs.push(`repeating_armour_${currentID}_DR_physical`);
- enc_attrs.push(`repeating_armour_${currentID}_RF_physical`);
- });
- getAttrs(enc_attrs, (v) => {
-
- console.log(v);
- if (v["speed_max"] === undefined) {
- v["speed_max"] = v['speed'];
- update["speed_max"] = v['speed'];
- }
- ["coin_gp", "coin_sp", "coin_nk", "coin_dm"].forEach((type)=> {
- let coinweight = (isNaN(parseInt(v[`${type}`], 10)) === false) ? parseInt(v[`${type}`], 10) : 0;
- // use roughly correct weights for different materials as per g/cm3
- if(type === 'coin_gp') {
- wtotal += coinweight / 100
- }
- if(type === 'coin_sp') {
- wtotal += coinweight / 200
- }
- if(type === 'coin_nk') {
- wtotal += coinweight / 250
- }
- if(type === 'coin_dm') {
- wtotal += coinweight / 1000
- }
- if(type === 'coin_dl') {
- wtotal += coinweight / 1000
- }
- if(type === 'coin_db') {
- wtotal += coinweight / 1000
- }
- });
-
- _.each(gearIds, (currentID, i) => {
- if (
- v[`repeating_gear_${currentID}_weight`]
- && v[`repeating_gear_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_gear_${currentID}_weight`], 10)) === false)
- {
- count = v[`repeating_gear_${currentID}_count`] && isNaN(parseFloat(v[`repeating_gear_${currentID}_count`])) === false ? parseFloat(v[`repeating_gear_${currentID}_count`]) : 1;
- wtotal = wtotal + (parseFloat(v[`repeating_gear_${currentID}_weight`]) * count);
- }
- });
-
- _.each(armourIds, (currentID, i) => {
- if (
- v[`repeating_armour_${currentID}_weight`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_weight`], 10)) === false)
- {
- count = v[`repeating_armour_${currentID}_count`] && isNaN(parseFloat(v[`repeating_armour_${currentID}_count`])) === false ? parseFloat(v[`repeating_armour_${currentID}_count`]) : 1;
- wtotal = wtotal + (parseFloat(v[`repeating_armour_${currentID}_weight`]) * count * (isNaN(parseFloat(v[`repeating_armour_${currentID}_enc_factor`])) === false ? parseFloat(v[`repeating_armour_${currentID}_enc_factor`]) : 0.5));
- PSfactor
- = isNaN(parseFloat(v[`repeating_armour_${currentID}_PS_factor`])) === false
- ? (v[`repeating_armour_${currentID}_PS_factor`] > PSfactor ? v[`repeating_armour_${currentID}_PS_factor`] : PSfactor)
- : PSfactor;
- spdfactor
- = isNaN(parseFloat(v[`repeating_armour_${currentID}_spd_factor`])) === false
- ? (v[`repeating_armour_${currentID}_spd_factor`] > spdfactor ? v[`repeating_armour_${currentID}_spd_factor`] : spdfactor)
- : spdfactor;
- }
- // update DR_physical
- if (
- v[`repeating_armour_${currentID}_DR_physical`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_DR_physical`], 10)) === false
- ) {
- DR_physical += parseInt(v[`repeating_armour_${currentID}_DR_physical`]);
- }
- // update DR_energy
- console.log('DR_energy: ', v[`repeating_armour_${currentID}_DR_energy`]);
- if (
- v[`repeating_armour_${currentID}_DR_energy`] !== undefined
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_DR_energy`], 10)) === false
- ) {
- DR_energy += parseInt(v[`repeating_armour_${currentID}_DR_energy`]);
- } else {
- DR_energy += DR_physical;
- }
-
- // update CS
- if (
- v[`repeating_armour_${currentID}_shield_size`]
- && v[`repeating_armour_${currentID}_shield_material`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- ) {
- CS = getShieldCS(v[`repeating_armour_${currentID}_shield_size`], v[`repeating_armour_${currentID}_shield_material`] );
- CS_physical += CS.CS_physical;
- CS_mental += CS.CS_mental;
- CS_energy += CS.CS_energy;
- }
- if (
- v[`repeating_armour_${currentID}_CS_mental`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- ) {
- console.log('HELMET: '+v[`repeating_armour_${currentID}_CS_mental`] )
- CS_mental += parseInt(v[`repeating_armour_${currentID}_CS_mental`]) ;
- }
-
- // update RF
- if (
- v[`repeating_armour_${currentID}_RF_physical`]
- && v[`repeating_armour_${currentID}_equipped`] === '1'
- && isNaN(parseInt(v[`repeating_armour_${currentID}_RF_physical`], 10)) === false
- ) {
- RFtotal += parseInt(v[`repeating_armour_${currentID}_RF_physical`]);
- console.log(CS_physical);
- }
- });
- // console.log(CS_physical);
- update["RF_physical"] = RFtotal;
- update["RF_energy"] = RFtotal;
- update["CS_physical"] = CS_physical;
- update["CS_energy"] = CS_energy;
- update["CS_mental"] = CS_mental;
- update["DR_physical"] = DR_physical;
- update["DR_energy"] = DR_energy;
- update["encumbrance"] = Math.round(wtotal * 10) / 10;
- let PS = (parseInt(v["PS_rolled"])
- + parseInt(v["PS_advanced"])
- + parseInt(v["PS_tmp"])) * PSfactor;
- update['PS'] = PS;
- update["burden"] =
- (wtotal > PS*5) ? "Crushing Weight" :
- (wtotal > PS*3) ? "Immobile" :
- (wtotal > PS*2) ? "Heavily Burdened" :
- (wtotal > PS*1) ? "Burdened" :
- "Normal";
- update["speed"] =
- (wtotal > PS*3) ? 0 :
- (wtotal > PS*2) ? Math.floor((parseInt(v["speed_max"]) / 3)) :
- (wtotal > PS*1) ? Math.floor((parseInt(v["speed_max"]) /3)*2) :
- parseInt(v["speed_max"]) * spdfactor;
- console.log(update);
- setAttrs(update, {silent: true});
- update_mod('PS');
- });
- });
- });
-};
-
-const update_mod = function(ability) {
- console.log('update_mod: '+ability);
- let update = {};
- let mod = 6;
- let total = 0;
- let ps_attrs = [ability];
- getAttrs(ps_attrs, (v) => {
+ _.each(armourIds, (currentID, i) => {
+ enc_attrs.push(`repeating_armour_${currentID}_weight`);
+ enc_attrs.push(`repeating_armour_${currentID}_count`);
+ enc_attrs.push(`repeating_armour_${currentID}_equipped`);
+ enc_attrs.push(`repeating_armour_${currentID}_powered`);
+ enc_attrs.push(`repeating_armour_${currentID}_enc_factor`);
+ enc_attrs.push(`repeating_armour_${currentID}_spd_factor`);
+ enc_attrs.push(`repeating_armour_${currentID}_PS_factor`);
+ enc_attrs.push(`repeating_armour_${currentID}_shield_size`);
+ enc_attrs.push(`repeating_armour_${currentID}_shield_material`);
+ enc_attrs.push(`repeating_armour_${currentID}_CS_mental`);
+ enc_attrs.push(`repeating_armour_${currentID}_DR_energy`);
+ enc_attrs.push(`repeating_armour_${currentID}_DR_physical`);
+ enc_attrs.push(`repeating_armour_${currentID}_RF_physical`);
+ });
+ getAttrs(enc_attrs, (v) => {
console.log(v);
- console.log(v[ability]);
- total += parseInt(v[ability]);
- if(total < 601) {
- mod = 5;
+ if (v["speed_max"] === undefined) {
+ v["speed_max"] = v["speed"];
+ update["speed_max"] = v["speed"];
}
- if(total < 121) {
- mod = 4;
- }
- if(total < 22) {
- mod = 3;
- }
- if(total < 19) {
- mod = 2;
- }
- if(total < 16) {
- mod = 1;
- }
- if(total < 12) {
- mod = 0;
- }
- if(total < 10) {
- mod = -1;
- }
- if(total < 7) {
- mod = -2;
- }
- if(total < 4) {
- mod = -3;
- }
- if(total < 0) {
- mod = -4;
- }
- if(total < -6) {
- mod = -5;
- }
- if(total < -26) {
- mod = -6;
- }
- update[ability+'_modifier'] = mod;
- setAttrs(update, {silent: true});
+ ["coin_gp", "coin_sp", "coin_nk", "coin_dm"].forEach((type) => {
+ let coinweight =
+ isNaN(parseInt(v[`${type}`], 10)) === false
+ ? parseInt(v[`${type}`], 10)
+ : 0;
+ // use roughly correct weights for different materials as per g/cm3
+ if (type === "coin_gp") {
+ wtotal += coinweight / 100;
+ }
+ if (type === "coin_sp") {
+ wtotal += coinweight / 200;
+ }
+ if (type === "coin_nk") {
+ wtotal += coinweight / 250;
+ }
+ if (type === "coin_dm") {
+ wtotal += coinweight / 1000;
+ }
+ if (type === "coin_dl") {
+ wtotal += coinweight / 1000;
+ }
+ if (type === "coin_db") {
+ wtotal += coinweight / 1000;
+ }
+ });
+
+ _.each(gearIds, (currentID, i) => {
+ if (
+ v[`repeating_gear_${currentID}_weight`] &&
+ v[`repeating_gear_${currentID}_equipped`] === "1" &&
+ isNaN(parseInt(v[`repeating_gear_${currentID}_weight`], 10)) ===
+ false
+ ) {
+ count =
+ v[`repeating_gear_${currentID}_count`] &&
+ isNaN(parseFloat(v[`repeating_gear_${currentID}_count`])) ===
+ false
+ ? parseFloat(v[`repeating_gear_${currentID}_count`])
+ : 1;
+ wtotal =
+ wtotal +
+ parseFloat(v[`repeating_gear_${currentID}_weight`]) * count;
+ }
+ });
+
+ _.each(armourIds, (currentID, i) => {
+ if (
+ v[`repeating_armour_${currentID}_weight`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(parseInt(v[`repeating_armour_${currentID}_weight`], 10)) ===
+ false
+ ) {
+ count =
+ v[`repeating_armour_${currentID}_count`] &&
+ isNaN(parseFloat(v[`repeating_armour_${currentID}_count`])) ===
+ false
+ ? parseFloat(v[`repeating_armour_${currentID}_count`])
+ : 1;
+ wtotal =
+ wtotal +
+ parseFloat(v[`repeating_armour_${currentID}_weight`]) *
+ count *
+ (isNaN(
+ parseFloat(v[`repeating_armour_${currentID}_enc_factor`])
+ ) === false
+ ? parseFloat(v[`repeating_armour_${currentID}_enc_factor`])
+ : 0.5);
+ PSfactor =
+ isNaN(
+ parseFloat(v[`repeating_armour_${currentID}_PS_factor`])
+ ) === false
+ ? v[`repeating_armour_${currentID}_PS_factor`] > PSfactor
+ ? v[`repeating_armour_${currentID}_PS_factor`]
+ : PSfactor
+ : PSfactor;
+ spdfactor =
+ isNaN(
+ parseFloat(v[`repeating_armour_${currentID}_spd_factor`])
+ ) === false
+ ? v[`repeating_armour_${currentID}_spd_factor`] > spdfactor
+ ? v[`repeating_armour_${currentID}_spd_factor`]
+ : spdfactor
+ : spdfactor;
+ }
+ // update DR_physical
+ if (
+ v[`repeating_armour_${currentID}_DR_physical`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(
+ parseInt(v[`repeating_armour_${currentID}_DR_physical`], 10)
+ ) === false
+ ) {
+ DR_physical += parseInt(
+ v[`repeating_armour_${currentID}_DR_physical`]
+ );
+ }
+ // update DR_energy
+ console.log(
+ "DR_energy: ",
+ v[`repeating_armour_${currentID}_DR_energy`]
+ );
+ if (
+ v[`repeating_armour_${currentID}_DR_energy`] !== undefined &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(
+ parseInt(v[`repeating_armour_${currentID}_DR_energy`], 10)
+ ) === false
+ ) {
+ DR_energy += parseInt(v[`repeating_armour_${currentID}_DR_energy`]);
+ } else {
+ DR_energy += DR_physical;
+ }
+
+ // update CS
+ if (
+ v[`repeating_armour_${currentID}_shield_size`] &&
+ v[`repeating_armour_${currentID}_shield_material`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1"
+ ) {
+ CS = getShieldCS(
+ v[`repeating_armour_${currentID}_shield_size`],
+ v[`repeating_armour_${currentID}_shield_material`]
+ );
+ CS_physical += CS.CS_physical;
+ CS_mental += CS.CS_mental;
+ CS_energy += CS.CS_energy;
+ }
+ if (
+ v[`repeating_armour_${currentID}_CS_mental`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1"
+ ) {
+ console.log(
+ "HELMET: " + v[`repeating_armour_${currentID}_CS_mental`]
+ );
+ CS_mental += parseInt(v[`repeating_armour_${currentID}_CS_mental`]);
+ }
+
+ // update RF
+ if (
+ v[`repeating_armour_${currentID}_RF_physical`] &&
+ v[`repeating_armour_${currentID}_equipped`] === "1" &&
+ isNaN(
+ parseInt(v[`repeating_armour_${currentID}_RF_physical`], 10)
+ ) === false
+ ) {
+ RFtotal += parseInt(v[`repeating_armour_${currentID}_RF_physical`]);
+ console.log(CS_physical);
+ }
+ });
+ // console.log(CS_physical);
+ update["RF_physical"] = RFtotal;
+ update["RF_energy"] = RFtotal;
+ update["CS_physical"] = CS_physical;
+ update["CS_energy"] = CS_energy;
+ update["CS_mental"] = CS_mental;
+ update["DR_physical"] = DR_physical;
+ update["DR_energy"] = DR_energy;
+ update["encumbrance"] = Math.round(wtotal * 10) / 10;
+ let PS =
+ (parseInt(v["PS_rolled"]) +
+ parseInt(v["PS_advanced"]) +
+ parseInt(v["PS_tmp"])) *
+ PSfactor;
+ update["PS"] = PS;
+ update["burden"] =
+ wtotal > PS * 5
+ ? "Crushing Weight"
+ : wtotal > PS * 3
+ ? "Immobile"
+ : wtotal > PS * 2
+ ? "Heavily Burdened"
+ : wtotal > PS * 1
+ ? "Burdened"
+ : "Normal";
+ update["speed"] =
+ wtotal > PS * 3
+ ? 0
+ : wtotal > PS * 2
+ ? Math.floor(parseInt(v["speed_max"]) / 3)
+ : wtotal > PS * 1
+ ? Math.floor((parseInt(v["speed_max"]) / 3) * 2)
+ : parseInt(v["speed_max"]) * spdfactor;
+ console.log(update);
+ setAttrs(update, { silent: true });
+ update_mod("PS");
+ });
});
+ });
};
-
+const update_mod = function (ability) {
+ console.log("update_mod: " + ability);
+ let update = {};
+ let mod = 6;
+ let total = 0;
+ let ps_attrs = [ability];
+ getAttrs(ps_attrs, (v) => {
+ console.log(v);
+ console.log(v[ability]);
+ total += parseInt(v[ability]);
+ if (total < 601) {
+ mod = 5;
+ }
+ if (total < 121) {
+ mod = 4;
+ }
+ if (total < 22) {
+ mod = 3;
+ }
+ if (total < 19) {
+ mod = 2;
+ }
+ if (total < 16) {
+ mod = 1;
+ }
+ if (total < 12) {
+ mod = 0;
+ }
+ if (total < 10) {
+ mod = -1;
+ }
+ if (total < 7) {
+ mod = -2;
+ }
+ if (total < 4) {
+ mod = -3;
+ }
+ if (total < 0) {
+ mod = -4;
+ }
+ if (total < -6) {
+ mod = -5;
+ }
+ if (total < -26) {
+ mod = -6;
+ }
+ update[ability + "_modifier"] = mod;
+ setAttrs(update, { silent: true });
+ });
+};
//------ Events ---------
-on("sheet:opened", function(eventinfo) {
- console.log('sheet:opened');
+on("sheet:opened", function (eventinfo) {
+ console.log("sheet:opened");
});
-on("change:import", function(args) {
- console.log('sheet:import',args);
-
+on("change:import", function (args) {
+ console.log("sheet:import", args);
});
-on("change:PS_rolled", function(args) {
- console.log('change:PS_rolled')
- update_ability('PS');
+on("change:PS_rolled", function (args) {
+ console.log("change:PS_rolled");
+ update_ability("PS");
});
-on("change:PS_advanced", function(args) {
- console.log('change:PS_advanced')
- update_ability('PS');
+on("change:PS_advanced", function (args) {
+ console.log("change:PS_advanced");
+ update_ability("PS");
});
-on("change:PS_tmp", function(args) {
- console.log('change:PS_tmp')
- update_ability('PS');
+on("change:PS_tmp", function (args) {
+ console.log("change:PS_tmp");
+ update_ability("PS");
});
-on("change:PS", function(args) {
- console.log('PS changed');
- update_mod('PS');
- update_enc();
+on("change:PS", function (args) {
+ console.log("PS changed");
+ update_mod("PS");
+ update_enc();
});
-on("change:DX_rolled", function(args) {
- console.log('change:DX_rolled')
- update_ability('DX');
+on("change:DX_rolled", function (args) {
+ console.log("change:DX_rolled");
+ update_ability("DX");
});
-on("change:DX_advanced", function(args) {
- console.log('change:DX_advanced')
- update_ability('DX');
+on("change:DX_advanced", function (args) {
+ console.log("change:DX_advanced");
+ update_ability("DX");
});
-on("change:DX_tmp", function(args) {
- console.log('change:DX_tmp')
- update_ability('DX');
+on("change:DX_tmp", function (args) {
+ console.log("change:DX_tmp");
+ update_ability("DX");
});
-on("change:DX", function(args) {
- console.log('DX changed');
- update_mod('DX');
+on("change:DX", function (args) {
+ console.log("DX changed");
+ update_mod("DX");
});
-on("change:CN_rolled", function(args) {
- console.log('change:CN_rolled')
- update_ability('CN');
+on("change:CN_rolled", function (args) {
+ console.log("change:CN_rolled");
+ update_ability("CN");
});
-on("change:CN_advanced", function(args) {
- console.log('change:CN_advanced')
- update_ability('CN');
+on("change:CN_advanced", function (args) {
+ console.log("change:CN_advanced");
+ update_ability("CN");
});
-on("change:CN_tmp", function(args) {
- console.log('change:CN_tmp')
- update_ability('CN');
+on("change:CN_tmp", function (args) {
+ console.log("change:CN_tmp");
+ update_ability("CN");
});
-on("change:CN", function(args) {
- console.log('CN changed');
- update_mod('CN');
+on("change:CN", function (args) {
+ console.log("CN changed");
+ update_mod("CN");
});
-on("change:IN_rolled", function(args) {
- console.log('change:IN_rolled')
- update_ability('IN');
+on("change:IN_rolled", function (args) {
+ console.log("change:IN_rolled");
+ update_ability("IN");
});
-on("change:IN_advanced", function(args) {
- console.log('change:IN_advanced')
- update_ability('IN');
+on("change:IN_advanced", function (args) {
+ console.log("change:IN_advanced");
+ update_ability("IN");
});
-on("change:IN_tmp", function(args) {
- console.log('change:IN_tmp')
- update_ability('IN');
+on("change:IN_tmp", function (args) {
+ console.log("change:IN_tmp");
+ update_ability("IN");
});
-on("change:IN", function(args) {
- console.log('IN changed');
- update_mod('IN');
+on("change:IN", function (args) {
+ console.log("IN changed");
+ update_mod("IN");
});
-on("change:MS_rolled", function(args) {
- console.log('change:MS_rolled')
- update_ability('MS');
+on("change:MS_rolled", function (args) {
+ console.log("change:MS_rolled");
+ update_ability("MS");
});
-on("change:MS_advanced", function(args) {
- console.log('change:MS_advanced')
- update_ability('MS');
+on("change:MS_advanced", function (args) {
+ console.log("change:MS_advanced");
+ update_ability("MS");
});
-on("change:MS_tmp", function(args) {
- console.log('change:MS_tmp')
- update_ability('MS');
+on("change:MS_tmp", function (args) {
+ console.log("change:MS_tmp");
+ update_ability("MS");
});
-on("change:MS", function(args) {
- console.log('MS changed');
- update_mod('MS');
+on("change:MS", function (args) {
+ console.log("MS changed");
+ update_mod("MS");
});
-on("change:CH_rolled", function(args) {
- console.log('change:CH_rolled')
- update_ability('CH');
+on("change:CH_rolled", function (args) {
+ console.log("change:CH_rolled");
+ update_ability("CH");
});
-on("change:CH_advanced", function(args) {
- console.log('change:CH_advanced')
- update_ability('CH');
+on("change:CH_advanced", function (args) {
+ console.log("change:CH_advanced");
+ update_ability("CH");
});
-on("change:CH_tmp", function(args) {
- console.log('change:CH_tmp')
- update_ability('CH');
+on("change:CH_tmp", function (args) {
+ console.log("change:CH_tmp");
+ update_ability("CH");
});
-on("change:CH", function(args) {
- console.log('CH changed');
- update_mod('CH');
+on("change:CH", function (args) {
+ console.log("CH changed");
+ update_mod("CH");
});
-on("change:repeating_gear", function(args) {
- update_enc();
+on("change:repeating_gear", function (args) {
+ update_enc();
});
-on("change:repeating_armour", function(args) {
- console.log('change:repeating_armour');
- update_enc();
- // update_ac();
+on("change:repeating_armour", function (args) {
+ console.log("change:repeating_armour");
+ update_enc();
+ // update_ac();
});
-on("change:coin_gp", function(args) {
- update_enc();
+on("change:coin_gp", function (args) {
+ update_enc();
});
-on("change:coin_nk", function(args) {
- update_enc();
+on("change:coin_nk", function (args) {
+ update_enc();
});
-on("change:coin_dm", function(args) {
- update_enc();
+on("change:coin_dm", function (args) {
+ update_enc();
});
-on("change:coin_sp", function(args) {
- update_enc();
+on("change:coin_sp", function (args) {
+ update_enc();
});
-on("change:rollSwitch", function(args) {
- console.log(args);
- let update = {};
- if(args.newValue == "0") {
- update['PS_rolled'] = 0;
- update['IN_rolled'] = 0;
- update['CN_rolled'] = 0;
- update['IN_rolled'] = 0;
- update['MS_rolled'] = 0;
- update['CH_rolled'] = 0;
- } else {
- update['PS_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['DX_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['CN_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['IN_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['MS_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- update['CH_rolled'] = dices.roll('4d6', {dropLowest: 1}).total;
- }
- setAttrs(update, {silent: true});
-
- update_ability('PS');
- update_ability('DX');
- update_ability('CN');
- update_ability('IN');
- update_ability('MS');
- update_ability('CH');
+on("change:rollSwitch", function (args) {
+ console.log(args);
+ let update = {};
+ if (args.newValue == "2") { return }
+ if (args.newValue == "1") {
+ update["PS_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["DX_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["CN_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["IN_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["MS_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ update["CH_rolled"] = dices.roll("4d6", { dropLowest: 1 }).total;
+ }
+
+ if (args.newValue == "0") {
+ update["PS_rolled"] = 0;
+ update["DX_rolled"] = 0;
+ update["IN_rolled"] = 0;
+ update["CN_rolled"] = 0;
+ update["IN_rolled"] = 0;
+ update["MS_rolled"] = 0;
+ update["CH_rolled"] = 0;
+ }
+ setAttrs(update, { silent: true });
- update_mod('PS');
- update_mod('DX');
- update_mod('CN');
- update_mod('IN');
- update_mod('MS');
- update_mod('CH');
+ update_ability("PS");
+ update_ability("DX");
+ update_ability("CN");
+ update_ability("IN");
+ update_ability("MS");
+ update_ability("CH");
+ update_mod("PS");
+ update_mod("DX");
+ update_mod("CN");
+ update_mod("IN");
+ update_mod("MS");
+ update_mod("CH");
});
-
-on("change:hpRollSwitch", function(args) {
- let update = {};
- if(args.newValue == "0") {
- update['hp_max'] = 0;
- } else {
- let rank, CN;
- getAttrs(['character_rank', 'CN'], (v) => {
- rank = v['character_rank'];
- CN = v['CN'];
- });
-
- update['hp_max'] = dices.roll(`${CN}d6+${CN}`).total;
- setAttrs(update, {silent: true});
- }
-});
\ No newline at end of file
+on("change:hpRollSwitch", function (args) {
+ console.log("change:hpRollSwitch");
+ console.log(args);
+ let update = {};
+ if (args.newValue == "0") {
+ console.log("set hp_max to zero");
+ update["hp_max"] = 0;
+ setAttrs(update, { silent: true });
+ } else {
+ let rank, CN;
+ getAttrs(["character_rank", "CN"], (v) => {
+ console.log("v", v);
+ rank = v["character_rank"];
+ CN = v["CN"];
+ update["hp_max"] = dices.roll(`${CN}d6+${CN}`).total;
+ setAttrs(update, { silent: true });
+ });
+ }
+});
diff --git a/GammaWorld3e/styles.css b/GammaWorld3e/styles.css
index 0751fa864e..43560f4379 100644
--- a/GammaWorld3e/styles.css
+++ b/GammaWorld3e/styles.css
@@ -314,10 +314,13 @@ input.sheet-pageToggle:not([value="3"]) ~ .sheet-tab3 {
/**********************
Roll-up
***********************/
-input.sheet-rollSwitch:not([value="0"]) ~ .sheet-pre-rolled {
+input.sheet-rollSwitch[value="0"] ~ .sheet-tab-score-roll, input.sheet-rollSwitch[value="0"] ~ .sheet-tab-score-input {
display: none; }
-input.sheet-rollSwitch:not([value="1"]) ~ .sheet-post-rolled {
+input.sheet-rollSwitch[value="1"] ~ .sheet-tab-score-input {
+ display: none; }
+
+input.sheet-rollSwitch[value="2"] ~ .sheet-tab-score-roll {
display: none; }
/**********************
diff --git a/Hack The Planet/Hack the Planet.css b/Hack The Planet/Hack the Planet.css
index 2ceffb85ae..de362d8e98 100644
--- a/Hack The Planet/Hack the Planet.css
+++ b/Hack The Planet/Hack the Planet.css
@@ -90,7 +90,6 @@ input[type="radio"] {
/*CREW SHEET TITLE*/
.sheet-crew-sheet-title {
- line-height: 50px;
font-family: "Franklin Gothic Medium", sans-serif;
font-style: normal;
font-size: 30px;
@@ -100,13 +99,14 @@ input[type="radio"] {
}
.sheet-rolltemplate-crew-sheet-title {
- line-height: 50px;
font-family: "Franklin Gothic Medium", sans-serif;
font-style: normal;
font-size: 20px;
- line-height: 45px;
+ /*line-height: 45px;*/
font-weight: 900;
color: white;
+ text-transform: uppercase;
+ padding-top: .5em;
}
/*OLD Sheet Switching Functionality*/
@@ -715,7 +715,7 @@ input.sheet-pages + span.sheet-stresslabel {
.sheet-abilitydesc {
background-color: rgba(0,0,0,0);
- color: white;
+ color: black;
width: 95%;
height: 36px;
line-height: 12px;
@@ -2166,16 +2166,15 @@ input[value="12"]:checked ~ .sheet-12clock {
.sheet-insight-ready,
.sheet-prowess-ready,
.sheet-resolve-ready,
-.sheet-insight-button,
-.sheet-prowess-button,
-.sheet-resolve-button,
+.sheet-resistance-roll-button,
.sheet-long-select,
+.sheet-long-roll-button,
.sheet-recover-select,
.sheet-reduce-select,
.sheet-vice-select,
.sheet-long-button,
.sheet-recover-button,
-.sheet-reduce-button,
+.sheet-reduce-roll-button,
.sheet-vice-button,
.sheet-crewactionroll-selected,
.sheet-crewdowntimeroll-selected,
@@ -2221,7 +2220,8 @@ input[value="12"]:checked ~ .sheet-12clock {
.sheet-crewreduce-button,
.sheet-crewvice-button,
.sheet-crewacquire-select,
-.sheet-crewacquire-button{
+.sheet-crewacquire-button
+{
display:none;
}
@@ -2230,11 +2230,11 @@ input[value="12"]:checked ~ .sheet-12clock {
.sheet-engagementroll-selected:checked ~ .sheet-engagement-select,
.sheet-fortuneroll-selected:checked ~ .sheet-fortune-select,
.sheet-resistanceroll-selected:checked ~ .sheet-resistance-select,
-.sheet-crewroll-selected[value="actionroll"] ~ .sheet-crewaction-select,
-.sheet-crewroll-selected[value="downtimeroll"] ~ .sheet-crewdowntime-select,
-.sheet-crewroll-selected[value="engagementroll"] ~ .sheet-crewengagement-select,
-.sheet-crewroll-selected[value="fortuneroll"] ~ .sheet-crewfortune-select,
-.sheet-crewroll-selected[value="resistanceroll"] ~ .sheet-crewresistance-select,
+.sheet-crewroll-selected[value="action"] ~ .sheet-crewaction-select,
+.sheet-crewroll-selected[value="downtime"] ~ .sheet-crewdowntime-select,
+.sheet-crewroll-selected[value="engagement"] ~ .sheet-crewengagement-select,
+.sheet-crewroll-selected[value="fortune"] ~ .sheet-crewfortune-select,
+.sheet-crewroll-selected[value="resistance"] ~ .sheet-crewresistance-select,
.sheet-acquire-selected:checked ~ .sheet-acquire-select,
.sheet-long-selected:checked ~ .sheet-long-select,
.sheet-recover-selected:checked ~ .sheet-recover-select,
@@ -2259,13 +2259,11 @@ input[value="12"]:checked ~ .sheet-12clock {
.sheet-downtime-action-selected[value="recover"] ~ .sheet-recover-select,
.sheet-downtime-action-selected[value="reduce"] ~ .sheet-reduce-select,
.sheet-downtime-action-selected[value="vice"] ~ .sheet-vice-select,
-.sheet-downtime-selected[value="long"] ~ .sheet-long-button,
.sheet-downtime-selected[value="recover"] ~ .sheet-recover-button,
-.sheet-downtime-selected[value="reduce"] ~ .sheet-reduce-button,
.sheet-downtime-selected[value="vice"] ~ .sheet-vice-button,
-.sheet-resistance-select[value="insight"] ~ .sheet-insight-button,
-.sheet-resistance-select[value="prowess"] ~ .sheet-prowess-button,
-.sheet-resistance-select[value="resolve"] ~ .sheet-resolve-button
+.sheet-resistance-select[value="insight"] ~ .sheet-resistance-roll-button,
+.sheet-resistance-select[value="prowess"] ~ .sheet-resistance-roll-button,
+.sheet-resistance-select[value="resolve"] ~ .sheet-resistance-roll-button,
.sheet-action-selected[value="trace"] ~ .sheet-trace-button,
.sheet-action-selected[value="study"] ~ .sheet-study-button,
.sheet-action-selected[value="survey"] ~ .sheet-survey-button,
@@ -2278,20 +2276,21 @@ input[value="12"]:checked ~ .sheet-12clock {
.sheet-action-selected[value="control"] ~ .sheet-control-button,
.sheet-action-selected[value="network"] ~ .sheet-network-button,
.sheet-action-selected[value="sway"] ~ .sheet-sway-button,
-.sheet-crewdowntime-action-selected[value="acquire"] ~ .sheet-crewacquire-select,
+.sheet-downtime-action-selected[value="long"] ~ .sheet-downtime-long-actionselected:not([value="nothing"]) ~ .sheet-long-roll-button,
+.sheet-downtime-action-selected[value="reduce"] ~ .sheet-downtime-reduce-action-selected:not([value="nothing"]) ~ .sheet-reduce-roll-button,
+.sheet-crewroll-selected[value="downtime"] ~ .sheet-crewdowntime-action-selected[value="acquire"] ~ .sheet-crewacquire-select,
.sheet-crewdowntime-action-selected[value="long"] ~ .sheet-crewlong-select,
.sheet-crewdowntime-action-selected[value="recover"] ~ .sheet-crewrecover-select,
.sheet-crewdowntime-action-selected[value="reduce"] ~ .sheet-crewreduce-select,
.sheet-crewdowntime-action-selected[value="vice"] ~ .sheet-crewvice-select,
.sheet-crewdowntime-selected[value="long"] ~ .sheet-crewlong-button,
-.sheet-crewdowntime-action-selected[value="acquire"] ~ .sheet-crewacquire-select,
.sheet-crewdowntime-selected[value="acquire"] ~ .sheet-crewacquire-button,
.sheet-crewdowntime-selected[value="recover"] ~ .sheet-crewrecover-button,
.sheet-crewdowntime-selected[value="reduce"] ~ .sheet-crewreduce-button,
.sheet-crewdowntime-selected[value="vice"] ~ .sheet-crewvice-button,
-.sheet-crewresistance-select[value="insight"] ~ .sheet-insight-button,
-.sheet-crewresistance-select[value="prowess"] ~ .sheet-prowess-button,
-.sheet-crewresistance-select[value="resolve"] ~ .sheet-resolve-button{
+.sheet-crewresistance-select[value="insight"] ~ .sheet-resistance-roll-button,
+.sheet-crewresistance-select[value="prowess"] ~ .sheet-resistance-roll-button,
+.sheet-crewresistance-select[value="resolve"] ~ .sheet-resistance-roll-button{
display:block;
}
@@ -2362,8 +2361,150 @@ input[value="12"]:checked ~ .sheet-12clock {
.sheet-rolltemplate-dice {
font-size: 20px;
font-weight: 400;
+ margin: 1.5em 0;
}
+.sheet-rolltemplate-zerodice-msg {
+ font-size: 12px;
+ font-style: italic;
+ margin-top: 0.4em;
+}
+
+.sheet-rolltemplate-rolltype-name {
+ color: #66ffff;
+ text-transform: capitalize;
+}
+
+.sheet-rolltemplate-roll2 {
+ text-shadow: 1px 0 0 #000, 0 -1px 0 #000, 0 1px 0 #000, -1px 0 0 #000;
+}
+
+.sheet-rolltemplate-actionroll {
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+}
+
+.sheet-rolltemplate-character-text {
+ margin-top: .5em;
+}
+
+.sheet-rolltemplate-action-name {
+ text-transform: capitalize;
+}
+
+.sheet-rolltemplate-outcome {
+ margin-top: 1em;
+}
+
+.sheet-rolltemplate-roll2 .sheet-rolltemplate-dice .inlinerollresult {
+ background-color: rgba(0,0,0,0);
+ border-color: rgba(0,0,0,0);
+}
+
+.sheet-rolltemplate-outcome > * {
+ display: none;
+}
+
+/* non-zero rolls */
+/* non-zero roll with 2+ crits = critical success */
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-critical-success {
+ display: block;
+}
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-success,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure
+{
+ display: none;
+}
+
+/* non-zero roll with 1 crit = success */
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-success {
+ display: block;
+}
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit[title*="6"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit[title*="6"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit[original-title*="6"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .fullcrit[original-title*="6"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure
+{
+ display: none;
+}
+
+/* non-zero roll with a 4 or 5 = mixed success */
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success {
+ display: block;
+}
+
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure {
+ display: none;
+}
+
+/* if all else fails, it's a failure */
+.sheet-rolltemplate-dice.sheet-nonzerodice-rolled .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure {
+ display: block;
+}
+
+/* zero rolls */
+/* two sixes on a zero roll = success */
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-success {
+ display: block;
+}
+
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure {
+ display: none;
+}
+
+/* at least 2 of 4, 5 and 6 = mixed success */
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="5"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="5"] ~ [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="5"] ~ [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="4"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="4"] ~ [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="4"] ~ [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="5"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="5"] ~ [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="5"] ~ [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="4"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="4"] ~ [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="4"] ~ [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-mixed-success {
+ display: block;
+}
+
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="5"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="5"] ~ [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="5"] ~ [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="4"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="4"] ~ [title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [title*="4"] ~ [title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .fullcrit ~ [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="5"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="5"] ~ [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="5"] ~ [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="4"] ~ .fullcrit ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="4"] ~ [original-title*="5"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure,
+.sheet-rolltemplate-dice.sheet-zerodice-rolled [original-title*="4"] ~ [original-title*="4"] ~ .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure {
+ display: none;
+}
+
+/* otherwise, we've got a failure */
+.sheet-rolltemplate-dice.sheet-zerodice-rolled .sheet-rolltemplate-outcome .sheet-rolltemplate-outcome-failure {
+ display: block;
+}
+
+
.sheet-rolltemplate-die1,
.sheet-rolltemplate-die2,
.sheet-rolltemplate-die3,
@@ -2408,11 +2549,11 @@ input[value="12"]:checked ~ .sheet-12clock {
font-size: 20px;
}
-.sheet-rolltemplate-actionroll > .sheet-rolltemplate-action-roll,
-.sheet-rolltemplate-downtimeroll > .sheet-rolltemplate-downtime-roll,
-.sheet-rolltemplate-engagementroll > .sheet-rolltemplate-engagement-roll,
-.sheet-rolltemplate-fortuneroll > .sheet-rolltemplate-fortune-roll,
-.sheet-rolltemplate-resistanceroll > .sheet-rolltemplate-resistance-roll {
+.sheet-rolltemplate-actionroll .sheet-rolltemplate-action-roll,
+.sheet-rolltemplate-downtimeroll .sheet-rolltemplate-downtime-roll,
+.sheet-rolltemplate-engagementroll .sheet-rolltemplate-engagement-roll,
+.sheet-rolltemplate-fortuneroll .sheet-rolltemplate-fortune-roll,
+.sheet-rolltemplate-resistanceroll .sheet-rolltemplate-resistance-roll {
display:block;
}
diff --git a/Hack The Planet/Hack the Planet.html b/Hack The Planet/Hack the Planet.html
index da8488c904..b3ea7db86a 100644
--- a/Hack The Planet/Hack the Planet.html
+++ b/Hack The Planet/Hack the Planet.html
@@ -516,17 +516,17 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
What Roll Is This?
- Action Roll
- Downtime Roll
- Engagement Roll (Crew Sheet Only)
- Fortune Roll
- Resistance Roll
+ Action Roll
+ Downtime Roll
+ Engagement Roll (Crew Sheet Only)
+ Fortune Roll
+ Resistance Roll
-
-
-
-
-
+
+
+
+
+
Which Action?
@@ -572,40 +572,16 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
-3
-
-
-
-
+
+
+
-
- Trace
- Study
- Survey
- Modify
- Finesse
- Ghost
- Combat
- Wreck
- Hack
- Control
- Network
- Sway
+
+ Roll
-
-
+
+
Which Downtime Action?
Which Downtime Action?
@@ -619,8 +595,6 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
-
-
-2
-3
-
-
+
+
+
+ Roll
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
- Long-Term Project
-
Dice from the Treatment?
@@ -738,22 +701,10 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
-2
-3
-
-
-
- Trace
- Study
- Survey
- Modify
- Finesse
- Ghost
- Combat
- Wreck
- Hack
- Control
- Network
- Sway
-
+
+
+
+
Roll
Any Bonus Dice?
@@ -767,12 +718,16 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
-3
+
- Recover
- Vice
+
+
+ Roll
+
+ Roll
@@ -800,7 +755,11 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
5
6
-
Fortune Roll
+
+
+
+
Roll
+
Which Attribute?
@@ -810,15 +769,14 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
Resolve
+
-
Insight Resist
-
Prowess Resist
-
Resolve Resist
-
+
Roll
+
Playbook XP
@@ -1721,11 +1679,11 @@ RECKLESS - SOFT - UNSTABLE - VICIOUS-->
What Roll Is This?
- Action Roll (Character Sheet Only)
- Downtime Roll
- Engagement Roll
- Fortune Roll
- Resistance Roll (Character Sheet Only)
+ Action Roll (Character Sheet Only)
+ Downtime Roll
+ Engagement Roll
+ Fortune Roll
+ Resistance Roll (Character Sheet Only)
-
+
-2
-3
-
Acquire Asset
+
+
+
Roll
Fortune Dice?
@@ -2012,7 +1974,9 @@ give you +1d. Maybe a higherTier target will give you -1d. Maybe
5
6
-
Fortune Roll
+
+
+
Roll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Skillset
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Adv.
+
+
+ STR
+ TOU
+ AGI
+ WFR
+ WFM
+ INT
+ PER
+ CR
+ CH
+ LD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Languages
+
+
+
+
+
+
+
+
+
+
+
Abilities
+
Expand or collapse ability's descriptor block ⯆
+
+
+ ▼
+ ❖
+
+
+
+
+ ▼
+ ❖
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Finger / Toe
+
+ Nominal
+ 01-15
+ 16-30
+ 31-45
+ 46+
+
+
+
+
No Effect / Healthy
+
+
-1 WFM + WFR to Finger, -2 Agility to Toe
+
+
-2 WFM + WFR to Finger, -4 Agility to Toe
+
+
Body Location damaged. No longer usable. -3 Strength to Finger, -3 Agility to Toe
+
+
Body Locaton destroyed, -4 Strength to Finger, -4 Agility to Toe
+
+
+
+
+ Heart
+
+ Nominal
+ 01-20
+ 21-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Strength + Toughness + Agility
+
+
-5 Strength + Toughness + Agility
+
+
-10 Strength + Toughness + Agility
+
+
Body Location damaged. +10 Fatigue, -15 Strength + Toughness + Agility
+
+
Body Locaton destroyed, instant death
+
+
+
+
+ Neck
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Toughness
+
+
-5 Toughness
+
+
-10 Toughness
+
+
+1 Fatigue, -10 Toughness
+
+
Body Location damaged. -20 Toughness, Paralyzed and Helpless
+
+
Body Location destroyed, instant death
+
+
+
+
+ Skull / Brain
+
+ Nominal
+ 01-20
+ 21-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Perception + Intellect + WFM + WFR
+
+
-5 Perception + Intellect + WFM + WFR
+
+
-10 Perception + Intellect + WFM + WFR
+
+
Body Location damaged. +10 Fatigue, -15 Perception + Intellect + WFM + WFR
+
+
Body Location destroyed, instant death
+
+
+
+
+ Nose / Ear
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Perception to smelling or hearing Perception tests
+
+
-5 Perception to smelling or hearing Perception tests
+
+
-10 Perception to smelling or hearing Perception tests
+
+
-15 Perception to smelling or hearing Perception tests
+
+
Body Location broken. -20 Perception to smelling or hearing Perception tests
+
+
Body Location destroyed, cannot make or halve Perception to smelling or hearing tests
+
+
+
+
+ Limb (Arm / Leg)
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Strength to Arm or -2 Agility to Leg
+
+
-5 Strength to Arm, or -5 Agility to Leg
+
+
-10 Strength to Arm, or -10 Agility to Leg
+
+
-15 Strength to Arm, or -15 Agility to Leg
+
+
Body Location damaged. -15 Strength to Arm, or -15 Agility to Leg. -5 to limb's Actions
+
+
Body Location destroyed, limb cannot be used +3 Fatigue
+
+
+
+
+ Small / Large Intestines
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Toughness + Agility
+
+
-4 Toughness + Agility
+
+
-6 Toughness + Agility
+
+
-10 Toughness + Agility
+
+
Body Location damaged. +2 Fatigue, -15 Toughness + Agility
+
+
Body Location destroyed, +5 Fatigue, -20 Toughness + Agility
+
+
+
+
+ Lungs
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Toughness, stunned for (D5-Toughness Modifier) rounds
+
+
-5 Toughness, stunned for (2D5-Toughness Modifier) rounds
+
+
-10 Toughness, stunned for (3D5-Toughness Modifier) rounds
+
+
-15 Toughness, stunned for (4D5-Toughness Modifier) rounds
+
+
Body Location damaged. -20 Toughness, stunned for (5D5-Toughness Modifier) rounds
+
+
Body Location destroyed, -25 Toughness, stunned for (6D5-Toughness Modifier) rounds. Character will take 2 wounds whenever they take a Movement Action quicker than 2 Meters per Turn.
+
+
+
+
+ Kidney / Stomach / Liver / Spleen
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Toughness + Agility
+
+
-4 Toughness + Agility
+
+
-6 Toughness + Agility
+
+
-10 Toughness + Agility
+
+
Body Location damaged. +1 Fatigue, -15 Toughness + Agility
+
+
Body Location destroyed, +5 Fatigue, -20 Toughness + Agility
+
+
+
+
+ Knee / Ankle / Shoulder / Elbow
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Strength + Agility
+
+
-4 Strength + Agility
+
+
-6 Strength + Agility
+
+
-10 Strength + Agility
+
+
Body Location damaged. +1 Fatigue, -15 Strength + Agility
+
+
Body Location destroyed, +5 Fatigue, -20 Strength + Agility
+
+
+
+
+ Eye
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59+
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Perception to seeing tests
+
+
-5 Perception to seeing tests
+
+
-10 Perception to seeing tests
+
+
-12 Perception to seeing tests
+
+
Body Location broken. -15 Perception to seeing tests
+
+
Body Location destroyed, Character blinded for D5 rounds. -20 Perception to seeing tests
+
+
+
+
+ Mouth
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59+
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-1 Toughness, -5 to speaking tests
+
+
-3 Toughness, -5 to speaking tests
+
+
-5 Toughness, -10 to speaking tests
+
+
-8 Toughness, -10 to speaking tests
+
+
Body Location broken. +1 Fatigue, -12 Toughness, -15 to speaking tests
+
+
Body Location destroyed, +2 Fatigue, -15 Toughness, -15 to speaking tests
+
+
+
+
+ Hand
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59+
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-3 to both Warfare stats if hand is used to Attack
+
+
-5 to both Warfare stats if hand is used to Attack
+
+
-10 to both Warfare stats if hand is used to Attack
+
+
-13 to both Warfare stats if hand is used to Attack
+
+
Body Location broken. -15 to both Warfare stats if hand is used to Attack
+
+
Body Location destroyed, Character cannot use the hand for any Actions
+
+
+
+
+ Chin / Jaw / Cheek
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59+
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Toughness
+
+
-4 Toughness, -5 to speaking tests
+
+
-6 Toughness, -10 to speaking tests
+
+
+1 Fatigue, -10 Toughness, -10 to speaking tests
+
+
Body Location damaged. +2 Fatigue, -15 Toughness, -15 to speaking tests
+
+
Body Location destroyed, +3 Fatigue, -20 Toughness, -20 to speaking tests
+
+
+
+
+ Foot
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59+
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-5 to Agility when figuring Movement Speed
+
+
-10 to Agility when figuring Movement Speed
+
+
-15 to Agility when figuring Movement Speed
+
+
-20 to Agility when figuring Movement Speed
+
+
Body Location broken. -25 to Agility when figuring Movement Speed
+
+
Body Location destroyed, Character cannot use the Foot for any Actions. Half Move reduced to 1 Meter, Full Move reduced to 2 Meters, Charge and Run are impossible.
+
+
+
+
+ Pelvis
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59+
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-1 Toughness, -4 Agility
+
+
-3 Toughness, -6 Agility
+
+
-6 Toughness, -8 Agility
+
+
-8 Toughness, -12 Agility
+
+
Body Location damaged. -20 Toughness + Agility
+
+
Body Location destroyed, -30 Toughness + Agility
+
+
+
+
+ Chest
+
+ Nominal
+ 01-20
+ 21-25
+ 26-30
+ 31-40
+ 41-59+
+ 60+
+
+
+
+
No Effect / Healthy
+
+
-2 Toughness
+
+
-4 Toughness
+
+
-8 Toughness, stunned for 1D5 rounds
+
+
-10 Toughness, stunned for 2D5 rounds
+
+
Body Location broken. -15 Toughness, stunned for 3D5 rounds
+
+
Body Location destroyed, instant death
+
+
+
+
+
+
Hit Location
+
01-10 HEAD
+
01 Neck
+
02 Chin
+
03 Mouth
+
04-05 Nose
+
06-07 Cheeks
+
08 Eyes
+
09 Forehead
+
10 Ear
+
11-20 LEFT ARM
+
11 Fingers
+
12 Hands
+
13-15 Forearm
+
16 Elbow
+
17-19 Bicep
+
20 Shoulder
+
21-30 RIGHT ARM
+
21 Fingers
+
22 Hands
+
23-25 Forearm
+
26 Elbow
+
27-29 Bicep
+
30 Shoulder
+
31-45 LEFT LEG
+
31 Toes
+
32 Foot
+
33 Ankle
+
34-37 Shin
+
38 Knee
+
39-43 Thigh
+
44-45 Pelvis
+
46-61 RIGHT LEG
+
46 Toes
+
47 Foot
+
48 Ankle
+
49-53 Shin
+
54 Knee
+
55-58 Thigh
+
59-60 Pelvis
+
62-100 CHEST
+
61-66 Small Intestines
+
67-72 Large Intestines
+
73-78 Kidney
+
79-84 Stomach / Liver
+
85-89 Heart
+
90-96 Lungs
+
97-100 No Organ Hit
+
+
+
ROLL LOCATION (optional)
+
1-3 Left
+
4-7 Center
+
8-10 Right
+
+
+
IF Fingers / Toes 1D10
+
1-2 Pinky Finger / Toe
+
3-4 Ring Finger / Toe
+
5-6 Middle Finger / Toe
+
7-8 Index Finger / Toe
+
9-10 Thumb Finger / Toe
+
+
+
+
+
+
Medical Information
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Journal: Objectives
+
+
+
+ ✔
+
+
+
Journal: Notes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BREAKPOINTS
+
1-20 Wep
+
21-40 Mob
+
41-60 Eng
+
61-80 Optic
+
81-100 Crew
+
+
+
+
+
+
Armor
+
Front
+
Back
+
Side
+
Top
+
Bottom
+
+
+
+
+
+
+
+
+
+
+
+
+
Vehicle Ranged Weapons
+
+
+
+
+
Range
+
+
DMG Roll
+
+
Base
+
+
Pierce
+
+
+
+
Hit Mod
+
+
Magazine
+
+
/
+
+
Hit
+
DMG
+
+
+
RoF
+
+
/
+
+
/
+
+
Reload
+
+
Weight
+
+
+
+
+ ▼
+ ❖
+
+
+
+
+
+
+
+
+
+
Vehicle Melee Weaponry
+
+
+
+
+
Reach
+
+
DMG Roll
+
+
Base
+
+
Pierce
+
+
+
+
Hit Mod
+
+
Weight
+
+
Br Pts
+
+
/
+
+
Hit
+
DMG
+
+
+
+ ▼
+ ❖
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Settings
+ Species Overrides
+
+ Racial Features: N/A
+ Spartan 2 / Spartan 3 / Spartan 4
+ Sangheili / Elite
+ Jiralhanae / Brutes
+ Kig-yar Ruutian / Halo Trilogy Jackals
+ Kig-yar T'vaoan / Halo Reach Jackals / Skirmishers
+ Kig-yar Ibie'shan / Halo 4/5 Jackals
+ Mgalekgolo / Hunters
+ Promethean Knight
+ Dont Auto Calculate Speed And Weight
+
+
+
+ Initiative Overrides
+
+ No tiebreaker
+ Decimal tiebreaker
+ AGI tiebreaker
+
+
+
+ Auto Roll Hit Locations
+
+ Automatically roll hit locations
+ Don't automatically roll hit locations
+
+
+
+ Weapon Description in Damage Roll
+
+ Include weapon description
+ Exclude weapon description
+
+
+
+ Calculate The Negative Impact Of Fatigue Automatically
+
+ Auto calculate Fatigue
+ auto calculate Fatigue Enduring
+ Dont auto calculate Fatigue
+
+
+
+ Add half mythic agility to initiative
+
+ Half mythic agility
+ No mythic agility (3.7 legacy)
+
+
+
+ NPC Sheet
+ NPC Sheet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Initiative|
+
+ Standard
+ Fast Foot
+ Custom
+
+
+
+
+
+
+
+ Agility
+ Intellect
+ N/A
+
+
+
+
+
+
+
+ Infographic
+ To GM
+ Inline Mod
+ NPC Sheet
+ Auto-Damage
+ Scatter
+
+
+
+
+
+
+
+
Wounds
+
Current
+
+
Max
+
+
+
+
+
Fatigue
+
Current
+
+
Max
+
+
+
+
+
Luck
+
Current
+
+
Max
+
+
+
+
+
S Pts
+
Current
+
+
Max
+
+
+
+
+
Shields
+
Current
+
+
Max
+
+
Delay
+
+
Charge
+
+
+
+
+
Armor
+
Head
+
+
Arms
+
+
Chest
+
+
Legs
+
+
+
+
+
+
+
+
+
Ranged Weapons
+
+
+
+
+
Range
+
+
DMG Roll
+
+
Base
+
+
Pierce
+
+
+
+
Hit Mod
+
+
Magazine
+
+
/
+
+
Hit
+
DMG
+
+
+
RoF
+
+
/
+
+
/
+
+
Reload
+
+
Weight
+
+
+
+
+ ▼
+ ❖
+
+
+
+
+
+
+
+
+
Melee Weapons
+
+
+
+
+
Reach
+
+
DMG Roll
+
+
Base
+
+
Pierce
+
+
+
+
Hit Mod
+
+
Weight
+
+
Br Pts
+
+
/
+
+
Hit
+
DMG
+
+
+
+
damage plus Strength
+
+ None
+ Half
+ Full
+
+
+
pierce plus Strength
+
+ None
+ Half
+ Full
+
+
+
+
+
+ ▼
+ ❖
+
+
+
+
+
+
+
+
+
Additional info
+
+
+ ▼
+ ❖
+
+
+
+
+ ▼
+ ❖
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{#initiative}}
+
+
+
{{initiative}} Degrees of success
+
+
+ {{/initiative}}
+
+
+
+ {{#roll-name}}
+
+
+
+
{{roll}}
+
+ {{#^rollLess() roll 0 }}Degrees of success{{/^rollLess() roll 0 }}
+ {{#rollLess() roll 0 }}Degrees of failure{{/rollLess() roll 0 }}
+
+
+
+
+ {{/roll-name}}
+
+
+
+ {{#avrdam}}
+
+
+
+
Damage dealt:
+
{{avrdam}}
+
+
Warning: this macro is complex; Values displayed are not a perfectly accurate simulation.
+
+
+ {{/avrdam}}
+
+
+
+ {{#attack}}
+
+ {{#loc}}{{/loc}}
+ {{^loc}}
{{/loc}}
+
+
+
{{roll}}
+ {{#^rollLess() roll 0 }}
Degrees of success
{{/^rollLess() roll 0 }}
+ {{#rollLess() roll 0 }}
Degrees of failure
{{/rollLess() roll 0 }}
+
+
+ {{#rollWasCrit() roll }}
A CRITICAL FAIL!
{{/rollWasCrit() roll }}
+ {{#rollWasFumble() roll }}
A CRITICAL HIT!
{{/rollWasFumble() roll }}
+
+ {{/attack}}
+
+
+
+ {{#loc}}
+ {{^attack}}
{{/attack}}
+ {{#attack}}
{{/attack}}
+
Hit Location {{loc}}
+
+ {{#rollBetween() loc 1 10}} HEAD: {{/rollBetween() loc 1 10}}
+ {{#rollBetween() loc 1 1}} 01 Neck {{/rollBetween() loc 1 1}}
+ {{#rollBetween() loc 2 2}} 02 Chin {{/rollBetween() loc 2 2}}
+ {{#rollBetween() loc 3 3}} 03 Mouth {{/rollBetween() loc 3 3}}
+ {{#rollBetween() loc 4 5}} 04-05 Nose {{/rollBetween() loc 4 5}}
+ {{#rollBetween() loc 6 7}} 06-07 Cheeks {{/rollBetween() loc 6 7}}
+ {{#rollBetween() loc 8 8}} 08 Eyes {{/rollBetween() loc 8 8}}
+ {{#rollBetween() loc 9 9}} 09 Forehead {{/rollBetween() loc 9 9}}
+ {{#rollBetween() loc 10 10}} 10 Ear {{/rollBetween() loc 10 10}}
+
+ {{#rollBetween() loc 11 20}} LEFT ARM: {{/rollBetween() loc 11 20}}
+ {{#rollBetween() loc 11 11}} 11 Fingers {{/rollBetween() loc 11 11}}
+ {{#rollBetween() loc 12 12}} 12 Hands {{/rollBetween() loc 12 12}}
+ {{#rollBetween() loc 13 15}} 13-15 Forearm {{/rollBetween() loc 13 15}}
+ {{#rollBetween() loc 16 16}} 16 Elbow {{/rollBetween() loc 16 16}}
+ {{#rollBetween() loc 17 19}} 17-19 Bicep {{/rollBetween() loc 17 19}}
+ {{#rollBetween() loc 20 20}} 20 Shoulder {{/rollBetween() loc 20 20}}
+
+ {{#rollBetween() loc 21 30}} RIGHT ARM: {{/rollBetween() loc 21 30}}
+ {{#rollBetween() loc 21 21}} 21 Finger {{/rollBetween() loc 21 21}}
+ {{#rollBetween() loc 22 22}} 22 Hands {{/rollBetween() loc 22 22}}
+ {{#rollBetween() loc 23 25}} 23-25 Forearm {{/rollBetween() loc 23 25}}
+ {{#rollBetween() loc 26 26}} 26 Elbow {{/rollBetween() loc 26 26}}
+ {{#rollBetween() loc 27 29}} 27-29 Bicep {{/rollBetween() loc 27 29}}
+ {{#rollBetween() loc 30 30}} 30 Shoulder {{/rollBetween() loc 30 30}}
+
+ {{#rollBetween() loc 31 45}} LEFT LEG: {{/rollBetween() loc 31 45}}
+ {{#rollBetween() loc 31 31}} 31 Toes {{/rollBetween() loc 31 31}}
+ {{#rollBetween() loc 32 32}} 32 Foot {{/rollBetween() loc 32 32}}
+ {{#rollBetween() loc 33 33}} 33 Ankle {{/rollBetween() loc 33 33}}
+ {{#rollBetween() loc 34 37}} 34-37 Shin {{/rollBetween() loc 34 37}}
+ {{#rollBetween() loc 38 38}} 38 Kne {{/rollBetween() loc 38 38}}
+ {{#rollBetween() loc 39 43}} 39-43 Thigh {{/rollBetween() loc 39 43}}
+ {{#rollBetween() loc 44 45}} 44-45 Pelvis {{/rollBetween() loc 44 45}}
+
+ {{#rollBetween() loc 46 60}} RIGHT LEG: {{/rollBetween() loc 46 60}}
+ {{#rollBetween() loc 46 46}} 46 Toes {{/rollBetween() loc 46 46}}
+ {{#rollBetween() loc 47 47}} 47 Foot {{/rollBetween() loc 47 47}}
+ {{#rollBetween() loc 48 48}} 48 Ankle {{/rollBetween() loc 48 48}}
+ {{#rollBetween() loc 49 53}} 49-53 Shin {{/rollBetween() loc 49 53}}
+ {{#rollBetween() loc 54 54}} 54 Knee {{/rollBetween() loc 54 54}}
+ {{#rollBetween() loc 55 58}} 55-58 Thigh {{/rollBetween() loc 55 58}}
+ {{#rollBetween() loc 59 60}} 59-60 Pelvis {{/rollBetween() loc 59 60}}
+
+ {{#rollBetween() loc 61 100}} CHEST: {{/rollBetween() loc 61 100}}
+ {{#rollBetween() loc 61 66}} 61-66 Small Intestines {{/rollBetween() loc 61 66}}
+ {{#rollBetween() loc 67 72}} 67-72 Large Intestines {{/rollBetween() loc 67 72}}
+ {{#rollBetween() loc 73 78}} 73-78 Kidney {{/rollBetween() loc 73 78}}
+ {{#rollBetween() loc 79 84}} 79-84 Stomach / Liver {{/rollBetween() loc 79 84}}
+ {{#rollBetween() loc 85 89}} 85-89 Heart {{/rollBetween() loc 85 89}}
+ {{#rollBetween() loc 90 96}} 90-96 Lungs {{/rollBetween() loc 90 96}}
+ {{#rollBetween() loc 97 100}} 97-100 No Organ Hit {{/rollBetween() loc 97 100}}
+
+
+ {{/loc}}
+
+
+
+ {{#damage}}
+
+ {{#description}}
{{/description}}
+ {{^description}}
+ {{/damage}}
+ {{#description}}
+ {{#name}}{{/name}}
+
+ {{/description}}
+
+
+
+ {{#scatter-range}}
+
+
+
Range: {{scatter-range}} meters
+ {{#rollBetween() scatter-direction 1 2}}
{{/rollBetween() scatter-direction 1 2}}
+ {{#rollBetween() scatter-direction 3 3}}
{{/rollBetween() scatter-direction 3 3}}
+ {{#rollBetween() scatter-direction 4 4}}
{{/rollBetween() scatter-direction 4 4}}
+ {{#rollBetween() scatter-direction 5 5}}
{{/rollBetween() scatter-direction 5 5}}
+ {{#rollBetween() scatter-direction 6 7}}
{{/rollBetween() scatter-direction 6 7}}
+ {{#rollBetween() scatter-direction 8 8}}
{{/rollBetween() scatter-direction 8 8}}
+ {{#rollBetween() scatter-direction 9 9}}
{{/rollBetween() scatter-direction 9 9}}
+ {{#rollBetween() scatter-direction 10 10}}
{{/rollBetween() scatter-direction 10 10}}
+
+
+ {{/scatter-range}}
+
+
+
+ {{#2x2}}
+
+
+
+
+
{{2x2-name}}
+
+
{{2x2-name-max}}
+
+
+
+
+ {{/2x2}}
+
+ {{#4x2-1}}
+
+
+
+
+
+
{{4x2-1-name}}
+
+
{{4x2-1-name-max}}
+
+
+
+
+
{{4x2-2-name}}
+
+
{{4x2-2-name-max}}
+
+
+
+
+ {{/4x2-1}}
+
+
+
diff --git a/Halo_Mythic_3dot5/README.md b/Halo_Mythic_3dot5/README.md
index df8037a813..73a2114f30 100644
--- a/Halo_Mythic_3dot5/README.md
+++ b/Halo_Mythic_3dot5/README.md
@@ -1,7 +1,7 @@
-# Halo_Mythic_3dot5
+# Halo_Mythic_4dot0
This sheet is designed for use in Roll20. There is a universal header that applies to all in-sheet tabs. This header section consists of five grid sub-sections: first logo and core character details, second characteristics, third Mythical characteristics plus physical calculations such as movement and carrying capacity, fourth initiative roller and alternate in-sheet tabs, and fifth has all other numbers that should be accessible on-hand by the player such as luck, wounds, etc.
Specifically, the fifth header grid will be made to have the following attributes displayed: total experience points, luck points, support points, fatigue points, wound count, armor data, shield data, and credit count. Note that these attributes will be accessible and editable in other parts of the sheet.
- These tabs are composed of different sections: core character information such as skills and education, a summary of medical status along with any bodily injuries that could be sustained, a list of equipment both used in and out of combat such as weapons or communications gear, an experience page to differentiate unspent/spent experience points toward an automatically tracked total sum number, a player-kept journal tab to list complete/incomplete objectives in a mission or keep a history of your character's time spent, a vehicles tab to list vehicle data, and a settings tab to allow the player to apply technical changes to the sheet if needed, such as applying an automatic jump multiplier of 2 if playing as a Jackal.
+ These tabs are composed of different sections: core character information such as skills and education, a summary of medical status along with any bodily injuries that could be sustained, a list of equipment both used in and out of combat such as weapons or communications gear, an experience page to differentiate unspent/spent experience points toward an automatically tracked total sum number, a player-kept journal tab to list complete/incomplete objectives in a mission or keep a history of your character's time spent, a vehicles tab to list vehicle data, and a settings tab to allow the player to apply technical changes to the sheet if needed, such as applying an automatic jump multiplier if playing as a Jackal.
diff --git a/Halo_Mythic_3dot5/sheet.json b/Halo_Mythic_3dot5/sheet.json
index 5cd1953805..9ad42db587 100644
--- a/Halo_Mythic_3dot5/sheet.json
+++ b/Halo_Mythic_3dot5/sheet.json
@@ -1,10 +1,10 @@
{
- "html": "HaloMythic3dot5.html",
- "css": "HaloMythic3dot5.css",
+ "html": "HaloMythic4dot0.html",
+ "css": "HaloMythic4dot0.css",
"authors": "Omran Losinno, Michael van Weelde",
"roll20userid": "557736, 1503191",
"preview": "preview.png",
- "instructions": "This sheet is designed for use in Roll20 it is based on the Mythic ttrpg by Brandon Vorked Miller.\r\rThere is a universal header that applies to all in-sheet tabs. This header section consists of five grid sub-sections: first logo and core character details, second characteristics, third Mythical characteristics plus physical calculations such as movement and carrying capacity, fourth initiative roller and alternate in-sheet tabs, and fifth has all other numbers that should be accessible on-hand by the player such as luck, wounds, etc. Specifically, the fifth header grid will be made to have the following attributes displayed: total experience points, luck points, support points, fatigue points, wound count, armor data, shield data, and credit count. Note that these attributes will be accessible and editable in other parts of the sheet. These tabs are composed of different sections: core character information such as skills and education, a summary of medical status along with any bodily injuries that could be sustained, a list of equipment both used in and out of combat such as weapons or communications gear, an experience page to differentiate unspent/spent experience points toward an automatically tracked total sum number, a player-kept journal tab to list complete/incomplete objectives in a mission or keep a history of your character's time spent, a vehicles tab to list vehicle data, and a settings tab to allow the player to apply technical changes to the sheet if needed, such as applying an automatic jump multiplier of 2 if playing as a Jackal.",
+ "instructions": "This sheet is designed for use in Roll20 it is based on the Mythic ttrpg by Brandon Vorked Miller.\r\rThere is a universal header that applies to all in-sheet tabs. This header section consists of five grid sub-sections: first logo and core character details, second characteristics, third Mythical characteristics plus physical calculations such as movement and carrying capacity, fourth initiative roller and alternate in-sheet tabs, and fifth has all other numbers that should be accessible on-hand by the player such as luck, wounds, etc. Specifically, the fifth header grid will be made to have the following attributes displayed: total experience points, luck points, support points, fatigue points, wound count, armor data, shield data, and credit count. Note that these attributes will be accessible and editable in other parts of the sheet. These tabs are composed of different sections: core character information such as skills and education, a summary of medical status along with any bodily injuries that could be sustained, a list of equipment both used in and out of combat such as weapons or communications gear, an experience page to differentiate unspent/spent experience points toward an automatically tracked total sum number, a player-kept journal tab to list complete/incomplete objectives in a mission or keep a history of your character's time spent, a vehicles tab to list vehicle data, and a settings tab to allow the player to apply technical changes to the sheet if needed, such as applying an automatic jump multiplier if playing as a Jackal.",
"useroptions": [
{
"attribute": "initmod0",
@@ -46,10 +46,22 @@
"type": "select",
"options": [
"Auto calculate Fatigue|0",
- "Dont auto calculate Fatigue|1"
+ "auto calculate Fatigue Enduring|1",
+ "Dont auto calculate Fatigue|2"
],
"default": "0",
"description": "Select the fatigue calculation setting to use on the character sheet."
+ },
+ {
+ "attribute": "initmod4",
+ "displayname": "Add half mythic agility to initiative",
+ "type": "select",
+ "options": [
+ "Half mythic agility|1",
+ "No mythic agility (3.7 legacy)|0"
+ ],
+ "default": "1",
+ "description": "Select the initiative calculation setting to use on the character sheet."
}
],
"legacy": true
diff --git a/Imperator/sheet.json b/Imperator/sheet.json
index 7e1a4ad85f..9ea91fb791 100644
--- a/Imperator/sheet.json
+++ b/Imperator/sheet.json
@@ -10,9 +10,10 @@
"attribute": "useAPI",
"displayname": "Utilisation de l'API Imperator",
"type": "checkbox",
- "value": "1",
- "checked": "checked",
- "description": "En cochant cette case, les jets de dés feront appel à l'API javascript codée pour Imperator (accessible seulement aux utilisateurs possédant un compte pro). Si l'API Imperator est utilisée (dans Paramètres > Scripts API), les résultats critiques (sur des 10 ou des 1) seront correctement comptabilisés. Sinon, ce sera aux utilisateurs de vérifier le total."
+ "value": "1",
+ "checked": "checked",
+ "description": "En cochant cette case, les jets de dés feront appel à l'API javascript codée pour Imperator (accessible seulement aux utilisateurs possédant un compte pro). Si l'API Imperator est utilisée (dans Paramètres > Scripts API), les résultats critiques (sur des 10 ou des 1) seront correctement comptabilisés. Sinon, ce sera aux utilisateurs de vérifier le total."
}
- ]
+ ],
+ "legacy": true
}
\ No newline at end of file
diff --git a/Ironcrunch/src/package-lock.json b/Ironcrunch/src/package-lock.json
index fbd20d5abe..c9fbf191b1 100644
--- a/Ironcrunch/src/package-lock.json
+++ b/Ironcrunch/src/package-lock.json
@@ -55,6 +55,11 @@
}
}
},
+ "@babel/parser": {
+ "version": "7.13.9",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.13.9.tgz",
+ "integrity": "sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw=="
+ },
"@babel/runtime": {
"version": "7.9.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz",
@@ -70,6 +75,33 @@
}
}
},
+ "@babel/types": {
+ "version": "7.13.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.13.0.tgz",
+ "integrity": "sha512-hE+HE8rnG1Z6Wzo+MhaKE5lM5eMx71T4EHJgku2E3xIfaULhDcxiiRxUYgwX8qwP1BBSlag+TdGOt6JAidIZTA==",
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.12.11",
+ "lodash": "^4.17.19",
+ "to-fast-properties": "^2.0.0"
+ },
+ "dependencies": {
+ "@babel/helper-validator-identifier": {
+ "version": "7.12.11",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz",
+ "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw=="
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
+ }
+ }
+ },
"@types/babel-types": {
"version": "7.0.7",
"resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.7.tgz",
@@ -107,16 +139,16 @@
"integrity": "sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw=="
},
"acorn": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
- "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
},
"acorn-globals": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
"integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
"requires": {
- "acorn": "4.0.13"
+ "acorn": "^4.0.4"
},
"dependencies": {
"acorn": {
@@ -131,9 +163,9 @@
"resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
"requires": {
- "kind-of": "3.2.2",
- "longest": "1.0.1",
- "repeat-string": "1.6.1"
+ "kind-of": "^3.0.2",
+ "longest": "^1.0.1",
+ "repeat-string": "^1.5.2"
}
},
"ansi-regex": {
@@ -151,6 +183,11 @@
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
+ "assert-never": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/assert-never/-/assert-never-1.2.1.tgz",
+ "integrity": "sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw=="
+ },
"async": {
"version": "2.6.3",
"resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz",
@@ -184,6 +221,14 @@
"to-fast-properties": "1.0.3"
}
},
+ "babel-walk": {
+ "version": "3.0.0-canary-5",
+ "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz",
+ "integrity": "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==",
+ "requires": {
+ "@babel/types": "^7.9.6"
+ }
+ },
"babylon": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
@@ -218,8 +263,8 @@
"resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
"integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
"requires": {
- "align-text": "0.1.4",
- "lazy-cache": "1.0.4"
+ "align-text": "^0.1.3",
+ "lazy-cache": "^1.0.3"
}
},
"chalk": {
@@ -252,7 +297,7 @@
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz",
"integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==",
"requires": {
- "source-map": "0.6.1"
+ "source-map": "~0.6.0"
}
},
"cliui": {
@@ -260,8 +305,8 @@
"resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
"integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
"requires": {
- "center-align": "0.1.3",
- "right-align": "0.1.3",
+ "center-align": "^0.1.1",
+ "right-align": "^0.1.1",
"wordwrap": "0.0.2"
}
},
@@ -599,9 +644,9 @@
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"is-promise": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
- "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="
},
"is-regex": {
"version": "1.0.5",
@@ -631,8 +676,8 @@
"resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
"integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
"requires": {
- "is-promise": "2.1.0",
- "promise": "7.3.1"
+ "is-promise": "^2.0.0",
+ "promise": "^7.0.1"
}
},
"kind-of": {
@@ -640,7 +685,7 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"requires": {
- "is-buffer": "1.1.6"
+ "is-buffer": "^1.1.5"
}
},
"lazy-cache": {
@@ -811,22 +856,53 @@
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"requires": {
- "asap": "2.0.6"
+ "asap": "~2.0.3"
}
},
"pug": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
- "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/pug/-/pug-3.0.1.tgz",
+ "integrity": "sha512-9v1o2yXMfSKJy2PykKyWUhpgx9Pf9D/UlPgIs2pTTxR6DQZ0oivy4I9f8PlWXRY4sjIhDU4TMJ7hQmYnNJc2bw==",
"requires": {
- "pug-code-gen": "2.0.2",
- "pug-filters": "3.1.1",
- "pug-lexer": "4.1.0",
- "pug-linker": "3.0.6",
- "pug-load": "2.0.12",
- "pug-parser": "5.0.1",
- "pug-runtime": "2.0.5",
- "pug-strip-comments": "1.0.4"
+ "pug-code-gen": "^3.0.2",
+ "pug-filters": "^4.0.0",
+ "pug-lexer": "^5.0.0",
+ "pug-linker": "^4.0.0",
+ "pug-load": "^3.0.0",
+ "pug-parser": "^6.0.0",
+ "pug-runtime": "^3.0.0",
+ "pug-strip-comments": "^2.0.0"
+ },
+ "dependencies": {
+ "is-expression": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-4.0.0.tgz",
+ "integrity": "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==",
+ "requires": {
+ "acorn": "^7.1.1",
+ "object-assign": "^4.1.1"
+ }
+ },
+ "pug-error": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+ "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
+ },
+ "pug-lexer": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-5.0.1.tgz",
+ "integrity": "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==",
+ "requires": {
+ "character-parser": "^2.2.0",
+ "is-expression": "^4.0.0",
+ "pug-error": "^2.0.0"
+ }
+ },
+ "pug-runtime": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz",
+ "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg=="
+ }
}
},
"pug-attrs": {
@@ -848,21 +924,162 @@
"commander": "2.20.3",
"mkdirp": "0.5.5",
"pug": "2.0.4"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+ "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
+ },
+ "pug": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.4.tgz",
+ "integrity": "sha512-XhoaDlvi6NIzL49nu094R2NA6P37ijtgMDuWE+ofekDChvfKnzFal60bhSdiy8y2PBO6fmz3oMEIcfpBVRUdvw==",
+ "requires": {
+ "pug-code-gen": "^2.0.2",
+ "pug-filters": "^3.1.1",
+ "pug-lexer": "^4.1.0",
+ "pug-linker": "^3.0.6",
+ "pug-load": "^2.0.12",
+ "pug-parser": "^5.0.1",
+ "pug-runtime": "^2.0.5",
+ "pug-strip-comments": "^1.0.4"
+ }
+ },
+ "pug-code-gen": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.3.tgz",
+ "integrity": "sha512-r9sezXdDuZJfW9J91TN/2LFbiqDhmltTFmGpHTsGdrNGp3p4SxAjjXEfnuK2e4ywYsRIVP0NeLbSAMHUcaX1EA==",
+ "requires": {
+ "constantinople": "^3.1.2",
+ "doctypes": "^1.1.0",
+ "js-stringify": "^1.0.1",
+ "pug-attrs": "^2.0.4",
+ "pug-error": "^1.3.3",
+ "pug-runtime": "^2.0.5",
+ "void-elements": "^2.0.1",
+ "with": "^5.0.0"
+ }
+ },
+ "pug-filters": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz",
+ "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==",
+ "requires": {
+ "clean-css": "^4.1.11",
+ "constantinople": "^3.0.1",
+ "jstransformer": "1.0.0",
+ "pug-error": "^1.3.3",
+ "pug-walk": "^1.1.8",
+ "resolve": "^1.1.6",
+ "uglify-js": "^2.6.1"
+ }
+ },
+ "pug-linker": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz",
+ "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==",
+ "requires": {
+ "pug-error": "^1.3.3",
+ "pug-walk": "^1.1.8"
+ }
+ },
+ "pug-load": {
+ "version": "2.0.12",
+ "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz",
+ "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==",
+ "requires": {
+ "object-assign": "^4.1.0",
+ "pug-walk": "^1.1.8"
+ }
+ },
+ "pug-parser": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz",
+ "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==",
+ "requires": {
+ "pug-error": "^1.3.3",
+ "token-stream": "0.0.1"
+ }
+ },
+ "pug-strip-comments": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz",
+ "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==",
+ "requires": {
+ "pug-error": "^1.3.3"
+ }
+ },
+ "pug-walk": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz",
+ "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA=="
+ },
+ "token-stream": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
+ "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
+ },
+ "with": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
+ "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
+ "requires": {
+ "acorn": "^3.1.0",
+ "acorn-globals": "^3.0.0"
+ }
+ }
}
},
"pug-code-gen": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.2.tgz",
- "integrity": "sha512-kROFWv/AHx/9CRgoGJeRSm+4mLWchbgpRzTEn8XCiwwOy6Vh0gAClS8Vh5TEJ9DBjaP8wCjS3J6HKsEsYdvaCw==",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-3.0.2.tgz",
+ "integrity": "sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==",
"requires": {
- "constantinople": "3.1.2",
- "doctypes": "1.1.0",
- "js-stringify": "1.0.2",
- "pug-attrs": "2.0.4",
- "pug-error": "1.3.3",
- "pug-runtime": "2.0.5",
- "void-elements": "2.0.1",
- "with": "5.1.1"
+ "constantinople": "^4.0.1",
+ "doctypes": "^1.1.0",
+ "js-stringify": "^1.0.2",
+ "pug-attrs": "^3.0.0",
+ "pug-error": "^2.0.0",
+ "pug-runtime": "^3.0.0",
+ "void-elements": "^3.1.0",
+ "with": "^7.0.0"
+ },
+ "dependencies": {
+ "constantinople": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
+ "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
+ "requires": {
+ "@babel/parser": "^7.6.0",
+ "@babel/types": "^7.6.1"
+ }
+ },
+ "pug-attrs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-3.0.0.tgz",
+ "integrity": "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==",
+ "requires": {
+ "constantinople": "^4.0.1",
+ "js-stringify": "^1.0.2",
+ "pug-runtime": "^3.0.0"
+ }
+ },
+ "pug-error": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+ "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
+ },
+ "pug-runtime": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-3.0.1.tgz",
+ "integrity": "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg=="
+ },
+ "void-elements": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
+ "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk="
+ }
}
},
"pug-error": {
@@ -871,17 +1088,31 @@
"integrity": "sha512-qE3YhESP2mRAWMFJgKdtT5D7ckThRScXRwkfo+Erqga7dyJdY3ZquspprMCj/9sJ2ijm5hXFWQE/A3l4poMWiQ=="
},
"pug-filters": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.1.tgz",
- "integrity": "sha512-lFfjNyGEyVWC4BwX0WyvkoWLapI5xHSM3xZJFUhx4JM4XyyRdO8Aucc6pCygnqV2uSgJFaJWW3Ft1wCWSoQkQg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-4.0.0.tgz",
+ "integrity": "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==",
"requires": {
- "clean-css": "4.2.3",
- "constantinople": "3.1.2",
+ "constantinople": "^4.0.1",
"jstransformer": "1.0.0",
- "pug-error": "1.3.3",
- "pug-walk": "1.1.8",
- "resolve": "1.15.1",
- "uglify-js": "2.8.29"
+ "pug-error": "^2.0.0",
+ "pug-walk": "^2.0.0",
+ "resolve": "^1.15.1"
+ },
+ "dependencies": {
+ "constantinople": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz",
+ "integrity": "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==",
+ "requires": {
+ "@babel/parser": "^7.6.0",
+ "@babel/types": "^7.6.1"
+ }
+ },
+ "pug-error": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+ "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
+ }
}
},
"pug-lexer": {
@@ -895,12 +1126,19 @@
}
},
"pug-linker": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.6.tgz",
- "integrity": "sha512-bagfuHttfQOpANGy1Y6NJ+0mNb7dD2MswFG2ZKj22s8g0wVsojpRlqveEQHmgXXcfROB2RT6oqbPYr9EN2ZWzg==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-4.0.0.tgz",
+ "integrity": "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==",
"requires": {
- "pug-error": "1.3.3",
- "pug-walk": "1.1.8"
+ "pug-error": "^2.0.0",
+ "pug-walk": "^2.0.0"
+ },
+ "dependencies": {
+ "pug-error": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+ "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
+ }
}
},
"pug-lint": {
@@ -931,21 +1169,28 @@
}
},
"pug-load": {
- "version": "2.0.12",
- "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.12.tgz",
- "integrity": "sha512-UqpgGpyyXRYgJs/X60sE6SIf8UBsmcHYKNaOccyVLEuT6OPBIMo6xMPhoJnqtB3Q3BbO4Z3Bjz5qDsUWh4rXsg==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-3.0.0.tgz",
+ "integrity": "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==",
"requires": {
- "object-assign": "4.1.1",
- "pug-walk": "1.1.8"
+ "object-assign": "^4.1.1",
+ "pug-walk": "^2.0.0"
}
},
"pug-parser": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.1.tgz",
- "integrity": "sha512-nGHqK+w07p5/PsPIyzkTQfzlYfuqoiGjaoqHv1LjOv2ZLXmGX1O+4Vcvps+P4LhxZ3drYSljjq4b+Naid126wA==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-6.0.0.tgz",
+ "integrity": "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==",
"requires": {
- "pug-error": "1.3.3",
- "token-stream": "0.0.1"
+ "pug-error": "^2.0.0",
+ "token-stream": "1.0.0"
+ },
+ "dependencies": {
+ "pug-error": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+ "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
+ }
}
},
"pug-runtime": {
@@ -954,17 +1199,24 @@
"integrity": "sha512-P+rXKn9un4fQY77wtpcuFyvFaBww7/91f3jHa154qU26qFAnOe6SW1CbIDcxiG5lLK9HazYrMCCuDvNgDQNptw=="
},
"pug-strip-comments": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.4.tgz",
- "integrity": "sha512-i5j/9CS4yFhSxHp5iKPHwigaig/VV9g+FgReLJWWHEHbvKsbqL0oP/K5ubuLco6Wu3Kan5p7u7qk8A4oLLh6vw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-2.0.0.tgz",
+ "integrity": "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==",
"requires": {
- "pug-error": "1.3.3"
+ "pug-error": "^2.0.0"
+ },
+ "dependencies": {
+ "pug-error": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-2.0.0.tgz",
+ "integrity": "sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ=="
+ }
}
},
"pug-walk": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.8.tgz",
- "integrity": "sha512-GMu3M5nUL3fju4/egXwZO0XLi6fW/K3T3VTgFQ14GxNi8btlxgT5qZL//JwZFm/2Fa64J/PNS8AZeys3wiMkVA=="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-2.0.0.tgz",
+ "integrity": "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ=="
},
"regenerator-runtime": {
"version": "0.11.1",
@@ -1009,7 +1261,7 @@
"resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
"integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
"requires": {
- "align-text": "0.1.4"
+ "align-text": "^0.1.1"
}
},
"safer-buffer": {
@@ -1266,18 +1518,18 @@
"integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
},
"token-stream": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
- "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-1.0.0.tgz",
+ "integrity": "sha1-zCAOqyYT9BZtJ/+a/HylbUnfbrQ="
},
"uglify-js": {
"version": "2.8.29",
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
"integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
"requires": {
- "source-map": "0.5.7",
- "uglify-to-browserify": "1.0.2",
- "yargs": "3.10.0"
+ "source-map": "~0.5.1",
+ "uglify-to-browserify": "~1.0.0",
+ "yargs": "~3.10.0"
},
"dependencies": {
"source-map": {
@@ -1327,12 +1579,14 @@
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
},
"with": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
- "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/with/-/with-7.0.2.tgz",
+ "integrity": "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==",
"requires": {
- "acorn": "3.3.0",
- "acorn-globals": "3.1.0"
+ "@babel/parser": "^7.9.6",
+ "@babel/types": "^7.9.6",
+ "assert-never": "^1.2.1",
+ "babel-walk": "3.0.0-canary-5"
}
},
"wordwrap": {
@@ -1396,9 +1650,9 @@
"resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
"integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
"requires": {
- "camelcase": "1.2.1",
- "cliui": "2.1.0",
- "decamelize": "1.2.0",
+ "camelcase": "^1.0.2",
+ "cliui": "^2.1.0",
+ "decamelize": "^1.0.0",
"window-size": "0.1.0"
}
},
diff --git a/Ironcrunch/src/package.json b/Ironcrunch/src/package.json
index 565185795f..2f2b56332a 100644
--- a/Ironcrunch/src/package.json
+++ b/Ironcrunch/src/package.json
@@ -13,7 +13,7 @@
},
"author": "Ayethin",
"dependencies": {
- "pug": "2.0.4",
+ "pug": "3.0.1",
"pug-cli": "1.0.0-alpha6",
"pug-lint": "2.6.0",
"stlint": "1.0.62",
diff --git a/Ironsworn/Ironsworn.css b/Ironsworn/Ironsworn.css
index 346155f661..17d5954409 100644
--- a/Ironsworn/Ironsworn.css
+++ b/Ironsworn/Ironsworn.css
@@ -26,6 +26,8 @@ select::-ms-expand {
}
p {
font-family: 'Crimson Text', Arial, sans-serif;
+ font-size: 14.3px;
+ line-height: 1.25;
}
h1 {
font-weight: bold;
@@ -48,8 +50,8 @@ h2 {
h3 {
font-weight: bold;
width: 100%;
- line-height: 24px;
- font-size: 18px;
+ line-height: 1.4em;
+ font-size: 1.2em;
text-align: center;
margin: 0 0 0px;
padding: 0;
@@ -315,10 +317,10 @@ input[type=radio].sheet-sites:checked ~ div.sheet-sites {
.sheet-resources {
display: flex;
height: 2em;
+ justify-content: space-between;
}
.sheet-resource {
display: flex;
- margin-right: 0.25em;
border: 2px solid #4c4d4f;
border-left: 1px solid;
}
@@ -429,6 +431,9 @@ input[type=text].sheet-resource-value {
.sheet-miss-input {
margin: 0 !important;
}
+.sheet-failure-btn-div {
+ display: inline;
+}
input.sheet-optional-track-failures:checked ~ div.sheet-optional-track-failures {
visibility: visible;
height: auto;
@@ -634,16 +639,19 @@ input.sheet-vow-name:focus {
background: #494a4c;
color: #fff;
}
+.sheet-btn-div {
+ display: inline;
+}
.sheet-threat-header {
display: flex;
}
-input.sheet-threat-name {
+input.sheet-vow-threat {
background: #e6e7e8;
border: 2px solid #494a4c;
border-radius: 0;
width: 100%;
}
-input.sheet-threat-name:focus {
+input.sheet-vow-threat:focus {
outline: 3px solid #fd0;
outline-offset: 0;
box-shadow: inset 0 0 0 2px;
@@ -753,7 +761,7 @@ input.sheet-progress-name {
justify-content: center;
align-items: center;
padding: 2px 0px 0px 12px;
- margin-bottom: 0.4em;
+ margin: 0.3em 0em;
cursor: pointer;
border: 2px solid #4c4d4f;
border-radius: 0;
@@ -767,11 +775,76 @@ input.sheet-progress-name {
outline-offset: 0;
box-shadow: inset 0 0 0 2px;
}
-.sheet-nav-bar {
+.sheet-progress-holder {
display: flex;
- justify-content: space-evenly;
- margin-top: 0.1em;
- flex-flow: column;
+}
+input.sheet-progress-name {
+ margin-bottom: 0px;
+}
+.sheet-challenge-show {
+ padding: 0;
+ margin: 0;
+ border: 2px solid #4c4d4f;
+ width: auto;
+ height: auto;
+ cursor: pointer;
+ border-left: 0;
+}
+.sheet-challenge-show:hover {
+ background: #ccc;
+ transition: 0.5s ease;
+}
+.sheet-challenge-show-back {
+ height: 100%;
+ padding: 0em 1em 0em 1em;
+ line-height: 25px;
+}
+input[type='checkbox'].sheet-challenge-show:checked ~ div.sheet-challenge-row {
+ visibility: visible;
+ height: auto;
+ opacity: 1;
+ transition: 0.7s ease;
+}
+input[type='checkbox'].sheet-challenge-show-button:checked ~ div.sheet-challenge-show-back {
+ background: #4c4d4f;
+ color: #fff;
+}
+.sheet-challenge-row,
+.sheet-progress-row {
+ display: grid;
+ grid-template-columns: 151px repeat(10, 43.5px) 110px;
+ align-items: center;
+}
+label.sheet-challenge-label {
+ padding-left: 0.5em;
+ display: block;
+ height: 18px;
+ margin: 0px;
+}
+.sheet-challenge-box {
+ border: 2px solid #4c4d4f;
+ padding: 0;
+ display: inline-flex;
+ height: 36px;
+ width: 36px;
+ margin: 0.2em 0em;
+ cursor: pointer;
+}
+.sheet-challenge-fill {
+ height: 100%;
+ width: 100%;
+ background: #fff;
+}
+input[type="checkbox"].sheet-challenge:checked ~ .sheet-challenge-fill {
+ background: #4c4d4f;
+}
+input[type="checkbox"].sheet-challenge:hover ~ .sheet-challenge-fill {
+ background: #e6e7e8;
+}
+.blank-index {
+ display: inline-block;
+ height: 40px;
+ width: 40px;
}
.sheet-nav-child {
border: 2px solid #4c4d4f;
@@ -841,35 +914,27 @@ input[type=checkbox].sheet-momentum-burn:hover ~ div.sheet-momentum-burn-back {
transition: 0.5s ease;
}
input[type=checkbox].sheet-momentum-burn {
- width: 68px;
- height: 30px;
opacity: 0;
border: 0;
- vertical-align: top;
}
div.sheet-momentum-burn-back {
- height: 30px;
font-weight: bold;
- font-size: 18px;
- line-height: 30px;
text-align: center;
+ line-height: 22px;
+ padding: 0em 0.2em;
}
label.sheet-momentum-burn {
border: 2px solid #4c4d4f;
- width: 68px;
- height: 30px;
padding: 0;
cursor: pointer;
+ margin: 0;
+ font-size: 1em;
}
.sheet-momentum-box-input {
- width: 36px;
- height: 30px !important;
opacity: 0;
border: 0;
}
.sheet-momentum-status-box {
- width: 103px;
- height: 30px;
display: flex;
flex-direction: row;
justify-content: center;
@@ -877,27 +942,20 @@ label.sheet-momentum-burn {
border-radius: 0%;
background: transparent;
border: 2px solid #4c4d4f;
- margin-bottom: 2px;
+ padding-left: 0.2em;
}
.sheet-momentum-status-value {
width: auto;
- padding-right: 0.6em;
-}
-h3.sheet-momentum-max-box {
- display: inline;
- padding-left: 2em;
- line-height: 30px;
+ font-size: 1em;
}
+h3.sheet-momentum-max-box,
h3.sheet-momentum-reset-box {
display: inline;
padding-left: 1em;
- line-height: 30px;
}
.sheet-momentum-box-value {
font-weight: bold;
- height: 30px;
font-size: 16px;
- line-height: 30px;
color: inherit;
}
.sheet-momentum-input {
@@ -911,18 +969,32 @@ h3.sheet-momentum-reset-box {
cursor: pointer;
border: 2px solid #4c4d4f;
padding: 0;
- margin-bottom: 2px;
+ margin: 0;
}
.sheet-momentum-dark {
color: #fff;
border: 2px solid #4b4d4f;
background: #4b4d4f;
- height: 30px;
- width: 66%;
+ width: 100%;
+}
+.sheet-momentum-max,
+.sheet-momentum-reset {
+ line-height: 1.4em;
+ font-size: 1em;
}
.sheet-momentum-title {
- padding-top: 4px;
color: #fff;
+ line-height: 1.2em;
+ font-size: 1.2em;
+}
+.sheet-momentum-header {
+ height: 20px;
+}
+.sheet-sub-header-static {
+ margin-top: 0.2em;
+}
+.sheet-momentum-status-attr {
+ padding: 0em 0.2em;
}
.sheet-stats {
justify-content: space-evenly;
@@ -965,6 +1037,7 @@ label.sheet-roll-label {
border: 2px solid #4c4d4f;
cursor: pointer;
text-align: center;
+ line-height: 1.4em;
}
label.sheet-roll-label:hover {
background: #ccc;
@@ -1886,6 +1959,13 @@ div.sheet-builder-titles-3 {
}
.sheet-asset-custom {
padding: 0.2em;
+ background: linear-gradient(to bottom, #ccc 2em, #fff 2em, #fff);
+}
+.sheet-asset-custom > input[type=radio] {
+ margin-left: 4px;
+}
+.sheet-asset-custom div[class|=sheet-builder-ability] {
+ align-items: flex-start;
}
div.sheet-asset-view,
div.sheet-asset-builder {
@@ -1897,7 +1977,7 @@ input[type=checkbox].sheet-custom-asset-ability {
}
.sheet-custom-track {
width: 20.5em;
- margin-top: 0em;
+ margin: 0 !important;
}
.sheet-ability-checkbox,
.sheet-build-text {
@@ -1920,7 +2000,7 @@ input[type=checkbox].sheet-custom-asset-ability {
font-size: 14px;
}
.sheet-asset-description {
- margin: 0 12px 5px 12px;
+ margin: 0 12px 0px 12px;
font-family: 'Crimson Text', Arial, sans-serif;
}
div.sheet-asset-ability {
@@ -1952,11 +2032,14 @@ div.sheet-assets .repcontainer .repitem {
.sheet-asset-ability-write-in {
margin-top: 4px;
}
-.sheet-asset-write-in,
-.sheet-asset-ability-write-in {
+.sheet-asset-write-in {
display: flex;
white-space: nowrap;
}
+.sheet-asset-ability-write-in {
+ display: inline;
+ white-space: nowrap;
+}
.sheet-asset {
display: inline-block;
width: 320px;
@@ -2045,6 +2128,17 @@ span.sheet-custom-asset-page {
margin-left: 0.3em;
margin-right: 0.5em;
}
+.sheet-asset-description-text {
+ margin-top: 0.4em;
+}
+.sheet-asset-name {
+ display: inline;
+}
+.sheet-asset-body {
+ font-size: 14.3px;
+ line-height: 1.25;
+ margin: 0 0 4px;
+}
input.sheet-oracle-ironsworn:checked ~ div.sheet-oracle-ironsworn,
input.sheet-oracle-delve:checked ~ div.sheet-oracle-delve {
visibility: visible;
diff --git a/Ironsworn/Ironsworn.html b/Ironsworn/Ironsworn.html
index 3bd1f23248..83c8f25bd3 100644
--- a/Ironsworn/Ironsworn.html
+++ b/Ironsworn/Ironsworn.html
@@ -8,24 +8,24 @@
- CLOSE
+ CLOSE
-
SELECT THE SHEET TYPE
+ SELECT THE SHEET TYPE
- CHARACTER
+ CHARACTER
- SHARED
+ SHARED