diff --git a/src/main.mjs b/src/main.mjs index ed282e4f..1992fa77 100644 --- a/src/main.mjs +++ b/src/main.mjs @@ -7,7 +7,6 @@ import { VornachteileDataModel } from "./module/data/vornachteile.mjs"; import { Character } from "./module/documents/character.mjs"; import { CharacterSheet } from "./module/sheets/characterSheet.mjs"; import { VornachteilSheet } from "./module/sheets/vornachteilSheet.mjs"; -import {DragDropDSA41} from "./module/extensions/DragDropDSA41.mjs"; async function preloadHandlebarsTemplates() { return loadTemplates([ @@ -15,12 +14,17 @@ async function preloadHandlebarsTemplates() { 'systems/DSA_4-1/templates/ui/partial-rollable-button.hbs', 'systems/DSA_4-1/templates/ui/partial-attribute-button.hbs', 'systems/DSA_4-1/templates/ui/partial-talent-editable.hbs', - 'systems/DSA_4-1/templates/ui/partial-die.hbs' + 'systems/DSA_4-1/templates/ui/partial-die.hbs', + 'systems/DSA_4-1/templates/ui/partial-advantage-button.hbs' ]); } Hooks.once("init", () => { + game.DSA41 = { + rollItemMacro + } + // Configure custom Document implementations. CONFIG.Actor.documentClass = Character; @@ -35,7 +39,10 @@ Hooks.once("init", () => { Advantage: VornachteileDataModel } - CONFIG.ux.DragDrop = DragDropDSA41; + CONFIG.Combat.initiative = { + formula: `1d6 + @attribute.ini`, + decimals: 0 + } console.log("DSA 4.1 is ready for development!") @@ -66,5 +73,44 @@ Hooks.once("init", () => { }) Hooks.on('dropActorSheetData', (actor, sheet, data) => { - CharacterSheet.onDroppedData(actor, sheet, data); -} ) \ No newline at end of file + return CharacterSheet.onDroppedData(actor, sheet, data); +} ) + +Hooks.once("ready", async function() { + // Wait to register hotbar drop hook on ready so that modules could register earlier if they want to + Hooks.on("hotbarDrop", (bar, data, slot) => createBoilerplateMacro(data, slot)); +}); + +async function createBoilerplateMacro(data, slot) { + console.log(data, slot) + if (data.type !== "Item") return; + if (!("data" in data)) return ui.notifications.warn("You can only create macro buttons for owned Items"); + const item = data.data; + + // Create the macro command + const command = `game.DSA41.rollItemMacro("${item.name}");`; + let macro = game.macros.entities.find(m => (m.name === item.name) && (m.command === command)); + if (!macro) { + macro = await Macro.create({ + name: item.name, + type: "script", + img: item.img, + command: command, + flags: { "dsa41.itemMacro": true } + }); + } + game.user.assignHotbarMacro(macro, slot); + return false; +} + +function rollItemMacro(itemName) { + const speaker = ChatMessage.getSpeaker(); + let actor; + if (speaker.token) actor = game.actors.tokens[speaker.token]; + if (!actor) actor = game.actors.get(speaker.actor); + const item = actor ? actor.items.find(i => i.name === itemName) : null; + if (!item) return ui.notifications.warn(`Your controlled Actor does not have an item named ${itemName}`); + + // Trigger the item roll + return item.roll(); +} diff --git a/src/module/data/character.mjs b/src/module/data/character.mjs index 8f977b3d..7c86ddc0 100644 --- a/src/module/data/character.mjs +++ b/src/module/data/character.mjs @@ -1,5 +1,8 @@ +import {Skill} from "../documents/skill.mjs"; +import {SkillDataModel} from "./skill.mjs"; + const { - SchemaField, NumberField, StringField, ArrayField, ForeignDocumentField + SchemaField, NumberField, StringField, EmbeddedDocumentField, DocumentIdField, ArrayField, ForeignDocumentField } = foundry.data.fields; export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { @@ -103,7 +106,7 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { gilde: new StringField(), }), vornachteile: new ArrayField(new SchemaField({ - vornachteil: new ForeignDocumentField(Item), + vornachteil: new DocumentIdField(Item), wert: new NumberField({ required: false, integer: true }), })), sonderfertigkeiten: new ArrayField(new SchemaField({ @@ -111,13 +114,9 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { auswahlen: new ArrayField(new StringField()), })), - talente: new ArrayField(new SchemaField({ - talent: new ForeignDocumentField(Item), - taw: new NumberField({integer: true, required: true}), - }) - ), + talente: new ArrayField(new DocumentIdField(Item)), zauber: new ArrayField(new SchemaField({ - talent: new ForeignDocumentField(Item), + talent: new DocumentIdField(), zfw: new NumberField({integer: true, required: true}), })), liturgien: new ArrayField(new SchemaField({ @@ -140,80 +139,8 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { } async _onCreate(data, options, userId) { - // prepare base talents - const talentsByName = [ - "Athletik", "Klettern", "Körperbeherrschung", "Schleichen", "Schwimmen", "Selbstbeherrschung", "Sich Verstecken", "Singen", "Sinnenschärfe", "Tanzen", "Zechen", - "Menschenkenntnis", "Überreden", - "Fährtensuchen", "Orientierung", "Wildnisleben", - "Götter/Kulte", "Rechnen", "Sagen/Legenden", - "Heilkunde: Wunden", "Holzbearbeitung", "Kochen", "Lederverarbeitung", "Malen/Zeichnen", "Schneidern" - ] - - const talente = [] - - talentsByName.forEach( talentName => { - const talent = game.items.getName(talentName); - console.log(talent); - if (talent) { - talente.push({ - taw: 0, - talent - }) - } else { - console.error(`${talentName} not found in items`) - } - }) - - // push base talents - await game.actors.getName(data.name).update({system: {talente}}) - - const startEigenschaften = { - "mu": { - start: 10, - aktuell: 10, - mod: 0 - }, - "kl": { - start: 10, - aktuell: 10, - mod: 0 - }, - "in": { - start: 10, - aktuell: 10, - mod: 0 - }, - "ch": { - start: 10, - aktuell: 10, - mod: 0 - }, - "ff": { - start: 10, - aktuell: 10, - mod: 0 - }, - "ge": { - start: 10, - aktuell: 10, - mod: 0 - }, - "ko": { - start: 10, - aktuell: 10, - mod: 0 - }, - "kk": { - start: 10, - aktuell: 10, - mod: 0 - } - } - - await game.actors.getName(data.name).update({system: {attribute: startEigenschaften}}) - super._onCreate(data, options, userId); } -} \ No newline at end of file +} diff --git a/src/module/data/skill.mjs b/src/module/data/skill.mjs index 5056e80a..5032a4c1 100644 --- a/src/module/data/skill.mjs +++ b/src/module/data/skill.mjs @@ -8,6 +8,7 @@ export class SkillDataModel extends BaseItem { return { name: new StringField({ required: true }), gruppe: new StringField({ required: true }), + taw: new NumberField({ integer: true, initial: 0 }), probe: new ArrayField(new StringField(), { exact: 3 }), // References one of the eight attributes by name voraussetzung: new SchemaField({ talent: new StringField({ model: SkillDataModel }), @@ -15,7 +16,7 @@ export class SkillDataModel extends BaseItem { }), // Required skills at a given level talent: new HTMLField({ required: true }), behinderung: new NumberField({ required: false}), // BE-X - komplexität: new NumberField({ required: false }), // In case of languages + komplexität: new NumberField({ required: false }), // In case of languages } } /** @@ -34,6 +35,56 @@ export class SkillDataModel extends BaseItem { * @param {Event} event The originating click event * @private */ - async roll() { } + async roll() { + console.log(this.parent) + let roll1 = new Roll("3d20", this.actor.getRollData()); -} \ No newline at end of file + let evaluated1 = (await roll1.evaluate()) + + const dsaDieRollEvaluated = this._evaluateRoll(evaluated1.terms[0].results, { + taw: dataset.taw, + werte: [this.system.probe[0], this.system.probe[1], this.system.probe[2]], + }) + + if (dsaDieRollEvaluated.tap >= 0) { // erfolg + evaluated1.toMessage({ + speaker: ChatMessage.getSpeaker({actor: this.actor}), + flavor: ` ${dsaDieRollEvaluated.meisterlich?'Meisterlich geschafft':'Geschafft'} mit ${dsaDieRollEvaluated.tap} Punkten übrig`, + rollMode: game.settings.get('core', 'rollMode'), + }) + } else { // misserfolg + evaluated1.toMessage({ + speaker: ChatMessage.getSpeaker({actor: this.actor}), + flavor: ` ${dsaDieRollEvaluated.meisterlich?'Gepatzt':''} mit ${Math.abs(dsaDieRollEvaluated.tap)} Punkten daneben`, + rollMode: game.settings.get('core', 'rollMode'), + }) + } + } + + _evaluateRoll(rolledDice, { taw, lowerThreshold = 1, upperThreshold = 20, countToMeisterlich = 3, countToPatzer = 3, werte = [] } ) { + let tap = taw; + let meisterlichCounter = 0; + let patzerCounter = 0; + let failCounter = 0; + + rolledDice.forEach( (rolledDie, index) => { + if (tap < 0 && rolledDie.result > werte[index]) { + tap -= rolledDie.result - werte[index]; + if (tap <0) { // konnte nicht vollständig ausgeglichen werden + failCounter++; + } + } else if (rolledDie.result > werte[index]) { // taw ist bereits aufgebraucht und wert kann nicht ausgeglichen werden + tap -= rolledDie.result - werte[index]; + failCounter++; + } + if (rolledDie.result <= lowerThreshold) meisterlichCounter++; + if (rolledDie.result > upperThreshold) patzerCounter++; + }) + + return { + tap, + meisterlich: meisterlichCounter === countToMeisterlich, + patzer: patzerCounter === countToPatzer, + } + } +} diff --git a/src/module/documents/character.mjs b/src/module/documents/character.mjs index b7c4c35a..e692fb6a 100644 --- a/src/module/documents/character.mjs +++ b/src/module/documents/character.mjs @@ -34,11 +34,4 @@ export class Character extends Actor { console.log(data); return data; } - - - static onDroppedData(character, characterSheet, uuid) { - - } - - -} \ No newline at end of file +} diff --git a/src/module/extensions/DragDropApplicationMixin.mjs b/src/module/extensions/DragDropApplicationMixin.mjs deleted file mode 100644 index ecc9284a..00000000 --- a/src/module/extensions/DragDropApplicationMixin.mjs +++ /dev/null @@ -1,62 +0,0 @@ -import {DragDropDSA41} from "./DragDropDSA41.mjs"; - -export default function DragDropApplicationMixin(Base) { - return class DragDropApplication extends Base { - /** @override */ - _onDragOver(event) { - const data = DragDropDSA41.getPayload(event); - DragDropDSA41.dropEffect = event.dataTransfer.dropEffect = (foundry.utils.getType(data) === "Object") - ? this._dropBehavior(event, data) : "copy"; - } - - /* -------------------------------------------- */ - - /** - * The behavior for the dropped data. When called during the drop event, ensure this is called before awaiting - * anything or the drop behavior will be lost. - * @param {DragEvent} event The drag event. - * @param {object} [data] The drag payload. - * @returns {DropEffectValue} - */ - _dropBehavior(event, data) { - data ??= DragDropDSA41.getPayload(event); - const allowed = this._allowedDropBehaviors(event, data); - let behavior = DragDropDSA41.dropEffect ?? event.dataTransfer?.dropEffect; - - if ( event.type === "dragover" ) { - if ( areKeysPressed(event, "dragMove") ) behavior = "move"; - else if ( areKeysPressed(event, "dragCopy") ) behavior = "copy"; - else behavior = this._defaultDropBehavior(event, data); - } - - if ( (behavior !== "none") && !allowed.has(behavior) ) return allowed.first() ?? "none"; - return behavior || "copy"; - } - - /* -------------------------------------------- */ - - /** - * Types of allowed drop behaviors based on the origin & target of a drag event. - * @param {DragEvent} event The drag event. - * @param {object} [data] The drag payload. - * @returns {Set} - * @protected - */ - _allowedDropBehaviors(event, data) { - return new Set(); - } - - /* -------------------------------------------- */ - - /** - * Determine the default drop behavior for the provided operation. - * @param {DragEvent} event The drag event. - * @param {object} [data] The drag payload. - * @returns {DropEffectValue} - * @protected - */ - _defaultDropBehavior(event, data) { - return "copy"; - } - }; -} diff --git a/src/module/extensions/DragDropDSA41.mjs b/src/module/extensions/DragDropDSA41.mjs deleted file mode 100644 index 6344455e..00000000 --- a/src/module/extensions/DragDropDSA41.mjs +++ /dev/null @@ -1,54 +0,0 @@ -export class DragDropDSA41 extends foundry.applications.ux.DragDrop { - - /** - * Drop effect used for current drag operation. - * @type {DropEffectValue|null} - */ - static dropEffect = null; - - /* -------------------------------------------- */ - - /** - * Stored drag event payload. - * @type {{ data: any, event: DragEvent }|null} - */ - static #payload = null; - - /* -------------------------------------------- */ - - /** @override */ - async _handleDragStart(event) { - await this.callback(event, "dragstart"); - if ( event.dataTransfer.items.length ) { - console.log(event) - event.stopPropagation(); - let data = event.dataTransfer.getData("application/json") || event.dataTransfer.getData("text/plain"); - try { data = JSON.parse(data); } catch(err) {} - DragDropDSA41.#payload = data ? { event, data } : null; - } else { - DragDropDSA41.#payload = null; - } - } - - /* -------------------------------------------- */ - - /** @override */ - async _handleDragEnd(event) { - await this.callback(event, "dragend"); - DragDropDSA41.dropEffect = null; - DragDropDSA41.#payload = null; - } - - /* -------------------------------------------- */ - - /** - * Get the data payload for the current drag event. - * @param {DragEvent} event - * @returns {any} - */ - static getPayload(event) { - if ( !DragDropDSA41.#payload?.data ) return null; - return DragDropDSA41.#payload.data; - } - -} \ No newline at end of file diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs index f8eae1d8..66b453fd 100644 --- a/src/module/sheets/characterSheet.mjs +++ b/src/module/sheets/characterSheet.mjs @@ -1,5 +1,3 @@ -import {DragDropDSA41} from "../extensions/DragDropDSA41.mjs"; - export class CharacterSheet extends ActorSheet { /**@override */ static get defaultOptions() { @@ -24,10 +22,6 @@ export class CharacterSheet extends ActorSheet { /** @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. @@ -36,6 +30,74 @@ export class CharacterSheet extends ActorSheet { // 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) + + return context; + } + + #addSkillsToContext(context) { + const actorData = context.data; + context.skills = {}; + context.flatSkills = []; + + Object.values(actorData.items).forEach( (item, index) => { + if (item.type === "Skill") { + + const talentGruppe = item.system.gruppe; + const eigenschaften = Object.values(item.system.probe); + const werte = [ + {name: eigenschaften[0], value: this.prepareEigenschaftRoll(actorData, eigenschaften[0])}, + {name: eigenschaften[1], value: this.prepareEigenschaftRoll(actorData, eigenschaften[1])}, + {name: eigenschaften[2], value: this.prepareEigenschaftRoll(actorData, eigenschaften[2])} + ] + if (context.skills[talentGruppe] == null) { + context.skills[talentGruppe] = []; + } + const obj = { + type: "talent", + gruppe: talentGruppe, + name: item.name, + taw: "" + item.system.taw, + tawPath: `system.items.${index}.taw`, + werte, + rollEigenschaft1: werte[0].value, + rollEigenschaft2: werte[1].value, + rollEigenschaft3: werte[2].value, + eigenschaft1: werte[0].name, + eigenschaft2: werte[1].name, + eigenschaft3: werte[2].name, + probe: `(${eigenschaften.join("/")})`, + id: item._id, + }; + context.skills[talentGruppe].push(obj); + context.flatSkills.push(obj); + } + } + ); + } + + #addAdvantagesToContext(context) { + context.advantages = []; + const actorData = context.data; + Object.values(actorData.items).forEach( (item) => { + if (item.type === "Advantage") { + context.advantages.push({ + id: item._id, + name: item.name, + value: item.system.value, + options: item.system.auswahl, + description: item.system.description, + }); + } + } + ); + } + + #addAttributesToContext(context) { + const actorData = context.data; context.attributes = [ { eigenschaft: "mu", @@ -57,7 +119,7 @@ export class CharacterSheet extends ActorSheet { }, { eigenschaft: "ch", - name: "IN", + name: "CH", tooltip: "Charisma", wert: actorData.system.attribute.ch.aktuell ?? 0, }, @@ -81,52 +143,13 @@ export class CharacterSheet extends ActorSheet { }, { eigenschaft: "kk", - name: "KO", + name: "KK", tooltip: "Körperkraft", wert: actorData.system.attribute.kk.aktuell ?? 0, }, ]; - context.skills = {}; - context.flatSkills = []; - if ( context.system.talente?.length >= 0) { - context.system.talente.forEach( (talent, index) => { - if (talent.talent) { - const taw = talent.taw; - const talentObjekt = game.items.get(talent.talent); - console.log(talent); - const talentGruppe = talentObjekt.system.gruppe; - const eigenschaften = Object.values(talentObjekt.system.probe); - const werte = [ - {name: eigenschaften[0], value: this.prepareEigenschaftRoll(actorData, eigenschaften[0])}, - {name: eigenschaften[1], value: this.prepareEigenschaftRoll(actorData, eigenschaften[1])}, - {name: eigenschaften[2], value: this.prepareEigenschaftRoll(actorData, eigenschaften[2])} - ] - - if (context.skills[talentGruppe] == null) { - context.skills[talentGruppe] = []; - } - - const obj = { - type: "talent", - gruppe: talentGruppe, - name: talentObjekt.name, - taw: "" + taw, - tawPath: `system.talente.${index}.taw`, - werte, - rollEigenschaft1: werte[0].value, - rollEigenschaft2: werte[1].value, - rollEigenschaft3: werte[2].value, - probe: `(${eigenschaften.join("/")})` - }; - - context.skills[talentGruppe].push(obj); - context.flatSkills.push(obj); - } - }) - } - return context; } prepareEigenschaftRoll(actorData, name) { @@ -222,6 +245,42 @@ export class CharacterSheet extends ActorSheet { } } + openEmbeddedDocument(documentId) { + this.object.items.get(documentId).sheet.render(true) + } + + showAdjustAttributeDialog(attributeName, attributeField, previousValue) { + const thisActor = this; + const myContent = ` + Value: + + `; + + function updateAttribute(html) { + const value = html.find("input#attributeValue").val(); + const attribute = {} + attribute[attributeField.toLowerCase()] = { + aktuell: value + } + thisActor.object.update({ system: { attribute }}) + } + + new Dialog({ + title: `${attributeName} ändern auf`, + content: myContent, + buttons: { + button1: { + label: "Ändern", + callback: (html) => { + updateAttribute(html) + }, + icon: `` + } + } + }).render(true); + + } + activateListeners(html) { super.activateListeners(html); @@ -237,78 +296,94 @@ export class CharacterSheet extends ActorSheet { this._onRoll(evt); }); - // Everything below here is only needed if the sheet is editable - if (!this.isEditable) return; + html.on('click', '.talent .name', (evt) => { + this.openEmbeddedDocument(evt.target.dataset.id); + evt.stopPropagation(); + }) + html.on('click', '.advantage .name', (evt) => { + this.openEmbeddedDocument(evt.target.dataset.id); + evt.stopPropagation(); + }) + + new ContextMenu(html, '.talent.rollable', [ + { + name: "Entfernen", + icon: '', + callback: (event) => { + this.object.deleteEmbeddedDocuments('Item', [event[0].dataset.id]) + }, + condition: () => true + } + ]); + + + new ContextMenu(html, '.attribute.rollable', [ + { + name: "Anpassen", + icon: '', + callback: (event) => { + this.showAdjustAttributeDialog(event[0].dataset.name, event[0].dataset.label, event[0].dataset.value) + }, + condition: () => true + } + ]); + + let handler = ev => this._onDragStart(ev); + // Find all items on the character sheet. + html.find('.talent.rollable').each((i, li) => { + // Add draggable attribute and dragstart listener. + li.setAttribute("draggable", true); + li.addEventListener("dragstart", handler, false); + }); + + } + + #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; + } + } + } + + static getElementByName(collection, id) { + const array = Array.from(collection); + for (const element of array) { + if (element._id === id) { + return element; + } + } } static onDroppedData(actor, characterSheet, data) { - const item = game.items.get(foundry.utils.parseUuid(data.uuid).id) - console.log(); - let alreadyInSet = false; - let previousTaw = 0; - actor.system.talente.forEach(({taw, talent}) => { - if (talent._id === item._id) { - alreadyInSet = talent; - previousTaw = taw; - } - }) - - - - const myContent = ` - TaW: - -`; - new Dialog({ - title: `Talent ${item.name} ${alreadyInSet?'ersetzen':'hinzufügen'}`, - content: myContent, - buttons: { - button1: { - label: "hinzufügen", - callback: (html) => myCallback(html), - icon: `` - } - } - }).render(true); - - async function myCallback(html) { - const taw = html.find("input#taw").val(); - - let index = actor.system.talente.findIndex( predicate => predicate.talent._id === alreadyInSet._id ) - let sorted = []; - if (alreadyInSet) { - actor.system.talente[index].taw = taw; - sorted = actor.system.talente; - - } else { - sorted = [{ - taw: taw, - talent: {_id: item._id, name: item.name} - }, ...actor.system.talente].sort((a, b) => a.talent.name.localeCompare(b.talent.name)); - } - - const serialised = sorted.map(({taw, talent}) => { - return { - taw: taw, - talent: talent._id - } - }); - - await actor.update({ - system: { - talente: [ - - ...serialised - ] - } - }); - await characterSheet.render(true); - ui.notifications.info(`Talent ${item.name} auf TaW ${taw} hinzugefügt`); - + const uuid = foundry.utils.parseUuid(data.uuid); + 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); + default: + return false; } - actor.items.clear() } -} \ No newline at end of file +} diff --git a/src/module/sheets/skillSheet.mjs b/src/module/sheets/skillSheet.mjs index 9f73ce7d..abffa724 100644 --- a/src/module/sheets/skillSheet.mjs +++ b/src/module/sheets/skillSheet.mjs @@ -1,7 +1,4 @@ -import {DragDropDSA41} from "../extensions/DragDropDSA41.mjs"; -import DragDropApplicationMixin from "../extensions/DragDropApplicationMixin.mjs"; - -export class SkillSheet extends DragDropApplicationMixin(foundry.appv1.sheets.ItemSheet) { +export class SkillSheet extends ItemSheet { /**@override */ static get defaultOptions() { return foundry.utils.mergeObject(super.defaultOptions, { @@ -58,59 +55,4 @@ export class SkillSheet extends DragDropApplicationMixin(foundry.appv1.sheets.It if (!this.isEditable) return; } - - /* -------------------------------------------- */ - /* Drag & Drop */ - /* -------------------------------------------- */ - - /** @override */ - _allowedDropBehaviors(event, data) { - console.log(data, event); - if ( !data?.uuid ) return new Set(["copy", "link"]); - const allowed = new Set(["copy", "move", "link"]); - const s = foundry.utils.parseUuid(data.uuid); - const t = foundry.utils.parseUuid(this.document.uuid); - const sCompendium = s.collection instanceof foundry.documents.collections.CompendiumCollection; - const tCompendium = t.collection instanceof foundry.documents.collections.CompendiumCollection; - - // If either source or target are within a compendium, but not inside the same compendium, move not allowed - if ( (sCompendium || tCompendium) && (s.collection !== t.collection) ) allowed.delete("move"); - - return allowed; - } - - /* -------------------------------------------- */ - - /** @override */ - _defaultDropBehavior(event, data) { - if ( !data?.uuid ) return "copy"; - const d = foundry.utils.parseUuid(data.uuid); - const t = foundry.utils.parseUuid(this.document.uuid); - const base = d.embedded?.length ? "document" : "primary"; - console.log(d, t, base); - return (d.collection === t.collection) && (d[`${base}Id`] === t[`${base}Id`]) - && (d[`${base}Type`] === t[`${base}Type`]) ? "move" : "copy"; - } - - /* -------------------------------------------- */ - - /** @inheritDoc */ - async _onDragStart(event) { - await super._onDragStart(event); - if ( !this.document.isOwner || this.document.collection?.locked ) { - event.dataTransfer.effectAllowed = "copyLink"; - } - } - - _onDragOver(event) { - super._onDragOver(event); - console.log(event); - } - - _dropBehavior(event, data) { - console.log(event, data); - return super._dropBehavior(event, data); - - } - } \ No newline at end of file diff --git a/src/module/sheets/vornachteilSheet.mjs b/src/module/sheets/vornachteilSheet.mjs index 746b1b47..842bd24f 100644 --- a/src/module/sheets/vornachteilSheet.mjs +++ b/src/module/sheets/vornachteilSheet.mjs @@ -1,7 +1,4 @@ -import {DragDropDSA41} from "../extensions/DragDropDSA41.mjs"; -import DragDropApplicationMixin from "../extensions/DragDropApplicationMixin.mjs"; - -export class VornachteilSheet extends DragDropApplicationMixin(foundry.appv1.sheets.ItemSheet) { +export class VornachteilSheet extends ItemSheet { /**@override */ static get defaultOptions() { return foundry.utils.mergeObject(super.defaultOptions, { diff --git a/src/module/xml-import/xml-import.mjs b/src/module/xml-import/xml-import.mjs index e7681a07..5d9af9b6 100644 --- a/src/module/xml-import/xml-import.mjs +++ b/src/module/xml-import/xml-import.mjs @@ -27,7 +27,7 @@ export async function importCharacter(actorId, file) { let dom = domParser.parseFromString(xmlString, 'application/xml') let rawJson = getJsonFromXML(dom) - let characterJson = mapRawJson(rawJson) + let characterJson = mapRawJson(actor, rawJson) actor.update(characterJson) } @@ -70,6 +70,38 @@ function getJsonFromXML(dom) { return jsonResult; } +async function addSkillFromCompendiumByNameToActor(talentName, taw, actor) { + const compendiumOfSkills = game.packs.get('DSA_4-1.talente-brw'); + const talentId = compendiumOfSkills.index.find( skill => skill.name === talentName) + if (talentId) { + + const talent = await compendiumOfSkills.getDocument(talentId._id); + + try { + const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [talent]))[0] + embeddedDocument.update({system: {taw: taw}}); + } catch (error) { + console.error(`${talentName} not found in items`, error) + } + } +} + +async function addAdvantageFromCompendiumByNameToActor(advantageName, advantageValue, actor) { + const compendiumOfAdvantages = game.packs.get('DSA_4-1.Advantage'); + const advantageId = compendiumOfAdvantages.index.find( skill => skill.name === advantageName) + if (advantageId) { + + const advantage = await compendiumOfAdvantages.getDocument(advantageId._id); + + try { + const embeddedDocument = (await actor.createEmbeddedDocuments('Item', [advantage]))[0] + embeddedDocument.update({system: {value: advantageValue}}); + } catch (error) { + console.error(`${advantageName} not found in items`, error) + } + } +} + /** * gets the text content of a file * @param file the file with the desired content @@ -101,12 +133,26 @@ function calculateBirthdate(json) { return `${day}. ${month} ${year} BF` } +function mapSkills(actor, held) { + for (let talent in held.talentliste.talent) { + talent = held.talentliste.talent[talent] + addSkillFromCompendiumByNameToActor(talent.name, talent.value, actor) + } +} + +function mapAdvantages(actor, held) { + for (let advantage in held.vt.vorteil) { + advantage = held.vt.vorteil[advantage] + addAdvantageFromCompendiumByNameToActor(advantage.name, advantage.value, actor) + } +} + /** * parses a json into a fitting character-json * @param rawJson the json parsed from the Helden-Software XML * @returns {{}} a json representation of the character */ -function mapRawJson(rawJson) { +function mapRawJson(actor, rawJson) { let json = {} let held = rawJson.helden.held; json.name = held.name @@ -201,18 +247,7 @@ function mapRawJson(rawJson) { aktuell: attribute.value } json.attribute.so = getAttributeJson(attributes, "Sozialstatus") - let benefits = [] - for (let benefit in held.vt.vorteil) { - benefit = held.vt.vorteil[benefit] - let benefitJson = { - name: benefit.name, - } - if (benefit.value !== undefined) { - benefitJson.wert = benefit.value - } - benefits.push(benefitJson) - } - json.vornachteile = benefits + mapAdvantages(actor, held) let specialAbilities = [] let liturgies = [] for (let specialAbility in held.sf.sonderfertigkeit) { @@ -248,19 +283,8 @@ function mapRawJson(rawJson) { } json.sonderfertigkeiten = specialAbilities json.liturgien = liturgies - let talents = [] - for (let talent in held.talentliste.talent) { - talent = held.talentliste.talent[talent] - let talentItem = game.items.getName(talent.name) - if (talentItem) { - let talentJson = { - talent: talentItem, - taw: talent.value, - } - talents.push(talentJson) - } - } - json.talente = talents + + mapSkills(actor, held) let spells = [] /*for (let spell in held.zauberliste.zauber) { spell = held.zauberliste.zauber[spell] @@ -337,4 +361,4 @@ Hooks.on("getActorContextOptions", (application, menuItems) => { actor.import() } }) -}) \ No newline at end of file +}) diff --git a/src/style/_rollable.scss b/src/style/_rollable.scss index 40c2d4fb..d0e71cf2 100644 --- a/src/style/_rollable.scss +++ b/src/style/_rollable.scss @@ -24,13 +24,13 @@ $rollable_colours: ( height: 32px; position: relative; margin: 4px; - z-index: 2; .die { width: 32px; height: 32px; display: inline-block; position: relative; + z-index: 1; .border { fill: #0000; @@ -64,7 +64,6 @@ $rollable_colours: ( left: 16px; top: 0; height: 32px; - z-index: -1; padding-left: 24px; span.name { @@ -205,4 +204,4 @@ $rollable_colours: ( @include coloring("Gesellschaft"); @include coloring("Wissen"); @include coloring("Sprachen"); -@include coloring("Handwerk"); \ No newline at end of file +@include coloring("Handwerk"); diff --git a/src/templates/actor/actor-character-sheet.hbs b/src/templates/actor/actor-character-sheet.hbs index 09975c89..a6852343 100644 --- a/src/templates/actor/actor-character-sheet.hbs +++ b/src/templates/actor/actor-character-sheet.hbs @@ -60,7 +60,11 @@
- +
@@ -157,4 +161,4 @@
- \ No newline at end of file + diff --git a/src/templates/item/item-advantage-sheet.hbs b/src/templates/item/item-advantage-sheet.hbs index 7902b570..d50d00ce 100644 --- a/src/templates/item/item-advantage-sheet.hbs +++ b/src/templates/item/item-advantage-sheet.hbs @@ -8,7 +8,7 @@ {{!-- Sheet Body --}}
-
{{json}}
+
{{json}}
- \ No newline at end of file + diff --git a/src/templates/item/item-skill-sheet.hbs b/src/templates/item/item-skill-sheet.hbs index 89449c4f..22cd7fd3 100644 --- a/src/templates/item/item-skill-sheet.hbs +++ b/src/templates/item/item-skill-sheet.hbs @@ -17,6 +17,12 @@ +
+ +