implements die roll dialogs for attributes / flaws.
parent
277318a37b
commit
453db6f599
|
|
@ -0,0 +1,187 @@
|
||||||
|
import {LiturgyData} from "../data/miracle/liturgydata.mjs";
|
||||||
|
import {Talent} from "../data/talent.mjs";
|
||||||
|
import {ATTRIBUTE} from "../data/attribute.mjs";
|
||||||
|
|
||||||
|
const {ApplicationV2, HandlebarsApplicationMixin} = foundry.applications.api
|
||||||
|
|
||||||
|
export class AttributeDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
classes: ['dsa41', 'dialog', 'eigenschaft'],
|
||||||
|
tag: "form",
|
||||||
|
position: {
|
||||||
|
width: 480,
|
||||||
|
height: 800
|
||||||
|
},
|
||||||
|
window: {
|
||||||
|
resizable: false,
|
||||||
|
title: "Eigenschaft nutzen"
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
submitOnChange: true,
|
||||||
|
closeOnSubmit: false,
|
||||||
|
handler: AttributeDialog.#onSubmitForm
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
use: AttributeDialog.#use,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static PARTS = {
|
||||||
|
form: {
|
||||||
|
template: 'systems/DSA_4-1/templates/dialog/attribute-dialog.hbs',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static data = {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {Actor}
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_actor = null
|
||||||
|
|
||||||
|
constructor(actor, attributeOrAdvantageId) {
|
||||||
|
super()
|
||||||
|
this._actor = actor
|
||||||
|
const advantage = this._actor.itemTypes["Advantage"].find(p => p._id === attributeOrAdvantageId)
|
||||||
|
if (advantage) {
|
||||||
|
const badAttribute = advantage
|
||||||
|
this._name = badAttribute.name
|
||||||
|
this._value = badAttribute.system.value
|
||||||
|
this._flaw = true
|
||||||
|
this._symbol = "flaw"
|
||||||
|
this._text = badAttribute.system.description
|
||||||
|
} else {
|
||||||
|
this._name = attributeOrAdvantageId.name
|
||||||
|
this._value = this._actor.system.attribute[attributeOrAdvantageId.symbol.toLowerCase()].aktuell
|
||||||
|
this._flaw = false
|
||||||
|
this._symbol = attributeOrAdvantageId.symbol
|
||||||
|
}
|
||||||
|
|
||||||
|
this._circumstance = 0
|
||||||
|
this._mods = []
|
||||||
|
}
|
||||||
|
|
||||||
|
static async #onSubmitForm(event, form, formData) {
|
||||||
|
event.preventDefault()
|
||||||
|
|
||||||
|
this._circumstance = formData.object["circumstance"]
|
||||||
|
this._mods = []
|
||||||
|
Object.entries(formData.object).filter(([key, value]) => key.startsWith("mods.")).forEach(([key, value]) => {
|
||||||
|
const [_, suffix] = key.split("mods.")
|
||||||
|
if (value != null) {
|
||||||
|
this._mods.push({
|
||||||
|
name: suffix,
|
||||||
|
value: value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
this.render({parts: ["form"]})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static async #use(event, target) {
|
||||||
|
|
||||||
|
|
||||||
|
let modValue = this._circumstance
|
||||||
|
this._mods.forEach(mod => {
|
||||||
|
modValue += Number(mod.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
const targetValue = this._value + modValue
|
||||||
|
|
||||||
|
let roll = await new Roll(`1d20`).evaluate()
|
||||||
|
let diff = targetValue - roll.terms[0].results[0].result
|
||||||
|
roll.toMessage({
|
||||||
|
speaker: ChatMessage.getSpeaker({actor: this.actor}),
|
||||||
|
flavor: `${this._flaw ? "Schlechte " : ""}Eigenschaft: ${this._name}<br/>Ergebnis: ${Math.abs(diff)}${diff > 0 ? " übrig" : " daneben"}`,
|
||||||
|
rollMode: game.settings.get('core', 'rollMode'),
|
||||||
|
});
|
||||||
|
|
||||||
|
this.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
_configureRenderOptions(options) {
|
||||||
|
super._configureRenderOptions(options)
|
||||||
|
|
||||||
|
if (options.window) {
|
||||||
|
if (this._flaw) {
|
||||||
|
options.window.title = `Schlechte Eigenschaft: ${this._name}`
|
||||||
|
} else {
|
||||||
|
options.window.title = `Eigenschaft: ${this._name}`
|
||||||
|
}
|
||||||
|
|
||||||
|
options.position.height = 640
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return options
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async _prepareContext(options) {
|
||||||
|
const context = await super._prepareContext(options)
|
||||||
|
context.actor = this._actor
|
||||||
|
context.colorfulDice = game.settings.get('DSA_4-1', 'optional_colorfuldice')
|
||||||
|
|
||||||
|
context.text = this._text
|
||||||
|
|
||||||
|
context.dice = []
|
||||||
|
|
||||||
|
if (this._flaw) {
|
||||||
|
context.dice.push({
|
||||||
|
wert: this._value,
|
||||||
|
name: "",
|
||||||
|
tooltip: "flaw",
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
context.dice.push({
|
||||||
|
wert: this._actor.system.attribute[this._symbol.toLowerCase()].aktuell,
|
||||||
|
name: this._symbol.toUpperCase(),
|
||||||
|
tooltip: ATTRIBUTE[this._symbol.toLowerCase()],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
context.mods = [] // ADV, DDV, SF that may influence this talent atleast BE
|
||||||
|
|
||||||
|
const categories = ["Advantage", "SpecialAbility"]
|
||||||
|
categories.forEach(category => this._actor.itemTypes[category].forEach(adv => {
|
||||||
|
|
||||||
|
const mods = adv.system.getActiveMod()
|
||||||
|
|
||||||
|
mods?.forEach(mod => {
|
||||||
|
|
||||||
|
if (mod.name) {
|
||||||
|
|
||||||
|
if (mod.name === `attribute.${this._symbol.toLowerCase()}.mod`) {
|
||||||
|
context.mods.push({
|
||||||
|
name: adv.name,
|
||||||
|
value: mod.value,
|
||||||
|
mod: adv.name + "eigenschaft",
|
||||||
|
active: this._mods.find(mod => mod.name === adv.name + "eigenschaft")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}))
|
||||||
|
|
||||||
|
context.value = this._value
|
||||||
|
context.circumstance = this._circumstance
|
||||||
|
context.penalty = 0
|
||||||
|
this._mods.forEach(mod => {
|
||||||
|
context.penalty += Number(mod.value)
|
||||||
|
})
|
||||||
|
|
||||||
|
context.modResult = context.circumstance + context.penalty
|
||||||
|
context.displayModResult = context.modResult > 0 ? `+${context.modResult}` : context.modResult
|
||||||
|
|
||||||
|
return context
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -44,6 +44,8 @@ export class AdvantageSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
|
|
||||||
await this.document.update(formData.object) // Note: formData.object
|
await this.document.update(formData.object) // Note: formData.object
|
||||||
|
|
||||||
|
console.log(formData.object, this.document)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @override */
|
/** @override */
|
||||||
|
|
@ -56,7 +58,7 @@ export class AdvantageSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
|
||||||
context.hasChoices = context.system.auswahl?.length > 0;
|
context.hasChoices = context.system.auswahl?.length > 0;
|
||||||
context.choices = {}
|
context.choices = {}
|
||||||
context.system.auswahl?.forEach(a => {
|
context.system.auswahl?.forEach(a => {
|
||||||
context.choices[a] = a
|
context.choices[a.name] = a.name
|
||||||
})
|
})
|
||||||
context.hasModality = context.system.value != null
|
context.hasModality = context.system.value != null
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,9 @@ import {ActionManager} from "./actions/action-manager.mjs";
|
||||||
import {DefenseActionDialog} from "../dialog/defenseAction.mjs";
|
import {DefenseActionDialog} from "../dialog/defenseAction.mjs";
|
||||||
import {RestingDialog} from "../dialog/restingDialog.mjs";
|
import {RestingDialog} from "../dialog/restingDialog.mjs";
|
||||||
import {Character} from "../documents/character.mjs";
|
import {Character} from "../documents/character.mjs";
|
||||||
import {LiturgyDialog} from "../dialog/modify-liturgy.mjs";
|
import {LiturgyDialog} from "../dialog/liturgyDialog.mjs";
|
||||||
import {TalentDialog} from "../dialog/talentDialog.mjs";
|
import {TalentDialog} from "../dialog/talentDialog.mjs";
|
||||||
|
import {AttributeDialog} from "../dialog/attributeDialog.mjs";
|
||||||
|
|
||||||
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
|
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
|
||||||
const {ActorSheetV2} = foundry.applications.sheets
|
const {ActorSheetV2} = foundry.applications.sheets
|
||||||
|
|
@ -39,7 +40,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||||
rollCombatSkill: CharacterSheet.#rollCombatSkill,
|
rollCombatSkill: CharacterSheet.#rollCombatSkill,
|
||||||
rollSkill: CharacterSheet.#rollSkill,
|
rollSkill: CharacterSheet.#rollSkill,
|
||||||
rollFlaw: CharacterSheet.#rollFlaw,
|
rollFlaw: CharacterSheet.#rollFlaw,
|
||||||
roll: CharacterSheet.#dieRoll,
|
rollAttribute: CharacterSheet.#rollAttribute,
|
||||||
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
|
||||||
openEmbeddedDocument: CharacterSheet.#openEmbeddedDocument,
|
openEmbeddedDocument: CharacterSheet.#openEmbeddedDocument,
|
||||||
openCultureDocument: CharacterSheet.#openCultureDocument,
|
openCultureDocument: CharacterSheet.#openCultureDocument,
|
||||||
|
|
@ -120,37 +121,17 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static #dieRoll(event, target) {
|
static #rollAttribute(event, target) {
|
||||||
event.preventDefault()
|
|
||||||
const {roll} = target.dataset
|
new AttributeDialog(this.document, {
|
||||||
if (roll) {
|
name: target.dataset.name,
|
||||||
let label = dataset.label ? `[Attribut] ${dataset.label}` : ''
|
value: target.dataset.value,
|
||||||
let roll = new Roll(dataset.roll, this.actor.getRollData())
|
symbol: target.dataset.symbol,
|
||||||
roll.toMessage({
|
}).render(true)
|
||||||
speaker: ChatMessage.getSpeaker({actor: this.actor}),
|
|
||||||
flavor: label,
|
|
||||||
rollMode: game.settings.get('core', 'rollMode'),
|
|
||||||
});
|
|
||||||
return roll
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async #rollFlaw(event, target) {
|
static async #rollFlaw(event, target) {
|
||||||
event.preventDefault()
|
new AttributeDialog(this.document, target.dataset.itemId).render(true)
|
||||||
const {itemId} = target.dataset
|
|
||||||
if (itemId) {
|
|
||||||
const flaw = this.document.items.get(itemId)
|
|
||||||
if (flaw) {
|
|
||||||
const target = flaw.system.value
|
|
||||||
let roll = await new Roll(`1d20`).evaluate()
|
|
||||||
let diff = target - roll.terms[0].results[0].result
|
|
||||||
roll.toMessage({
|
|
||||||
speaker: ChatMessage.getSpeaker({actor: this.actor}),
|
|
||||||
flavor: `Schlechte Eigenschaft: ${flaw.name}<br/>Ergebnis: ${Math.abs(diff)}${diff > 0 ? " übrig" : " daneben"}`,
|
|
||||||
rollMode: game.settings.get('core', 'rollMode'),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async #progressCooldown(event, target) {
|
static async #progressCooldown(event, target) {
|
||||||
|
|
|
||||||
|
|
@ -6,66 +6,39 @@
|
||||||
"description": "Eine Eigenschaft, die der Held bei der Generierung auf einen Wert von 8 gesetzt hat (vor Einrechnung der Modifikatoren aus Rasse, Kultur, Profession und eventuellen anderen Vor- und Nachteilen), wird auf 7 gesenkt. Diese Eigenschaft kann in der späteren Laufbahn des Helden nur zu den doppelten Steigerungskosten angehoben werden. Dieser Nachteil kann mehr fach gewählt werden, allerdings für jede Eigenschaft nur einmal.",
|
"description": "Eine Eigenschaft, die der Held bei der Generierung auf einen Wert von 8 gesetzt hat (vor Einrechnung der Modifikatoren aus Rasse, Kultur, Profession und eventuellen anderen Vor- und Nachteilen), wird auf 7 gesenkt. Diese Eigenschaft kann in der späteren Laufbahn des Helden nur zu den doppelten Steigerungskosten angehoben werden. Dieser Nachteil kann mehr fach gewählt werden, allerdings für jede Eigenschaft nur einmal.",
|
||||||
"auswahl": [
|
"auswahl": [
|
||||||
{
|
{
|
||||||
"name": "Miserable Eigenschaft: Intuition",
|
"name": "Intuition",
|
||||||
"mod": [
|
"mod": [
|
||||||
{
|
|
||||||
"name": "attribute.in.aktuell",
|
|
||||||
"value": "7"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Miserable Eigenschaft: Klugheit",
|
"name": "Klugheit",
|
||||||
"mod": [
|
"mod": [
|
||||||
{
|
|
||||||
"name": "attribute.kl.aktuell",
|
|
||||||
"value": "7"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Miserable Eigenschaft: Mut",
|
"name": "Mut",
|
||||||
"mod": [
|
"mod": [
|
||||||
{
|
|
||||||
"name": "attribute.mu.aktuell",
|
|
||||||
"value": "7"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Miserable Eigenschaft: Körperkraft",
|
"name": "Körperkraft",
|
||||||
"mod": [
|
"mod": [
|
||||||
{
|
|
||||||
"name": "attribute.kk.aktuell",
|
|
||||||
"value": "7"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Miserable Eigenschaft: Fingerfertigkeit",
|
"name": "Fingerfertigkeit",
|
||||||
"mod": [
|
"mod": [
|
||||||
{
|
|
||||||
"name": "attribute.ff.aktuell",
|
|
||||||
"value": "7"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Miserable Eigenschaft: Gewandtheit",
|
"name": "Gewandtheit",
|
||||||
"mod": [
|
"mod": [
|
||||||
{
|
|
||||||
"name": "attribute.ge.aktuell",
|
|
||||||
"value": "7"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Miserable Eigenschaft: Konstitution",
|
"name": "Konstitution",
|
||||||
"mod": [
|
"mod": [
|
||||||
{
|
|
||||||
"name": "attribute.ko.aktuell",
|
|
||||||
"value": "7"
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,8 @@ $attribute-die-ag-color: #d5b467;
|
||||||
$attribute-die-bd-color: #a3a3a3;
|
$attribute-die-bd-color: #a3a3a3;
|
||||||
$attribute-die-st-color: #d6a878;
|
$attribute-die-st-color: #d6a878;
|
||||||
|
|
||||||
|
$attribute-die-flaw-color: #6a24d8;
|
||||||
|
|
||||||
$attribute-die-co-text-color: #fff;
|
$attribute-die-co-text-color: #fff;
|
||||||
$attribute-die-sm-text-color: #fff;
|
$attribute-die-sm-text-color: #fff;
|
||||||
$attribute-die-in-text-color: #fff;
|
$attribute-die-in-text-color: #fff;
|
||||||
|
|
@ -62,6 +64,8 @@ $attribute-die-ag-text-color: #000;
|
||||||
$attribute-die-bd-text-color: #000;
|
$attribute-die-bd-text-color: #000;
|
||||||
$attribute-die-st-text-color: #000;
|
$attribute-die-st-text-color: #000;
|
||||||
|
|
||||||
|
$attribute-die-flaw-text-color: #FFF;
|
||||||
|
|
||||||
|
|
||||||
$attribute-label-color: #000;
|
$attribute-label-color: #000;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,5 +140,16 @@
|
||||||
color: colours.$attribute-die-st-text-color;
|
color: colours.$attribute-die-st-text-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flaw {
|
||||||
|
|
||||||
|
.die svg path {
|
||||||
|
fill: colours.$attribute-die-flaw-color;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wert {
|
||||||
|
color: colours.$attribute-die-flaw-text-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="attributes {{#if this.colorfulDice}}colorfulDice{{/if}}">
|
<div class="attributes {{#if this.colorfulDice}}colorfulDice{{/if}}">
|
||||||
{{#each attributes}}
|
{{#each attributes}}
|
||||||
|
<div data-symbol="{{this.eigenschaft}}" data-value="{{this.wert}}" data-name="{{tooltip}}"
|
||||||
|
data-action="rollAttribute">
|
||||||
{{> "systems/DSA_4-1/templates/ui/partial-attribute-button.hbs" this}}
|
{{> "systems/DSA_4-1/templates/ui/partial-attribute-button.hbs" this}}
|
||||||
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
<section>
|
||||||
|
|
||||||
|
<div class="attributes {{#if this.colorfulDice}}colorfulDice{{/if}}">
|
||||||
|
|
||||||
|
<hr class="zier"/>
|
||||||
|
|
||||||
|
{{#each dice}}
|
||||||
|
|
||||||
|
{{> "systems/DSA_4-1/templates/ui/partial-attribute-button.hbs" this}}
|
||||||
|
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
<hr class="zier"/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="scroll-y">
|
||||||
|
{{{this.text}}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table>
|
||||||
|
{{#each this.mods}}
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" name="mods.{{this.mod}}" value="{{this.value}}" {{checked this.active}}>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{this.name}}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{{this.value}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<fieldset class="modding">
|
||||||
|
<legend>Erschwernisse</legend>
|
||||||
|
<div class="malus-and-mod">
|
||||||
|
<label><span>Wert</span>
|
||||||
|
<output name="wert" type="number">{{value}}</output>
|
||||||
|
</label>
|
||||||
|
<label><span>Umstände</span>
|
||||||
|
<input name="circumstance" type="number" value="{{circumstance}}">
|
||||||
|
</label>
|
||||||
|
<label><span>Modifikation</span>
|
||||||
|
<output name="penalty">{{penalty}}</output>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<output class="modResult"></output>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
|
||||||
|
<button class="actions" data-action="use"><i class="fa-solid fa-bolt"></i> Eigenschaftseinsatz {{#if modResult}}
|
||||||
|
[{{displayModResult}}]{{/if}}</button>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
<div>
|
<div>
|
||||||
<label for="{{this._id}}.choice">Auswahl</label>
|
<label for="{{this._id}}.choice">Auswahl</label>
|
||||||
{{#if hasChoices}}
|
{{#if hasChoices}}
|
||||||
<select id="{{this._id}}.choice" name="system.gruppe">
|
<select id="{{this._id}}.choice" name="system.value">
|
||||||
{{selectOptions choices selected=system.auswahl inverted=true}}
|
{{selectOptions choices selected=system.value inverted=true}}
|
||||||
</select>
|
</select>
|
||||||
{{else}}
|
{{else}}
|
||||||
<input type="text" id="{{this._id}}.choice" name="system.value" value="{{system.value}}"/>
|
<input type="text" id="{{this._id}}.choice" name="system.value" value="{{system.value}}"/>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue