diff --git a/src/module/data/character.mjs b/src/module/data/character.mjs index 6351e88b..bd77fa8e 100644 --- a/src/module/data/character.mjs +++ b/src/module/data/character.mjs @@ -43,7 +43,8 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { so: new NumberField({ required: true, integer: true }), gilde: new StringField(), }), - talente: new ArrayField ( new ForeignDocumentField(Item) ), + talente: new ArrayField ( new SchemaField( + {taw: new NumberField(), talent: new ForeignDocumentField(Item) })), zauber: new ArrayField ( new ForeignDocumentField(Item) ), } } @@ -52,4 +53,49 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel { super._initialize(options); } + _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 + game.actors.getName(data.name).update({system: {talente}}) + + const startEigenschaften = { + "mu": 10, + "kl": 10, + "in": 10, + "ch": 10, + "ff": 10, + "ge": 10, + "ko": 10, + "kk": 10, + } + + 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/documents/character.mjs b/src/module/documents/character.mjs index ebc67b42..a17df7be 100644 --- a/src/module/documents/character.mjs +++ b/src/module/documents/character.mjs @@ -7,4 +7,21 @@ export class Character extends Actor { this.prepareEmbeddedDocuments(); } + getRollData() { + const data = super.getRollData(); + + if (this.type !== 'character') return; + + // Copy the ability scores to the top level, so that rolls can use + // formulas like `@str.mod + 4`. + if (data.attribute) { + for (let [k, v] of Object.entries(data.attribute)) { + data[k] = foundry.utils.deepClone(v); + } + } + console.log(data); + return data; + } + + } \ No newline at end of file diff --git a/src/module/documents/skill.mjs b/src/module/documents/skill.mjs index ead10ed7..99b1992b 100644 --- a/src/module/documents/skill.mjs +++ b/src/module/documents/skill.mjs @@ -1,6 +1,5 @@ -import { BaseItem } from "./base-item.mjs"; -export class Skill extends BaseItem { +export class Skill extends Item { /** * Augment the basic Item data model with additional dynamic data. */ diff --git a/src/module/documents/spell.mjs b/src/module/documents/spell.mjs index f382a84c..05d34b42 100644 --- a/src/module/documents/spell.mjs +++ b/src/module/documents/spell.mjs @@ -1,6 +1,4 @@ -import { BaseItem } from "./base-item.mjs"; - -export class Spell extends BaseItem { +export class Spell extends Item { /** * Augment the basic Item data model with additional dynamic data. */ diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs index e1be95eb..44b29f88 100644 --- a/src/module/sheets/characterSheet.mjs +++ b/src/module/sheets/characterSheet.mjs @@ -34,14 +34,63 @@ 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; + context.attributes = [ + { + eigenschaft: "mu", + name: "Mut", + wert: actorData.system.attribute.mu ?? 0, + }, + { + eigenschaft: "kl", + name: "Klugheit", + wert: actorData.system.attribute.kl ?? 0, + }, + { + eigenschaft: "in", + name: "Intuition", + wert: actorData.system.attribute.in ?? 0, + }, + { + eigenschaft: "ch", + name: "Charisma", + wert: actorData.system.attribute.ch ?? 0, + }, + { + eigenschaft: "ff", + name: "Fingerfertigkeit", + wert: actorData.system.attribute.ff ?? 0, + }, + { + eigenschaft: "ge", + name: "Geschicklichkeit", + wert: actorData.system.attribute.ge ?? 0, + }, + { + eigenschaft: "ko", + name: "Konstitution", + wert: actorData.system.attribute.ko ?? 0, + }, + { + eigenschaft: "kk", + name: "Körperkraft", + wert: actorData.system.attribute.kk ?? 0, + }, + + ]; context.skills = []; if ( context.system.talente?.length >= 0) { context.system.talente.forEach(talent => { - const tempTalent = talent(); - console.log(tempTalent.system.probe); + console.log(talent); + const taw = talent.taw; + const talentObjekt = game.items.get(talent.talent); + const eigenschaften = Object.values(talentObjekt.system.probe); context.skills.push({ - talentName: tempTalent.name, - probe: `ROLLDATA(${Object.values(tempTalent.system.probe).join("/")})` + talentName: talentObjekt.name, + taw: taw, + rollEigenschaft1: this.prepareEigenschaftRoll(actorData, eigenschaften[0]), + rollEigenschaft2: this.prepareEigenschaftRoll(actorData, eigenschaften[1]), + rollEigenschaft3: this.prepareEigenschaftRoll(actorData, eigenschaften[2]), + probe: `(${eigenschaften.join("/")})` }); }) @@ -51,9 +100,97 @@ export class CharacterSheet extends ActorSheet { return context; } + prepareEigenschaftRoll(actorData, name) { + return actorData.system.attribute[name.toLowerCase()] + } + + async _onTalentRoll(event) { + event.preventDefault(); + const dataset = event.currentTarget.dataset; + console.log(dataset) + if (dataset.rolleigenschaft1) { + let roll1 = new Roll("3d20", this.actor.getRollData()); + + let evaluated1 = (await roll1.evaluate()) + + const dsaDieRollEvaluated = this._evaluateRoll(evaluated1.terms[0].results, { + taw: dataset.taw, + werte: [dataset.rolleigenschaft1, dataset.rolleigenschaft2, dataset.rolleigenschaft3], + }) + + 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, + } + } + + _onAttributeRoll(event) { + event.preventDefault(); + const dataset = event.currentTarget.dataset; + if (dataset.roll) { + let label = dataset.label ? `[Attribut] ${dataset.label}` : ''; + let roll = new Roll(dataset.roll, this.actor.getRollData()); + roll.toMessage({ + speaker: ChatMessage.getSpeaker({ actor: this.actor }), + flavor: label, + rollMode: game.settings.get('core', 'rollMode'), + }); + return roll; + } + } + activateListeners(html) { super.activateListeners(html); + html.on('click', '.attribut.rollable', (evt) => { + console.log(evt); + this._onAttributeRoll(evt); + }); + + html.on('click', '.talent.rollable', (evt) => { + console.log(evt); + this._onTalentRoll(evt); + }); + // Everything below here is only needed if the sheet is editable if (!this.isEditable) return; diff --git a/src/packs/_source/talente-brw/körperlich/sich-verstecken.json b/src/packs/_source/talente-brw/körperlich/sich-verstecken.json index adc9d8de..8fce89fa 100644 --- a/src/packs/_source/talente-brw/körperlich/sich-verstecken.json +++ b/src/packs/_source/talente-brw/körperlich/sich-verstecken.json @@ -2,7 +2,7 @@ "_id": "o1nYjhmMP0Zzlcw6", "_key": "!items!o1nYjhmMP0Zzlcw6", "type": "Skill", - "name": "Sich verstecken", + "name": "Sich Verstecken", "system": { "gruppe": "Körperlich", "probe": [ diff --git a/src/templates/actor/actor-character-sheet.hbs b/src/templates/actor/actor-character-sheet.hbs index f2e44565..5a38a416 100644 --- a/src/templates/actor/actor-character-sheet.hbs +++ b/src/templates/actor/actor-character-sheet.hbs @@ -6,6 +6,18 @@

+
+ {{#each attributes}} + + {{/each}} +
@@ -34,9 +46,10 @@