adds liturgy and modification scren

pull/53/head
macniel 2025-10-07 18:34:26 +02:00
parent 02c7f5ad9b
commit 02acf58cd9
47 changed files with 1314 additions and 113 deletions

View File

@ -55,7 +55,7 @@ function buildDB() {
const src = join(PACK_SRC, folder.name); const src = join(PACK_SRC, folder.name);
const dest = join(PACK_DEST, folder.name); const dest = join(PACK_DEST, folder.name);
console.info(`Compiling pack ${folder.name}`); console.info(`Compiling pack ${folder.name}`);
await compilePack(src, dest, {recursive: true, log: true, nedb: false}); await compilePack(src, dest, {recursive: true, nedb: false});
} }
resolve() resolve()

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -13,6 +13,9 @@ import {EquipmentDataModel} from "./module/data/equipment.mjs";
import {AusruestungSheet} from "./module/sheets/equipmentSheet.mjs"; import {AusruestungSheet} from "./module/sheets/equipmentSheet.mjs";
import {CreatureDataModel} from "./module/data/creature.mjs"; import {CreatureDataModel} from "./module/data/creature.mjs";
import {CreatureSheet} from "./module/sheets/creatureSheet.mjs"; import {CreatureSheet} from "./module/sheets/creatureSheet.mjs";
import {LiturgySheet} from "./module/sheets/liturgySheet.mjs";
import {LiturgyDataModel} from "./module/data/liturgy.mjs";
import {BlessingDataModel} from "./module/data/blessing.mjs";
async function preloadHandlebarsTemplates() { async function preloadHandlebarsTemplates() {
return loadTemplates([ return loadTemplates([
@ -26,7 +29,8 @@ async function preloadHandlebarsTemplates() {
'systems/DSA_4-1/templates/ui/partial-action-button.hbs', 'systems/DSA_4-1/templates/ui/partial-action-button.hbs',
'systems/DSA_4-1/templates/ui/partial-equipment-button.hbs', 'systems/DSA_4-1/templates/ui/partial-equipment-button.hbs',
'systems/DSA_4-1/templates/ui/partial-equipment-group-button.hbs', 'systems/DSA_4-1/templates/ui/partial-equipment-group-button.hbs',
'systems/DSA_4-1/templates/ui/partial-array-editor.hbs' 'systems/DSA_4-1/templates/ui/partial-array-editor.hbs',
'systems/DSA_4-1/templates/dialog/modify-liturgy.hbs'
]); ]);
} }
@ -51,6 +55,8 @@ Hooks.once("init", () => {
Spell: SpellDataModel, Spell: SpellDataModel,
Advantage: VornachteileDataModel, Advantage: VornachteileDataModel,
Equipment: EquipmentDataModel, Equipment: EquipmentDataModel,
Liturgy: LiturgyDataModel,
Blessing: BlessingDataModel
} }
CONFIG.Combat.initiative = { CONFIG.Combat.initiative = {
@ -97,6 +103,11 @@ Hooks.once("init", () => {
makeDefault: true, makeDefault: true,
label: 'DSA41.AusruestungLabels.Item' label: 'DSA41.AusruestungLabels.Item'
}) })
Items.registerSheet('dsa41.liturgy', LiturgySheet, {
types: ["Liturgy"],
makeDefault: true,
label: 'DSA41.LiturgyLabels.Item'
})
return preloadHandlebarsTemplates(); return preloadHandlebarsTemplates();
}) })

View File

@ -0,0 +1,13 @@
const {
SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField
} = foundry.data.fields;
export class BlessingDataModel extends foundry.abstract.TypeDataModel {
static defineSchema() {
return {
gottheit: new StringField(),
wert: new NumberField({min: 0, integer: true}),
}
}
}

View File

