diff --git a/src/ActorSheet.hbs b/src/ActorSheet.hbs index e679e2b..108fd92 100644 --- a/src/ActorSheet.hbs +++ b/src/ActorSheet.hbs @@ -13,7 +13,7 @@ {{/inline}}
-
+
{{>editable-input type="text" name="name" value=actor.name placeholder=(localize "DSA41.name")}} {{>editable-input type="text" name="system.race" value=actor.system.race placeholder=(localize "DSA41.race")}} {{>editable-input type="text" name="system.culture" value=actor.system.culture placeholder=(localize "DSA41.culture")}} @@ -141,7 +141,7 @@
{{#each actor.itemTypes.Bewaffnung}}
-
+
{{this.name}} @@ -168,7 +168,7 @@
{{#each actor.itemTypes.Ruestung}}
-
+
{{this.name}}
@@ -187,7 +187,7 @@
{{#each actor.itemTypes.Gegenstand}}
-
+
{{this.name}}
@@ -210,7 +210,7 @@ {{#each actor.system.computed.kampf.waffen}}
-
+
{{item.name}} @@ -221,6 +221,19 @@
{{>die-value type="trefferpunkte" data-roll=trefferpunkte value=trefferpunkte_display data-tooltip="trefferpunkte_tooltip"}}
{{/each}} + {{#each actor.system.computed.kampf.fernkampf_waffen}} +
+
+ +
+ {{item.name}} +
+
+
{{>die-value type="fernkampf-attacke" data-roll="1d20" value=attacke data-tooltip="fernkampf_attacke_tooltip"}}
+
+
{{>die-value type="fernkampf-trefferpunkte" data-roll=trefferpunkte value=trefferpunkte_display data-tooltip="fernkampf_trefferpunkte_tooltip"}}
+
+ {{/each}}
@@ -249,7 +262,7 @@ {{#each actor.system.computed.kampf.ruestungen}}
-
+
{{item.name}}
diff --git a/src/Dialogs/FernkampfAngriff.hbs b/src/Dialogs/FernkampfAngriff.hbs new file mode 100644 index 0000000..6702876 --- /dev/null +++ b/src/Dialogs/FernkampfAngriff.hbs @@ -0,0 +1,59 @@ +
+ {{localize "DSA41.kampf.zielgroesse.label"}} + + + {{localize "DSA41.kampf.deckung.label"}} + + + {{localize "DSA41.kampf.entfernung.label"}} + + + {{localize "DSA41.kampf.zielbewegung.label"}} + + + {{localize "DSA41.kampf.wind.label"}} + + + {{localize "DSA41.kampf.modifikator"}} + {{>editable-input type="number" name="modifikator" value=(lookup formData "modifikator")}} + +
+ max(-2, + {{formData.ziel_groesse}}{{localize "DSA41.kampf.zielgroesse.label"}} + + {{formData.deckung}}{{localize "DSA41.kampf.deckung.label"}} + + {{formData.ziel_bewegung}}{{localize "DSA41.kampf.zielbewegung.label"}} + ) + + + {{formData.entfernung}}{{localize "DSA41.kampf.entfernung.label"}} + + {{formData.wind}}{{localize "DSA41.kampf.wind.label"}} + + + {{formData.modifikator}}{{localize "DSA41.kampf.modifikator"}} +
+
diff --git a/src/Dialogs/FernkampfTrefferpunkte.hbs b/src/Dialogs/FernkampfTrefferpunkte.hbs new file mode 100644 index 0000000..80837b4 --- /dev/null +++ b/src/Dialogs/FernkampfTrefferpunkte.hbs @@ -0,0 +1,19 @@ +
+ {{localize "DSA41.kampf.entfernung.label"}} + + + {{localize "DSA41.kampf.modifikator"}} + {{>editable-input type="number" name="modifikator" value=(lookup formData "modifikator") }} + +
+ {{options.item.system.fernkampfwaffe.basis}}{{localize "DSA41.bewaffnung.fernkampfwaffe.basis"}} + + {{lookup options.item.system.fernkampfwaffe formData.entfernung}}{{localize "DSA41.kampf.entfernung.label"}} + + {{formData.modifikator}}{{localize "DSA41.kampf.modifikator"}} +
+
diff --git a/src/EditableInput.hbs b/src/EditableInput.hbs index 2c0d6db..4a7f721 100644 --- a/src/EditableInput.hbs +++ b/src/EditableInput.hbs @@ -1,4 +1,4 @@ -
+
{{#if (eq type "checkbox")}} {{else}} diff --git a/src/ItemSheets/Bewaffnung.hbs b/src/ItemSheets/Bewaffnung.hbs index 3f8aa53..b214705 100644 --- a/src/ItemSheets/Bewaffnung.hbs +++ b/src/ItemSheets/Bewaffnung.hbs @@ -3,7 +3,7 @@
{{>editable-input type="text" name="name" value=item.name placeholder=(localize "DSA41.name")}} -
+
{{>editable-input type="number" name="system.gewicht" value=item.system.gewicht placeholder=(localize "DSA41.weight")}} {{>editable-input type="number" name="system.preis" value=item.system.preis placeholder=(localize "DSA41.price")}}
diff --git a/src/ItemSheets/Gegenstand.hbs b/src/ItemSheets/Gegenstand.hbs index 8c53988..7fc6c45 100644 --- a/src/ItemSheets/Gegenstand.hbs +++ b/src/ItemSheets/Gegenstand.hbs @@ -3,7 +3,7 @@
{{>editable-input type="text" name="name" value=item.name placeholder=(localize "DSA41.name")}} -
+
{{>editable-input type="number" name="system.gewicht" value=item.system.gewicht placeholder=(localize "DSA41.weight")}} {{>editable-input type="number" name="system.preis" value=item.system.preis placeholder=(localize "DSA41.price")}}
diff --git a/src/ItemSheets/Ruestung.hbs b/src/ItemSheets/Ruestung.hbs index 83e464d..b9ded9e 100644 --- a/src/ItemSheets/Ruestung.hbs +++ b/src/ItemSheets/Ruestung.hbs @@ -3,7 +3,7 @@
{{>editable-input type="text" name="name" value=item.name placeholder=(localize "DSA41.name")}} -
+
{{>editable-input type="number" name="system.gewicht" value=item.system.gewicht placeholder=(localize "DSA41.weight")}} {{>editable-input type="number" name="system.preis" value=item.system.preis placeholder=(localize "DSA41.price")}}
diff --git a/src/Tooltips/Attacke.hbs b/src/Tooltips/Attacke.hbs index 49f6ca6..2b0947a 100644 --- a/src/Tooltips/Attacke.hbs +++ b/src/Tooltips/Attacke.hbs @@ -1,5 +1,7 @@
- {{talent_attacke}}{{localize "DSA41.talente.label"}} + {{basis_attacke}}{{localize "DSA41.bewaffnung.nahkampfwaffe.basis"}} + + + {{talent_attacke}}{{localize "DSA41.talente.label"}} {{#if (ne modifikator_attacke 0)}} + {{modifikator_attacke}}{{localize "DSA41.bewaffnung.nahkampfwaffe.modifikator"}} diff --git a/src/Tooltips/FernkampfAttacke.hbs b/src/Tooltips/FernkampfAttacke.hbs new file mode 100644 index 0000000..4bbe4f4 --- /dev/null +++ b/src/Tooltips/FernkampfAttacke.hbs @@ -0,0 +1,4 @@ +
+ {{basis_attacke}}{{localize "DSA41.bewaffnung.fernkampfwaffe.basis"}} + + {{talent_attacke}}{{localize "DSA41.talente.label"}} +
diff --git a/src/Tooltips/FernkampfTrefferpunkte.hbs b/src/Tooltips/FernkampfTrefferpunkte.hbs new file mode 100644 index 0000000..344e525 --- /dev/null +++ b/src/Tooltips/FernkampfTrefferpunkte.hbs @@ -0,0 +1,3 @@ +
+ {{item.system.fernkampfwaffe.basis}}{{localize "DSA41.bewaffnung.fernkampfwaffe.basis"}} +
diff --git a/src/Tooltips/Parade.hbs b/src/Tooltips/Parade.hbs index db7e1c8..d4d3d18 100644 --- a/src/Tooltips/Parade.hbs +++ b/src/Tooltips/Parade.hbs @@ -1,5 +1,7 @@
- {{talent_parade}}{{localize "DSA41.talente.label"}} + {{basis_parade}}{{localize "DSA41.bewaffnung.nahkampfwaffe.basis"}} + + + {{talent_parade}}{{localize "DSA41.talente.label"}} {{#if (ne modifikator_parade 0)}} + {{modifikator_parade}}{{localize "DSA41.bewaffnung.nahkampfwaffe.modifikator"}} diff --git a/src/lang/de.json b/src/lang/de.json index b991243..e82bad9 100644 --- a/src/lang/de.json +++ b/src/lang/de.json @@ -27,7 +27,10 @@ "attacke": "Attacke", "parade": "Parade", - "trefferpunkte": "Trefferpunkte" + "trefferpunkte": "Trefferpunkte", + + "fernkampf-attacke": "Attacke", + "fernkampf-trefferpunkte": "Trefferpunkte" }, "character": { @@ -358,7 +361,55 @@ "attacke": "Attacke", "parade": "Parade", "trefferpunkte": "Trefferpunkte", - "ruestungen": "Rüstungen" + "ruestungen": "Rüstungen", + "modifikator": "Modifikator", + + "zielgroesse": { + "label": "Zielgröße", + + "winzig": "Winzig", + "sehr_klein": "Sehr Klein", + "klein": "Klein", + "mittel": "Mittel", + "gross": "Groß", + "sehr_gross": "Sehr Groß" + }, + + "deckung": { + "label": "Deckung", + + "keine": "Keine", + "halb": "Halb", + "drei_viertel": "Drei Viertel" + }, + + "entfernung": { + "label": "Entfernung", + + "sehr_nah": "Sehr Nah", + "nah": "Nah", + "mittel": "Mittel", + "weit": "Weit", + "extrem_weit": "Extrem Weit" + }, + + "zielbewegung": { + "label": "Bewegung des Ziels", + + "unbeweglich": "Unbeweglich", + "stillstehend": "Stillstehend", + "leicht": "Leicht", + "schnell": "Schnell", + "sehr_schnell": "Sehr Schnell" + }, + + "wind": { + "label": "Wind", + + "still": "Still", + "seitenwind": "Böiger Seitenwind", + "starker_seitenwind": "Starker Seitenwind" + } } } } diff --git a/src/main.css b/src/main.css index 40d5c77..a989ade 100644 --- a/src/main.css +++ b/src/main.css @@ -14,7 +14,7 @@ & [data-action] { cursor: pointer; - &:hover { + &:not(button):hover { transform: scale(1.05); } } @@ -58,6 +58,10 @@ flex: 0; } + & .gap { + gap: 0.5rem; + } + & .subgrid { display: grid; grid-template-rows: subgrid; @@ -105,7 +109,6 @@ & .editable-input { flex: 1; - padding: 0px 3px; & input { border: none; @@ -132,6 +135,7 @@ & .item-image { width: 80px; height: 80px; + margin-right: 0.5rem; } & .die { @@ -161,6 +165,9 @@ &.die-attacke { fill: #b22319; } &.die-parade { fill: #388834; } &.die-trefferpunkte { fill: #0c0c0c; } + + &.die-fernkampf-attacke { fill: #388834; } + &.die-fernkampf-trefferpunkte { fill: #0c0c0c; } } & .tabs { @@ -194,10 +201,6 @@ width: 40px; height: 40px; } - - & .item-name { - gap: 0.5rem; - } } & .list-header { @@ -231,6 +234,17 @@ } } + &.Dialog > .window-content { + gap: 1rem; + + & > :first-child { + display: grid; + grid-template-columns: repeat(4, 1fr); + gap: 0.5rem; + align-items: center; + } + } + & [data-application-part="Bewaffnung"] { & .tab { grid-template-columns: minmax(0, max-content) minmax(0, 1fr) minmax(0, max-content) minmax(0, 1fr); @@ -302,4 +316,9 @@ } } } + + & .dsa41-calculation { + font-size: 18px; + padding-top: 0.5rem; + } } diff --git a/src/main.mjs b/src/main.mjs index 49f81c7..43b65ca 100644 --- a/src/main.mjs +++ b/src/main.mjs @@ -1,10 +1,10 @@ const { TypeDataModel } = foundry.abstract; const { SchemaField, NumberField, StringField, BooleanField } = foundry.data.fields; const { ActorSheetV2, ItemSheetV2 } = foundry.applications.sheets; -const { HandlebarsApplicationMixin } = foundry.applications.api; +const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; const { OperatorTerm, NumericTerm } = foundry.dice.terms; -Hooks.once("init", function() { +Hooks.once("init", async function() { CONFIG.Combat.initiative.formula = "1d6 + @computed.ini_basiswert[INI-Basiswert]"; CONFIG.Actor.dataModels.Player = DSA41_CharacterData; @@ -32,7 +32,7 @@ Hooks.once("init", function() { ] }); - loadTemplates({ + await loadTemplates({ "editable-input": "systems/dsa-4th-edition/src/EditableInput.hbs", "attribute_tooltip": "systems/dsa-4th-edition/src/Tooltips/Attribute.hbs", @@ -40,6 +40,12 @@ Hooks.once("init", function() { "attacke_tooltip": "systems/dsa-4th-edition/src/Tooltips/Attacke.hbs", "parade_tooltip": "systems/dsa-4th-edition/src/Tooltips/Parade.hbs", "trefferpunkte_tooltip": "systems/dsa-4th-edition/src/Tooltips/Trefferpunkte.hbs", + + "fernkampf_attacke_tooltip": "systems/dsa-4th-edition/src/Tooltips/FernkampfAttacke.hbs", + "fernkampf_trefferpunkte_tooltip": "systems/dsa-4th-edition/src/Tooltips/FernkampfTrefferpunkte.hbs", + + "fernkampf_angriff_dialog": "systems/dsa-4th-edition/src/Dialogs/FernkampfAngriff.hbs", + "fernkampf_trefferpunkte_dialog": "systems/dsa-4th-edition/src/Dialogs/FernkampfTrefferpunkte.hbs", }); }); @@ -300,9 +306,10 @@ class DSA41_CharacterData extends TypeDataModel { attributes_without_modifiers: {}, kampf: { - talente: {}, - waffen: {}, - ruestungen: {}, + talente: {}, + waffen: {}, + fernkampf_waffen: {}, + ruestungen: {}, ruestungen_gesamt: { kopf: 0, brust: 0, @@ -374,6 +381,9 @@ class DSA41_CharacterData extends TypeDataModel { parade: 0, trefferpunkte: "", trefferpunkte_display: "", + + basis_attacke: 0, + basis_parade: 0, talent_attacke: 0, talent_parade: 0, @@ -390,10 +400,13 @@ class DSA41_CharacterData extends TypeDataModel { schild_parade: 0, }; + computed.basis_attacke = this.computed.at_basiswert; + computed.basis_parade = this.computed.pa_basiswert; + const talent = item.system.nahkampfwaffe.kampftalente; - computed.talent_attacke = this.computed.kampf.talente[talent].attacke; - computed.talent_parade = this.computed.kampf.talente[talent].parade; + computed.talent_attacke = this.kampf_talente[talent]?.attacke ?? 0; + computed.talent_parade = this.kampf_talente[talent]?.parade ?? 0; computed.modifikator_attacke = item.system.nahkampfwaffe.modifikator_attacke; computed.modifikator_parade = item.system.nahkampfwaffe.modifikator_parade; @@ -416,13 +429,35 @@ class DSA41_CharacterData extends TypeDataModel { computed.schild_parade += schild.system.schild.modifikator_parade; } - computed.attacke = computed.talent_attacke + computed.modifikator_attacke + computed.parierwaffe_attacke + computed.schild_attacke + Math.min(computed.tp_kk, 0); - computed.parade = computed.talent_parade + computed.modifikator_parade + computed.parierwaffe_parade + computed.schild_parade + Math.min(computed.tp_kk, 0); + computed.attacke = computed.basis_attacke + computed.talent_attacke + computed.modifikator_attacke + computed.parierwaffe_attacke + computed.schild_attacke + Math.min(computed.tp_kk, 0); + computed.parade = computed.basis_parade + computed.talent_parade + computed.modifikator_parade + computed.parierwaffe_parade + computed.schild_parade + Math.min(computed.tp_kk, 0); computed.trefferpunkte = get_minified_formula(item.system.nahkampfwaffe.basis + (computed.tp_kk != 0 ? " + " + computed.tp_kk : "")); computed.trefferpunkte_display = computed.trefferpunkte.replace(/[\+\-]/, (op) => "
" + op); } } + + for (const item of equipped_fernkampfwaffen) { + let computed = this.computed.kampf.fernkampf_waffen[item._id] = { + item: item, + attacke: 0, + trefferpunkte: "", + trefferpunkte_display: "", + + basis_attacke: 0, + talent_attacke: 0, + }; + + computed.basis_attacke = this.computed.fk_basiswert; + + const talent = item.system.nahkampfwaffe.kampftalente; + computed.talent_attacke = this.kampf_talente[talent]?.attacke ?? 0; + + computed.attacke = computed.basis_attacke + computed.talent_attacke; + + computed.trefferpunkte = get_minified_formula(item.system.fernkampfwaffe.basis); + computed.trefferpunkte_display = computed.trefferpunkte.replace(/[\+\-]/, (op) => "
" + op); + } } } @@ -551,6 +586,75 @@ function DSA41_ApplicationMixin(BaseApplication) { return DSA41_Application; } +class DSA41_Dialog extends DSA41_ApplicationMixin(ApplicationV2) { + static PARTS = { + FernkampfAngriff: { template: "systems/dsa-4th-edition/src/Dialogs/FernkampfAngriff.hbs" }, + FernkampfTrefferpunkte: { template: "systems/dsa-4th-edition/src/Dialogs/FernkampfTrefferpunkte.hbs" }, + + footer: { template: "templates/generic/form-footer.hbs" }, + }; + + static DEFAULT_OPTIONS = { + classes: [ "DSA41", "Dialog" ], + window: { + title: "Dialog", + minimizable: false, + resizable: false + }, + tag: "form", + form: { + closeOnSubmit: false, + submitOnChange: true, + } + }; + + get formData() { + const data = Object.fromEntries( + new FormData(this.element).entries().map(([key, value])=>{ + if (typeof value != "string") return [key, value]; + return isNaN(value) ? [key, value] : [key, Number(value)]; + }) + ); + + return data; + } + + buttons = [{ + type: "submit", + label: "Confirm" + }]; + + static async wait(dialog_type, options) { + return new Promise((resolve, reject) => { + const dialog = new this({ + dialog_type: dialog_type, + form: { + handler: (event, form, formData) => { + if (event.type != "submit") { + dialog.render({ force: false }); + return; + } + + dialog.close(); + resolve(dialog.formData); + } + }, + ...options, + }); + dialog.render({ force: true }); + }); + } + + _configureRenderOptions(options) { + super._configureRenderOptions(options); + options.parts = [ this.options.dialog_type, "footer" ]; + } + + _onFirstRender(context, options) { + this.render(options) + } +} + class DSA41_ActorSheet extends DSA41_ApplicationMixin(ActorSheetV2) { static PARTS = { ActorSheet: { template: "systems/dsa-4th-edition/src/ActorSheet.hbs" }, @@ -563,7 +667,41 @@ class DSA41_ActorSheet extends DSA41_ApplicationMixin(ActorSheetV2) { const roll_formula = event.target.closest("[data-roll]").dataset.roll; const roll_type = event.target.closest("[data-roll-type]").dataset.rollType; const success_value = event.target.closest("[data-success-value]")?.dataset.successValue; + const item_id = event.target.closest("[data-item-id]")?.dataset.itemId; + const item = this.document.items.get(item_id); + if (roll_type == "fernkampf-attacke") { + const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + item.name; + const data = await DSA41_Dialog.wait("FernkampfAngriff", { window: { title: title }, item: this.document.system.computed.kampf.fernkampf_waffen[item_id] }); + + const groessen_modifikator = Math.max(data.ziel_groesse + data.deckung + data.ziel_bewegung, -2); + const andere_modifikator = data.entfernung + data.wind + data.modifikator; + + const total_modifikator = groessen_modifikator + andere_modifikator; + + let roll = new Roll(roll_formula + " + " + total_modifikator, this.document.system); + roll.toMessage({ + speaker: ChatMessage.getSpeaker({ actor: this.document }), + flavor: game.i18n.localize("DSA41.roll_types." + roll_type), + }); + + return; + } + + if (roll_type == "fernkampf-trefferpunkte") { + const title = game.i18n.localize("DSA41.roll_types." + roll_type) + ": " + item.name; + const data = await DSA41_Dialog.wait("FernkampfTrefferpunkte", { window: { title: title }, item: item }); + const entfernung = item.system.fernkampfwaffe[data.entfernung]; + + let roll = new Roll(roll_formula + " + " + (entfernung + data.modifikator), this.document.system); + roll.toMessage({ + speaker: ChatMessage.getSpeaker({ actor: this.document }), + flavor: game.i18n.localize("DSA41.roll_types." + roll_type), + }); + + return; + } + let flavor = game.i18n.localize("DSA41.roll_types." + roll_type); if (typeof success_value !== 'undefined') { flavor += " <= " + success_value;