@ -107,23 +107,7 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
}), }),
gilde: new StringField(), gilde: new StringField(),
}), }),
vornachteile: new ArrayField(new SchemaField({
vornachteil: new DocumentIdField(Item),
wert: new NumberField({required: false, integer: true}),
})),
sonderfertigkeiten: new ArrayField(new SchemaField({
name: new StringField(),
auswahlen: new ArrayField(new StringField()),
})),
talente: new ArrayField(new DocumentIdField(Item)),
zauber: new ArrayField(new SchemaField({
talent: new DocumentIdField(),
zfw: new NumberField({integer: true, required: true}),
})),
liturgien: new ArrayField(new SchemaField({
name: new StringField(),
})),
kampfwerte: new ArrayField(new SchemaField({ kampfwerte: new ArrayField(new SchemaField({
name: new StringField(), name: new StringField(),
at: new NumberField({required: true, integer: true}), at: new NumberField({required: true, integer: true}),

View File

@ -0,0 +1,49 @@
import BaseItem from "./base-item.mjs";
const {BooleanField, NumberField, SchemaField, ArrayField, StringField, HTMLField} = foundry.data.fields;
export class LiturgyDataModel extends BaseItem {
static defineSchema() {
return {
herkunft: new ArrayField(new SchemaField({
name: new StringField(),
grad: new NumberField(),
})),
grad: new NumberField({min: 1, max: 5}),
reichweite: new StringField(),
ziel: new StringField(),
wirkungsdauer: new StringField(),
auswirkung: new SchemaField({
I: new StringField(),
II: new StringField(),
III: new StringField(),
IV: new StringField(),
V: new StringField(),
VI: new StringField(),
VII: new StringField(),
VIII: new StringField(),
})
}
}
prepareData() {
}
/**
* Prepare a data object which is passed to any Roll formulas which are created related to this Item
* @private
*/
getRollData() {
}
/**
* Handle clickable rolls.
* @param {Event} event The originating click event
* @private
*/
async roll() {
}
}

View File

@ -0,0 +1,115 @@
export class LiturgyData {
static ranks = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII"]
static #ranks = [
{index: 0, name: "O", lkp: 3, mod: 2, costKaP: 2, costKaPPermant: 0, duration: "{*} KR", strength: "{*}/2"},
{index: 1, name: "I", lkp: 3, mod: 0, costKaP: 5, costKaPPermant: 0, duration: "{*} KR", strength: "{*}/2"},
{
index: 2,
name: "II",
lkp: 6,
mod: -2,
costKaP: 10,
costKaPPermant: 0,
duration: "{*}*10 KR",
strength: "{*}/2+5"
},
{index: 3, name: "III", lkp: 9, mod: -4, costKaP: 15, costKaPPermant: 0, duration: "{*} SR", strength: "{*}+5"},
{
index: 4,
name: "IV",
lkp: 12,
mod: -6,
costKaP: 20,
costKaPPermant: 0,
duration: "{*} Stunden",
strength: "{*}+10"
},
{
index: 5,
name: "V",
lkp: 15,
mod: -8,
costKaP: 25,
costKaPPermant: 1,
duration: "{*} Tage",
strength: "{*}+15"
},
{
index: 6,
name: "VI",
lkp: 18,
mod: -10,
costKaP: 30,
costKaPPermant: 3,
duration: "{*} Wochen",
strength: "{*}+20"
},
{
index: 7,
name: "VII",
lkp: 21,
mod: -12,
costKaP: 35,
costKaPPermant: 5,
duration: "{*} Monate",
strength: "{*}+25"
},
{
index: 8,
name: "VIII",
lkp: 24,
mod: -14,
costKaP: 40,
costKaPPermant: 7,
duration: "{*} Jahre oder permanent",
casttime: "",
strength: "{*}+30"
},
];
static alverans = [
"Praios",
"Rondra",
"Efferd",
"Travia",
"Boron",
"Hesinde",
"Firun",
"Tsa",
"Phex",
"Peraine",
"Ingerimm",
"Rahja"
]
static #aliases = [
{
"originalName": "Handwerkssegen",
"aliases": ["Cereborns Handreichung", "Hauch der Leidenschaft"]
},
{
"originalName": "Heiliger Befehl",
"aliases": ["Wort der Wahrheit"],
},
{
"originalName": "Eidsegen",
"aliases": ["Lehnseid"],
}
]
static getRankOfLiturgy(liturgy, deity) {
const lookupData = liturgy.herkunft.find(p => p.name === deity)
const rank = lookupData?.grad;
return LiturgyData.#ranks[rank];
}
static lookupAlias(alias) {
return LiturgyData.#aliases.find((entry) => {
console.log(alias, entry.aliases.indexOf(alias) !== -1)
return entry.aliases.indexOf(alias) !== -1
})?.originalName ?? alias; // cant determine thus simply return the original query name
}
}

View File

@ -0,0 +1,89 @@
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
export class ModifyLiturgy {
static data = {}
static naming = {
"range": "Reichweite",
"strength": "Wirkung",
"target": "Ziele",
"castduration": "Wirkzeit",
"duration": "Wirkdauer"
}
constructor(data) {
ModifyLiturgy.data = data;
ModifyLiturgy.data.maxmods = Math.round(data.lkp / 3);
ModifyLiturgy.data.variation = null;
console.log("ModifyLiturgy constructed", data)
}
static renderMods(html) {
let result = '';
ModifyLiturgy.data.mods.forEach(((mod, index) => {
result += `<tr><td>${LiturgyData.ranks[mod.rank]}</td><td>${ModifyLiturgy.naming[mod.mod]}</td><td><button class="remove-mod" data-index="${index}"><i class="fa-solid fa-xmark"></i></button></td></tr>`
}))
return result;
}
handleRender(html) {
html.off('click', 'input[name="data.variation"]')
html.on('click', 'input[name="data.variation"]', (evt) => {
if (evt.currentTarget.checked) {
ModifyLiturgy.data.variation = evt.currentTarget.dataset['rank'];
ModifyLiturgy.data.mods = [];
}
this.render(html)
})
html.off('click', 'button[class="remove-mod"]')
html.on('click', 'button[class="remove-mod"]', (evt) => {
const {index} = evt.currentTarget.dataset;
ModifyLiturgy.data.mods.splice(index, 1);
this.render(html)
})
html.off('change', 'select[name="mod"]')
html.on('change', 'select[name="mod"]', (evt) => {
const value = evt.currentTarget.value;
if (value === '') return;
const currentRank = ModifyLiturgy.data.mods.length + Number(ModifyLiturgy.data.rank);
ModifyLiturgy.data.mods.push({
rank: currentRank,
mod: value,
});
evt.currentTarget.value = "";
this.render(html)
})
// render state
$('#mods', html).html(ModifyLiturgy.renderMods(html))
// state handling
if (ModifyLiturgy.data.mods.length === ModifyLiturgy.data.maxmods) {
$(".editor, .editor *", html).attr('disabled', 'disabled');
$(".editor select", html).hide();
$('span#info', html).text('LkW lässt keine weitere Modifikationen zu')
$("#mod_rank", html).text(LiturgyData.ranks[ModifyLiturgy.data.mods.length + Number(ModifyLiturgy.data.rank)]);
} else if (ModifyLiturgy.data.variation == null) {
$(".editor select *", html).attr('disabled', 'disabled');
$(".editor select", html).hide();
$('span#info', html).text('Keine Variante ausgewählt')
$("#mod_rank", html).text('');
} else {
$(".editor, .editor *", html).removeAttr('disabled');
$(".editor select", html).show();
$('span#info', html).text('')
$("#mod_rank", html).text('');
}
}
}

View File

@ -0,0 +1,9 @@
export class Blessing extends Item {
/**
* Augment the basic Item data model with additional dynamic data.
*/
prepareData() {
super.prepareData();
}
}

View File

@ -1,4 +1,5 @@
import {importCharacter} from "../xml-import/xml-import.mjs"; import {importCharacter} from "../xml-import/xml-import.mjs";
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
export class Character extends Actor { export class Character extends Actor {
@ -42,12 +43,29 @@ export class Character extends Actor {
systemData.aup.max = Math.round((mu + ko + ge) / 2) + systemData.aup.mod; systemData.aup.max = Math.round((mu + ko + ge) / 2) + systemData.aup.mod;
systemData.asp.max = Math.round((mu + _in + ch) / 2) + systemData.asp.mod; systemData.asp.max = Math.round((mu + _in + ch) / 2) + systemData.asp.mod;
systemData.at = Math.round((mu + ge + kk) / 5); systemData.at = Math.round((mu + ge + kk) / 5);
systemData.pa = Math.round((_in + ge + kk) / 5); systemData.pa = Math.round((_in + ge + kk) / 5);
systemData.fk = Math.round((_in + ff + kk) / 5); systemData.fk = Math.round((_in + ff + kk) / 5);
systemData.ini.aktuell = Math.round((mu + mu + _in + ge) / 5) + systemData.ini.mod; systemData.ini.aktuell = Math.round((mu + mu + _in + ge) / 5) + systemData.ini.mod;
systemData.mr.aktuell = Math.round((mu + kl + ko) / 5) + systemData.mr.mod; systemData.mr.aktuell = Math.round((mu + kl + ko) / 5) + systemData.mr.mod;
// evaluate deities for KaP
systemData.rs = 0;
systemData.kap.max = 0;
const deities = systemData.parent.items.filter(p => p.type === "Blessing")
deities?.forEach((deity) => {
if (LiturgyData.alverans.includes(deity.system.gottheit)) {
systemData.kap.max = 24;
} else if (systemData.kap.max === 0) {
systemData.kap.max += 12;
}
}, 0)
} }

View File

@ -0,0 +1,9 @@
export class Liturgy extends Item {
/**
* Augment the basic Item data model with additional dynamic data.
*/
prepareData() {
super.prepareData();
}
}

View File

@ -202,11 +202,11 @@ export class ActionManager {
] ]
#hatSonderfertigkeitBeginnendMit(name) { #hatSonderfertigkeitBeginnendMit(name) {
return this.actor.system.sonderfertigkeiten.find(p => p.name.startsWith(name)) != null return this.actor.system.sonderfertigkeiten?.find(p => p.name.startsWith(name)) != null
} }
#hatSonderfertigkeit(name) { #hatSonderfertigkeit(name) {
return this.actor.system.sonderfertigkeiten.find(p => p.name === name) != null return this.actor.system.sonderfertigkeiten?.find(p => p.name === name) != null
} }
evaluate() { evaluate() {

View File

@ -1,5 +1,7 @@
import {PlayerCharacterDataModel} from "../data/character.mjs"; import {PlayerCharacterDataModel} from "../data/character.mjs";
import {ActionManager} from "./actions/action-manager.mjs"; import {ActionManager} from "./actions/action-manager.mjs";
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
import {ModifyLiturgy} from "../dialog/modify-liturgy.mjs";
export class CharacterSheet extends ActorSheet { export class CharacterSheet extends ActorSheet {
/**@override */ /**@override */
@ -23,26 +25,28 @@ export class CharacterSheet extends ActorSheet {
return `systems/DSA_4-1/templates/actor/actor-character-sheet.hbs`; return `systems/DSA_4-1/templates/actor/actor-character-sheet.hbs`;
} }
/** @override */ static onDroppedData(actor, characterSheet, data) {
async getData() { const uuid = foundry.utils.parseUuid(data.uuid);
const context = super.getData(); const collection = uuid.collection.index ?? uuid.collection;
const document = CharacterSheet.getElementByName(collection, uuid.id);
const {
name,
type
} = document
console.log(name, type)
switch (type) {
case "Skill":
return characterSheet.#handleDroppedSkill(actor, document); // on false cancel this whole operation
case "Advantage":
return characterSheet.#handleDroppedAdvantage(actor, document);
case "Equipment":
return characterSheet.#handleDroppedEquipment(actor, document);
case "Liturgy":
return characterSheet.#handleDroppedLiturgy(actor, document);
default:
return false;
}
// Use a safe clone of the actor data for further operations.
const actorData = context.data;
// Add the actor's data to context.data for easier access, as well as flags.
context.system = actorData.system;
context.flags = actorData.flags;
this.#addSkillsToContext(context)
this.#addAdvantagesToContext(context)
this.#addAttributesToContext(context)
this.#addEquipmentsToContext(context)
await this.#addCombatStatistics(context)
this.#addActionsToContext(context)
this.#addSpellsToContext(context)
return context;
} }
static getElementByName(collection, id) { static getElementByName(collection, id) {
@ -101,6 +105,30 @@ export class CharacterSheet extends ActorSheet {
return merkmale.split(",").map((merkmal) => merkmal.trim()) return merkmale.split(",").map((merkmal) => merkmal.trim())
} }
/** @override */
async getData() {
const context = super.getData();
// Use a safe clone of the actor data for further operations.
const actorData = context.data;
// Add the actor's data to context.data for easier access, as well as flags.
context.system = actorData.system;
context.flags = actorData.flags;
context.derived = context.document.system;
this.#addSkillsToContext(context)
this.#addAdvantagesToContext(context)
this.#addAttributesToContext(context)
this.#addEquipmentsToContext(context)
await this.#addCombatStatistics(context)
this.#addActionsToContext(context)
this.#addSpellsToContext(context)
this.#addLiturgiesToContext(context)
return context;
}
#addSpellsToContext(context) { #addSpellsToContext(context) {
const actorData = context.data; const actorData = context.data;
context.spells = []; context.spells = [];
@ -127,6 +155,7 @@ export class CharacterSheet extends ActorSheet {
}) })
} }
}) })
context.hasSpells = context.spells.length > 0;
} }
#addAttributesToContext(context) { #addAttributesToContext(context) {
@ -566,6 +595,116 @@ export class CharacterSheet extends ActorSheet {
} }
#addLiturgiesToContext(context) {
const actorData = context.data;
context.liturgies = [];
context.blessings = [];
Object.values(actorData.items).forEach((item, index) => {
if (item.type === "Blessing") {
context.blessings.push({
deity: item.system.gottheit,
value: item.system.wert
})
}
})
Object.values(actorData.items).forEach((item, index) => {
if (item.type === "Liturgy") {
context.blessings.forEach(({deity, value}) => {
let insertObject = context.liturgies.find(p => p.deity === deity);
if (!insertObject) {
insertObject = {
deity: deity,
lkp: value,
O: [],
I: [],
II: [],
III: [],
IV: [],
V: [],
VI: [],
VII: [],
VIII: [],
"NA": [],
countO: 1,
countI: 1,
countII: 1,
countIII: 1,
countIV: 1,
countV: 1,
countVI: 1,
countVII: 1,
countVIII: 1,
countNA: 0,
total: 3,
}
context.liturgies.push(insertObject);
}
// sort by rank
const rankData = LiturgyData.getRankOfLiturgy(item.system, deity)
if (rankData) {
let {index, name, lkp, mod, costKaP} = rankData;
insertObject["count" + name] = insertObject["count" + name] + 1;
insertObject[name].push({
id: item._id,
name: item.name,
lkpReq: lkp,
lkpMod: mod,
costKaP,
rank: index, // get effective liturgy rank based on deity
liturgiekenntnis: deity,
})
insertObject.total = insertObject.total + 1;
}
})
}
})
// clean up counter
Object.values(context.liturgies).forEach((litObject) => {
if (litObject.O.length === 0) litObject.countO = false;
if (litObject.I.length === 0) litObject.countI = false;
if (litObject.II.length === 0) litObject.countII = false;
if (litObject.III.length === 0) litObject.countIII = false;
if (litObject.IV.length === 0) litObject.countIV = false;
if (litObject.V.length === 0) litObject.countV = false;
if (litObject.VI.length === 0) litObject.countVI = false;
if (litObject.VII.length === 0) litObject.countVII = false;
if (litObject.VIII.length === 0) litObject.countVIII = false;
if (litObject.NA.length === 0) litObject.countNA = false;
})
context.hasLiturgies = context.blessings.length > 0;
}
#handleDroppedSkill(actor, skill) {
const array = Array.from(actor.items);
for (let i = 0; i < array.length; i++) {
if (array[i].name === skill.name) {
return false;
}
}
}
#handleDroppedAdvantage(actor, advantage) {
const array = Array.from(actor.items);
for (let i = 0; i < array.length; i++) {
if (array[i].name === advantage.name) { // TODO: adjust for uniqueness
return false;
}
}
}
activateListeners(html) { activateListeners(html) {
super.activateListeners(html); super.activateListeners(html);
@ -698,57 +837,77 @@ export class CharacterSheet extends ActorSheet {
} }
]); ]);
} html.on('click', '.liturgy.rollable', async (evt) => {
#handleDroppedSkill(actor, skill) { evt.stopPropagation();
const array = Array.from(actor.items);
for (let i = 0; i < array.length; i++) { const {id, rank, lkp, deity} = evt.currentTarget.dataset;
if (array[i].name === skill.name) { const document = await this.object.items.get(id)
return false;
} const data = {};
}
} data.rank = rank;
data.lkp = lkp;
data.deity = deity;
data.variations = [];
const ranks = LiturgyData.ranks
ranks.forEach(rank => {
if (document.system.auswirkung[rank]) {
data.variations.push({
rank,
effect: document.system.auswirkung[rank]
})
}
})
data.mods = [];
const htmlContent = await renderTemplate('systems/DSA_4-1/templates/dialog/modify-liturgy.hbs', data);
const dialogData = {
title: document.name,
content: htmlContent,
data: {},
buttons: {
submit: {
label: "Wirken",
icon: '<i class="fas fa-die"></i>',
callback: (html) => {
},
},
},
}
dialogData.render = new ModifyLiturgy(data).handleRender
const dialog = new Dialog(dialogData, {
classes: ['dsa41', 'dialog', 'liturgy'],
height: 480
})
dialog.render(true);
#handleDroppedAdvantage(actor, advantage) {
const array = Array.from(actor.items);
for (let i = 0; i < array.length; i++) {
if (array[i].name === advantage.name) { // TODO: adjust for uniqueness
return false; return false;
} })
}
} }
#handleDroppedEquipment(actor, equipment) { #handleDroppedEquipment(actor, equipment) {
const array = Array.from(actor.items); const array = Array.from(actor.items);
for (let i = 0; i < array.length; i++) { for (let i = 0; i < array.length; i++) {
if (array[i].name === equipment.name) { // TODO: adjust item quantity if item is the same if (array[i].name === equipment.name) { // TODO: adjust item quantity if item is the same
console.log(equipment);
return false; return false;
} }
} }
} }
static onDroppedData(actor, characterSheet, data) { #handleDroppedLiturgy(actor, liturgy) {
const uuid = foundry.utils.parseUuid(data.uuid); const array = Array.from(actor.items);
const collection = uuid.collection.index ?? uuid.collection; for (let i = 0; i < array.length; i++) {
const document = CharacterSheet.getElementByName(collection, uuid.id); if (array[i].name === liturgy.name) { // TODO: allow multiple miracles with the same name
const {
name,
type
} = document
console.log(name, type)
switch (type) {
case "Skill":
return characterSheet.#handleDroppedSkill(actor, document); // on false cancel this whole operation
case "Advantage":
return characterSheet.#handleDroppedAdvantage(actor, document);
case "Equipment":
return characterSheet.#handleDroppedEquipment(actor, document);
default:
return false; return false;
} }
}
} }
} }

View File

@ -0,0 +1,48 @@
export class LiturgySheet extends ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ['dsa41', 'sheet', 'item', 'liturgy'],
width: 520,
height: 480,
tabs: [
{
navSelector: '.sheet-tabs',
contentSelector: '.sheet-body',
initial: 'description',
},
],
});
}
/** @override */
get template() {
return `systems/DSA_4-1/templates/item/item-liturgy-sheet.hbs`;
}
/** @override */
getData() {
// Retrieve the data structure from the base sheet. You can inspect or log
// the context variable to see the structure, but some key properties for
// sheets are the actor object, the data object, whether or not it's
// editable, the items array, and the effects array.
const context = super.getData();
// Use a safe clone of the actor data for further operations.
const liturgyData = context.data;
// Add the actor's data to context.data for easier access, as well as flags.
context.system = liturgyData.system;
context.flags = liturgyData.flags;
context.json = JSON.stringify(liturgyData);
return context;
}
activateListeners(html) {
super.activateListeners(html);
// Everything below here is only needed if the sheet is editable
if (!this.isEditable)
}
}

View File

@ -1,3 +1,7 @@
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
import {BlessingDataModel} from "../data/blessing.mjs";
import {Blessing} from "../documents/blessing.mjs";
let months = [ let months = [
"Praios", "Praios",
"Rondra", "Rondra",
@ -71,7 +75,7 @@ function getJsonFromXML(dom) {
} }
async function addSkillFromCompendiumByNameToActor(talentName, taw, actor) { async function addSkillFromCompendiumByNameToActor(talentName, taw, actor) {
const compendiumOfSkills = game.packs.get('DSA_4-1.talente-brw'); const compendiumOfSkills = game.packs.get('DSA_4-1.talente');
const talentId = compendiumOfSkills.index.find(skill => skill.name === talentName) const talentId = compendiumOfSkills.index.find(skill => skill.name === talentName)
if (talentId) { if (talentId) {
@ -119,6 +123,23 @@ async function addSpellsFromCompendiumByNameToActor(spellName, zfw, representati
} }
} }
async function addLiturgiesFromCompendiumByNameToActor(liturgyName, actor) {
const compendiumOfLiturgies = game.packs.get('DSA_4-1.liturgien');
const liturgyId = compendiumOfLiturgies.index.find(liturgy => {
return liturgy.name === LiturgyData.lookupAlias(liturgyName.split(" (")[0])
})
if (liturgyId) {
const liturgy = await compendiumOfLiturgies.getDocument(liturgyId._id);
try {
await actor.createEmbeddedDocuments('Item', [liturgy])
} catch (error) {
console.error(`${liturgy} not found in items`, error)
}
}
}
/** /**
* gets the text content of a file * gets the text content of a file
* @param file the file with the desired content * @param file the file with the desired content
@ -153,9 +174,27 @@ function calculateBirthdate(json) {
function mapSkills(actor, held) { function mapSkills(actor, held) {
for (let talent in held.talentliste.talent) { for (let talent in held.talentliste.talent) {
talent = held.talentliste.talent[talent] talent = held.talentliste.talent[talent]
// hook liturgy
if (talent.name.startsWith("Liturgiekenntnis")) {
actor.createEmbeddedDocuments('Item', [
new Blessing({
name: talent.name,
type: "Blessing",
system: {
gottheit: new RegExp("\\((.+)\\)").exec(talent.name)[1],
wert: talent.value
}
})
])
} else {
// proceed
addSkillFromCompendiumByNameToActor(talent.name, talent.value, actor) addSkillFromCompendiumByNameToActor(talent.name, talent.value, actor)
} }
} }
}
function mapAdvantages(actor, held) { function mapAdvantages(actor, held) {
for (let advantage in held.vt.vorteil) { for (let advantage in held.vt.vorteil) {
@ -171,6 +210,13 @@ function mapSpells(actor, held) {
} }
} }
function mapMiracles(actor, liturgies) {
for (let liturgy in liturgies) {
liturgy = liturgies[liturgy]
addLiturgiesFromCompendiumByNameToActor(liturgy.name, actor)
}
}
/** /**
* parses a json into a fitting character-json * parses a json into a fitting character-json
* @param rawJson the json parsed from the Helden-Software XML * @param rawJson the json parsed from the Helden-Software XML
@ -291,6 +337,8 @@ function mapRawJson(actor, rawJson) {
mapSkills(actor, held) mapSkills(actor, held)
mapSpells(actor, held) mapSpells(actor, held)
mapMiracles(actor, liturgies)
let combatValues = [] let combatValues = []
for (let combatValue in held.kampf.kampfwerte) { for (let combatValue in held.kampf.kampfwerte) {
combatValue = held.kampf.kampfwerte[combatValue] combatValue = held.kampf.kampfwerte[combatValue]

View File

@ -104,46 +104,37 @@
.tab.combat { .tab.combat {
.initiaitve {
width: 100%;
height: 48px;
position: relative;
label {
width: 80px;
line-height: 48px;
vertical-align: middle;
}
input {
display: inline-block;
width: 40px;
height: 48px;
}
span.inline {
line-height: 48px;
vertical-align: middle;
width: 40px;
text-align: center;
}
}
} }
.tab.spells { .tab.spells {
tr {
height: 24px;
margin: 0;
padding: 0;
}
td {
margin: 0;
padding: 0;
height: 24px;
}
$color: #05f;
.spell.rollable svg { .spell.rollable svg {
width: 24px; width: 24px;
height: 24px; height: 24px;
top: 1px;
z-index: 1;
position: relative;
.border { .border {
fill: #0000; fill: #0000;
} }
$color: #05f;
.center { .center {
fill: $color; fill: $color;
stroke: colour.$rollable-die-border-color; stroke: colour.$rollable-die-border-color;
@ -170,6 +161,46 @@
} }
} }
.die-column {
width: 24px;
}
.clickable {
span {
position: relative;
z-index: 1;
}
}
tbody {
tr {
position: relative;
&::after {
content: '';
background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_light), numbers.$end_2_gradient));
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
position: absolute;
top: 2px;
left: 12px;
bottom: 2px;
right: 33%;
z-index: 0;
pointer-events: none;
}
&:nth-child(odd) {
&::after {
background-image: linear-gradient(to right, rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$start_gradient), rgba(color.scale($color, $lightness: numbers.$zebra_dark), numbers.$end_2_gradient));
}
}
}
}
.merkmal-list { .merkmal-list {
list-style: none; list-style: none;
margin: 0; margin: 0;
@ -184,6 +215,70 @@
} }
.tab.liturgies {
table {
border-top: unset;
border-bottom: unset;
position: relative;
}
.liturgy-header {
background: unset;
border: unset;
tr {
height: 90px;
th {
vertical-align: middle;
color: black;
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.2);
}
}
}
td, th {
padding-left: 8px;
}
}
.tab-resources {
display: flex;
justify-content: center;
gap: 0 16px;
padding-bottom: 8px;
& > div {
height: 48px;
position: relative;
label {
width: 80px;
line-height: 48px;
vertical-align: middle;
}
input {
display: inline-block;
width: 40px;
height: 48px;
}
span.inline {
line-height: 48px;
vertical-align: middle;
width: 40px;
text-align: center;
}
}
}
} }
} }

View File

@ -0,0 +1,247 @@
@use "sass:map";
@use "sass:color";
@use "colours" as colour;
@use "numbers";
$deity_colours_border: (
"Praios": orange,
"Rondra": red,
"Efferd": #74d0ec,
"Travia": #c6491a,
"Boron": #515151,
"Hesinde": #089e08,
"Firun": #8fdeff,
"Tsa": #6a24d8,
"Phex": #1569da,
"Peraine": #56a116,
"Ingerimm": #a53d19,
"Rahja": #ed70c2,
);
$deity_colours_tint: (
"Praios": rgba(orange, 0.5),
"Rondra": rgba(red, 0.5),
"Efferd": rgba(#74d0ec, 0.5),
"Travia": rgba(#c6491a, 0.5),
"Boron": rgba(#515151, 0.5),
"Hesinde": rgba(#089e08, 0.5),
"Firun": rgba(#8fdeff, 0.5),
"Tsa": linear-gradient(
-45deg,
rgba(255, 0, 0, 0.5) 0%,
rgba(255, 154, 0, 0.5) 10%,
rgba(208, 222, 33, 0.5) 20%,
rgba(79, 220, 74, 0.5) 30%,
rgba(63, 218, 216, 0.5) 40%,
rgba(47, 201, 226, 0.5) 50%,
rgba(28, 127, 238, 0.5) 60%,
rgba(95, 21, 242, 0.5) 70%,
rgba(186, 12, 248, 0.5) 80%,
rgba(251, 7, 217, 0.5) 90%,
rgba(255, 0, 0, 0.5) 100%
),
"Phex": rgba(#1569da, 0.5),
"Peraine": rgba(#56a116, 0.5),
"Ingerimm": rgba(#a53d19, 0.5),
"Rahja": rgba(#ed70c2, 0.5),
);
@mixin coloring($name) {
$color: map.get($deity_colours_border, $name);
$color-tint: map.get($deity_colours_tint, $name);
&.#{$name} {
th.background {
&::after {
background: $color-tint;
}
}
.banner-bot {
border-color: $color;
}
.banner-mid {
border-color: $color;
}
.banner-top {
&::before, &::after {
border-color: $color;
}
}
}
}
.tab.liturgies {
table {
@include coloring('Praios');
@include coloring('Rondra');
@include coloring('Efferd');
@include coloring('Travia');
@include coloring('Boron');
@include coloring('Hesinde');
@include coloring('Firun');
@include coloring('Tsa');
@include coloring('Phex');
@include coloring('Peraine');
@include coloring('Ingerimm');
@include coloring('Rahja');
tr {
th.background {
&::before {
position: absolute;
content: '';
background-image: url("../assets/velvet_strip.png");
background-repeat: repeat-y;
background-size: cover;
width: 86px;
height: 100%;
top: 45px;
left: 12px;
}
&::after { /* for tinting the texture */
content: "";
position: absolute;
width: 86px;
height: 100%;
top: 45px;
left: 12px;
}
}
}
.banner-top {
position: relative;
width: 90px;
img {
position: absolute;
top: 2px;
left: 1px;
width: 90px;
height: 90px;
border: 0;
z-index: 1;
}
&::after {
z-index: 0;
border-width: 0 4px 0 4px;
//background-color: #64b;
border-style: solid;
position: absolute;
content: "";
left: -2px;
top: 45px;
bottom: 0;
width: 94px;
}
&::before {
position: absolute;
border-radius: 45px;
height: 94px;
width: 94px;
content: '';
left: -2px;
right: -2px;
top: 0;
border-width: 4px;
border-style: solid;
z-index: 2;
}
}
.banner-mid {
position: relative;
border-width: 0 4px 0 4px;
//background-color: #64b;
border-style: solid;
width: 90px;
div {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
div.rank-label {
position: absolute;
left: 2px;
right: 2px;
top: 0;
bottom: 0;
border-bottom: 2px solid black;
color: gold;
text-shadow: 2px 2px 1px black;
}
}
}
.banner-bot {
position: relative;
border-width: 4px;
border-style: solid;
width: 90px;
height: 12px;
}
}
.liturgy.rollable {
width: 24px;
svg {
$color: #e4de61;
width: 24px;
height: 24px;
top: 1px;
z-index: 1;
position: relative;
.border {
fill: #0000;
}
.center {
fill: $color;
stroke: colour.$rollable-die-border-color;
}
.topleft {
fill: color.adjust($color, $lightness: numbers.$lighter_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomleft {
fill: color.adjust($color, $lightness: numbers.$lightest_factor);
stroke: colour.$rollable-die-border-color;
}
.topright {
fill: color.adjust($color, $lightness: numbers.$darken_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomright, .bottom {
fill: color.adjust($color, $lightness: numbers.$darkest_factor);
stroke: colour.$rollable-die-border-color;
}
}
}
.clickable:hover {
text-shadow: 0 0 10px rgb(255 0 0);
}
}

View File

@ -0,0 +1,45 @@
.dsa41.dialog.liturgy {
table {
tr {
th:first-child {
width: 48px;
}
}
}
table#mods {
tr {
th:first-child {
width: 48px;
}
}
.remove-mod {
width: 32px;
height: 32px;
}
}
.editor {
display: grid;
grid-template-columns: 48px 1fr;
#mod_rank {
display: inline-block;
width: 48px;
}
select {
}
}
.dialog-buttons {
flex: 0;
}
}

View File

@ -4,6 +4,7 @@ $darken_factor: -15%;
$darkest_factor: -40%; $darkest_factor: -40%;
$start_gradient: 0.8; $start_gradient: 0.8;
$end_gradient: 0.2; $end_gradient: 0.2;
$end_2_gradient: 0;
$direction_gradient: 90deg; $direction_gradient: 90deg;
$tab-border-width: 1px; $tab-border-width: 1px;
@ -17,3 +18,6 @@ $dice-box-border-width: 1px;
$pill-box-inset: 2px; $pill-box-inset: 2px;
$pill-box-blur-radius: 4px; $pill-box-blur-radius: 4px;
$zebra-dark: 0%;
$zebra-light: 20%;

View File

@ -9,3 +9,5 @@
@use "_paperdoll"; @use "_paperdoll";
@use "_creature-sheet"; @use "_creature-sheet";
@use "_player-action"; @use "_player-action";
@use "_modify-liturgy";
@use "_liturgy-banner";

View File

@ -26,11 +26,11 @@
], ],
"packs": [ "packs": [
{ {
"name": "talente-brw", "name": "talente",
"label": "Talente (BRW)", "label": "Talente",
"system": "DSA_4-1", "system": "DSA_4-1",
"type": "Item", "type": "Item",
"path": "packs/talente-brw", "path": "packs/talente",
"private": false "private": false
}, },
{ {
@ -183,6 +183,8 @@
"voraussetzung" "voraussetzung"
] ]
}, },
"Blessing": {},
"Liturgy": {},
"Spell": { "Spell": {
"stringFields": [ "stringFields": [
"name", "name",

View File

@ -56,8 +56,8 @@
<a class="item" data-tab="combat">Kampf</a> <a class="item" data-tab="combat">Kampf</a>
<a class="item" data-tab="skills">Talente</a> <a class="item" data-tab="skills">Talente</a>
<a class="item" data-tab="backpack">Inventar</a> <a class="item" data-tab="backpack">Inventar</a>
<a class="item" data-tab="spells">Zauber</a> {{#if this.hasSpells}}<a class="item" data-tab="spells">Zauber</a>{{/if}}
<a class="item" data-tab="miracles">Liturgien</a> {{#if this.hasLiturgies}}<a class="item" data-tab="liturgies">Liturgien</a>{{/if}}
<a class="item" data-tab="pets">Begleiter</a> <a class="item" data-tab="pets">Begleiter</a>
</nav> </nav>
@ -88,6 +88,8 @@
<div class="tab combat" data-group="primary" data-tab="combat"> <div class="tab combat" data-group="primary" data-tab="combat">
<div class="tab-resources">
<div class="initiaitve"> <div class="initiaitve">
<label>Initiative:</label> <label>Initiative:</label>
<input type="number" name="system.attribute.ini.wuerfel" value="{{this.inidice}}"/> <input type="number" name="system.attribute.ini.wuerfel" value="{{this.inidice}}"/>
@ -106,6 +108,11 @@
<span class="inline">von</span> <span class="inline">von</span>
<input type="number" name="system.aup.max" value="{{actor.system.aup.max}}"/> <input type="number" name="system.aup.max" value="{{actor.system.aup.max}}"/>
</div> </div>
<div class="armor">
<label>RS:</label>
{{derived.rs}}
</div>
</div>
<div class="actions"> <div class="actions">
{{#each this.actions}} {{#each this.actions}}
@ -253,12 +260,27 @@
</div> </div>
</div> </div>
{{#if this.hasSpells}}
<div class="tab spells" data-group="primary" data-tab="spells"> <div class="tab spells" data-group="primary" data-tab="spells">
<div class="tab-resources">
<div class="astralpoints">
<label>AsP:</label>
<input type="number" name="system.asp.aktuell" value="{{system.asp.aktuell}}"/>
<span class="inline">von</span>
{{derived.asp.max}}
</div>
<div class="mr">
<label>MR: </label>
{{derived.mr.aktuell}}
</div>
</div>
<table> <table>
<thead> <thead>
<tr> <tr>
<th></th> <th class="die-column"></th>
<th>Zaubername</th> <th>Zaubername</th>
<th colspan="3">Probe</th> <th colspan="3">Probe</th>
<th>ZfW</th> <th>ZfW</th>
@ -271,7 +293,8 @@
<td class="spell rollable"> <td class="spell rollable">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }} {{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td> </td>
<td class="clickable" data-id="{{this.id}}" data-operation="openActorSheet">{{this.name}}</td> <td class="clickable" data-id="{{this.id}}" data-operation="openActorSheet">
<span>{{this.name}}</span></td>
<td>{{this.eigenschaft1}}</td> <td>{{this.eigenschaft1}}</td>
<td>{{this.eigenschaft2}}</td> <td>{{this.eigenschaft2}}</td>
<td>{{this.eigenschaft3}}</td> <td>{{this.eigenschaft3}}</td>
@ -286,9 +309,188 @@
</table> </table>
</div> </div>
<div class="tab miracles" data-group="primary" data-tab="miracles"> {{/if}}
{{#if this.hasLiturgies}}
<div class="tab liturgies" data-group="primary" data-tab="liturgies">
<div class="tab-resources">
<div class="karmapoints">
<label>KaP:</label>
<input type="number" name="system.kap.aktuell" value="{{system.kap.aktuell}}"/>
<span class="inline">von</span>
{{derived.kap.max}}
</div>
</div>
{{#each this.liturgies}}
<table class="{{this.deity}}">
<thead class="liturgy-header">
<tr class="liturgy-header">
<th style="width: 0"></th>
<th class="banner-top" style="width: 90px"><img
src="systems/DSA_4-1/assets/deities/{{this.deity}}.png"/></th>
<th colspan="2">Liturgiekenntnis: {{this.lkp}}</th>
</tr>
</thead>
<tbody>
{{#if this.countI}}
<tr>
<th rowspan="{{this.total}}" class="background"></th>
<th class="banner-mid" rowspan="{{countI}}">
<div>
<div class="rank-label">I</div>
</div>
</th>
</tr>
{{#each this.I}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}" data-operation="openActorSheet">
{{this.name}}</td>
<td></td>
</tr>
{{/each}}
{{/if}}
{{#if this.countII}}
<tr>
<th class="banner-mid" rowspan="{{countII}}">
<div>
<div class="rank-label">II</div>
</div>
</th>
</tr>
{{#each this.II}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-operation="openActorSheet">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
{{#if this.countIII}}
<tr>
<th class="banner-mid" rowspan="{{countIII}}">
<div>
<div class="rank-label">III</div>
</div>
</th>
</tr>
{{#each this.III}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-operation="openActorSheet">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
{{#if this.countIV}}
<tr>
<th class="banner-mid" rowspan="{{countIV}}">
<div>
<div class="rank-label">IV</div>
</div>
</th>
</tr>
{{#each this.IV}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-operation="openActorSheet">{{this.name}}</td>
</tr>
{{/each}}{{/if}}
{{#if this.countV}}
<tr>
<th class="banner-mid" rowspan="{{countV}}">
<div>
<div class="rank-label">V</div>
</div>
</th>
</tr>
{{#each this.V}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-operation="openActorSheet">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
{{#if this.countVI}}
<tr>
<th class="banner-mid" rowspan="{{countVI}}">
<div>
<div class="rank-label">VI</div>
</div>
</th>
</tr>
{{#each this.VI}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-operation="openActorSheet">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}{{#if this.countVII}}
<tr>
<th class="banner-mid" rowspan="{{countVII}}">
<div>
<div class="rank-label">VII</div>
</div>
</th>
</tr>
{{#each this.VII}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-operation="openActorSheet">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}{{#if this.countVIII}}
<tr>
<th class="banner-mid" rowspan="{{countVIII}}">
<div>
<div class="rank-label">VIII</div>
</div>
</th>
</tr>
{{#each this.VIII}}
<tr>
<td class="liturgy rollable" data-id="{{this.id}}" data-rank="{{this.rank}}"
data-lkp="{{../lkp}}" data-deity="{{this.deity}}">
{{> 'systems/DSA_4-1/templates/ui/partial-die.hbs' }}
</td>
<td class="clickable" data-id="{{this.id}}"
data-operation="openActorSheet">{{this.name}}</td>
</tr>
{{/each}}
{{/if}}
</tbody>
</table>
{{/each}}
</div> </div>
{{/if}}
<div class="tab pets" data-group="primary" data-tab="pets"> <div class="tab pets" data-group="primary" data-tab="pets">
</div> </div>

View File

@ -0,0 +1,36 @@
<table>
<tr>
<th>Grad</th>
<th>Wirkung</th>
</tr>
</th>
{{#each variations}}
<tr>
<th><label><input type="radio" name="data.variation" data-rank="{{this.rank}}">{{this.rank}}</label></th>
<td>{{this.effect}}</td>
</tr>
{{/each}}
</table>
<h2>Modifizieren</h2>
<table id="mods"></table>
<div class="editor">
<div id="mod_rank" class="rank"></div>
<div class="modification">
<select name="mod" disabled="disabled">
<option value=""> - auswählen -</option>
<option value="range">Reichweite</option>
<option value="strength">Wirkung</option>
<option value="target">Ziele</option>
<option value="castduration">Wirkzeit</option>
<option value="duration">Wirkungsdauer</option>
</select>
<span id="info"></span>
</div>
</div>
<div class="result"></div>

View File

@ -0,0 +1,14 @@
<form class="{{cssClass}} {{actor.type}} flexcol" autocomplete="off">
{{!-- Sheet Tab Navigation --}}
<nav class="sheet-tabs tabs" style="flex: 0" data-group="primary">
<a class="item" data-tab="json">JSON</a>
</nav>
{{!-- Sheet Body --}}
<section class="sheet-body" style="flex: 1">
<div class="tab json" data-group="primary" data-tab="json">
<pre style="overflow: auto; white-space: normal; position: relative; top: 8px; bottom: 8px; left: 8px; right: 8px">{{json}}</pre>
</div>
</section>
</form>

View File

@ -1,6 +1,6 @@
let crypto; let crypto;
import {readdirSync, readFileSync, writeFileSync} from "fs"; import {readdirSync, readFileSync, writeFileSync, rmdirSync, rmSync, mkdirSync} from "fs";
import {join} from "path"; import {join} from "path";
try { try {
@ -46,18 +46,20 @@ try {
} }
delete targetSource.system.image; delete targetSource.system.image;
let target = JSON.stringify(targetSource, null, 2); let target = JSON.stringify(targetSource, null, 2);
let newFileName = "./" + join(DEST, targetSource.name.toLowerCase().replace(/[ /]/g, "-").replace(/\--{2,}/g, "-").replace(/[.,!]/g, "").trim() + ".json"); let newFileName = "./" + join(DEST, id + ".json");
console.log(newFileName); console.log(newFileName);
writeFileSync(newFileName, target, {encoding: "utf8"}); writeFileSync(newFileName, target, {encoding: "utf8"});
}); });
} }
convert("./src/packs/_source/talente", "./src/packs/__source/talente", "Skill");
convert("./src/packs/_source/zauber", "./src/packs/__source/zauber", "Spell"); convert("./src/packs/_source/zauber", "./src/packs/__source/zauber", "Spell");
convert("./src/packs/_source/vorteile", "./src/packs/__source/vorteile", "Advantage"); convert("./src/packs/_source/vorteile", "./src/packs/__source/vorteile", "Advantage");
convert("./src/packs/_source/waffen", "./src/packs/__source/waffen", "Equipment"); convert("./src/packs/_source/waffen", "./src/packs/__source/waffen", "Equipment");
convert("./src/packs/_source/munition", "./src/packs/__source/munition", "Equipment"); convert("./src/packs/_source/munition", "./src/packs/__source/munition", "Equipment");
convert("./src/packs/_source/ruestzeug", "./src/packs/__source/ruestzeug", "Equipment"); convert("./src/packs/_source/ruestzeug", "./src/packs/__source/ruestzeug", "Equipment");
convert("./src/packs/_source/liturgien-und-segnungen", "./src/packs/__source/liturgien", "Liturgy");
} catch (err) { } catch (err) {
console.error(err); console.error(err);