implements dialog for rolling skills
parent
d3f5702fd5
commit
fcbf6abaf6
|
|
@ -0,0 +1,10 @@
|
|||
export const ATTRIBUTE = {
|
||||
"mu": "Mut",
|
||||
"kl": "Klugheit",
|
||||
"in": "Intuition",
|
||||
"ch": "Charisma",
|
||||
"ff": "Fingerfertigkeit",
|
||||
"ge": "Gewandtheit",
|
||||
"ko": "Konstitution",
|
||||
"kk": "Körperkraft"
|
||||
}
|
||||
|
|
@ -25,7 +25,7 @@ export class SkillDataModel extends BaseItem {
|
|||
wert: new NumberField(),
|
||||
}, {required: false}), // Required skills at a given level
|
||||
talent: new HTMLField({required: true}),
|
||||
behinderung: new NumberField({required: false}), // BE-X
|
||||
behinderung: new StringField({required: false}), // BE-X
|
||||
komplexität: new NumberField({required: false}), // In case of languages
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,211 @@
|
|||
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 TalentDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['dsa41', 'dialog', 'talent'],
|
||||
tag: "form",
|
||||
position: {
|
||||
width: 480,
|
||||
height: 800
|
||||
},
|
||||
window: {
|
||||
resizable: false,
|
||||
title: "Talent nutzen"
|
||||
},
|
||||
form: {
|
||||
submitOnChange: true,
|
||||
closeOnSubmit: false,
|
||||
handler: TalentDialog.#onSubmitForm
|
||||
},
|
||||
actions: {
|
||||
use: TalentDialog.#use,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: 'systems/DSA_4-1/templates/dialog/talent-dialog.hbs',
|
||||
}
|
||||
}
|
||||
|
||||
static data = {}
|
||||
|
||||
/**
|
||||
*
|
||||
* @type {Actor}
|
||||
* @private
|
||||
*/
|
||||
_actor = null
|
||||
|
||||
constructor(actor, talentId) {
|
||||
super()
|
||||
this._actor = actor
|
||||
this._talent = this._actor.itemTypes["Skill"].find(p => p._id === talentId)
|
||||
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) {
|
||||
|
||||
const taw = this._talent.system.taw
|
||||
|
||||
let modValue = this._circumstance
|
||||
this._mods.forEach(mod => {
|
||||
modValue += Number(mod.value)
|
||||
})
|
||||
|
||||
const payload = {
|
||||
name: this._talent.name,
|
||||
taw: taw,
|
||||
mod: modValue,
|
||||
eigenschaft1: this._talent.system.probe[0].toLowerCase(),
|
||||
eigenschaft2: this._talent.system.probe[1].toLowerCase(),
|
||||
eigenschaft3: this._talent.system.probe[2].toLowerCase(),
|
||||
eigenschaften: {}
|
||||
}
|
||||
|
||||
payload.eigenschaften[this._talent.system.probe[0].toLowerCase()] = this._actor.system.attribute[this._talent.system.probe[0].toLowerCase()].aktuell
|
||||
payload.eigenschaften[this._talent.system.probe[1].toLowerCase()] = this._actor.system.attribute[this._talent.system.probe[1].toLowerCase()].aktuell
|
||||
payload.eigenschaften[this._talent.system.probe[2].toLowerCase()] = this._actor.system.attribute[this._talent.system.probe[2].toLowerCase()].aktuell
|
||||
|
||||
const result = await new Talent(payload).evaluate("publicroll")
|
||||
|
||||
result.evaluatedRoll.toMessage({
|
||||
speaker: ChatMessage.getSpeaker({actor: this._actor}),
|
||||
flavor: `Talent: ${this._talent.name}<br/>TaP*: ${result.tap}<br/>${result.meisterlich ? "Meisterlich" : ""}${result.patzer ? "Petzer" : ""}<br/>${this._talent.system.talent}`,
|
||||
})
|
||||
|
||||
this.close()
|
||||
}
|
||||
|
||||
_configureRenderOptions(options) {
|
||||
super._configureRenderOptions(options)
|
||||
|
||||
if (options.window) {
|
||||
if (this._talent) {
|
||||
options.window.title = this._talent.name
|
||||
}
|
||||
|
||||
options.position.height = 640
|
||||
|
||||
}
|
||||
|
||||
|
||||
return options
|
||||
}
|
||||
|
||||
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options)
|
||||
context.actor = this._actor
|
||||
context.talent = this._talent
|
||||
context.colorfulDice = game.settings.get('DSA_4-1', 'optional_colorfuldice')
|
||||
|
||||
context.text = context.talent.system.talent
|
||||
|
||||
context.dice = []
|
||||
context.talent.system.probe.forEach(p => {
|
||||
context.dice.push({
|
||||
wert: this._actor.system.attribute[p.toLowerCase()].aktuell,
|
||||
name: p,
|
||||
tooltip: ATTRIBUTE[p.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.talent === adv.name) {
|
||||
context.mods.push({
|
||||
name: adv.name,
|
||||
value: mod.value,
|
||||
mod: adv.name + "talent",
|
||||
active: this._mods.find(mod => mod.name === adv.name + "talent")
|
||||
})
|
||||
}
|
||||
|
||||
if (mod.name) {
|
||||
context.talent.system.probe.forEach(p => {
|
||||
if (mod.name === `attribute.${p.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")
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}))
|
||||
|
||||
if (context.talent.system.behinderung) { // can be null
|
||||
const eBE = context.talent.system.behinderung
|
||||
|
||||
if (eBE === "situationsbedingt") {
|
||||
context.mods.push({
|
||||
name: `Behinderung`,
|
||||
value: -this._actor.system.be,
|
||||
mod: "Behinderung",
|
||||
active: this._mods.find(mod => mod.name === "Behinderung")
|
||||
|
||||
})
|
||||
} else {
|
||||
const be = eval(this._actor.system.be + eBE) // eBE can be *X, +X, -X
|
||||
context.mods.push({
|
||||
name: `Behinderung (eBE${eBE})`,
|
||||
value: -be,
|
||||
mod: "Behinderung",
|
||||
active: this._mods.find(mod => mod.name === "Behinderung")
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
context.taw = this._talent.system.taw
|
||||
context.circumstance = this._circumstance
|
||||
context.penalty = 0
|
||||
this._mods.forEach(mod => {
|
||||
context.penalty += Number(mod.value)
|
||||
})
|
||||
|
||||
context.modResult = context.taw + context.circumstance + context.penalty
|
||||
context.displayModResult = context.modResult > 0 ? `+${context.modResult}` : context.modResult
|
||||
|
||||
return context
|
||||
}
|
||||
}
|
||||
|
|
@ -13,6 +13,7 @@ import {DefenseActionDialog} from "../dialog/defenseAction.mjs";
|
|||
import {RestingDialog} from "../dialog/restingDialog.mjs";
|
||||
import {Character} from "../documents/character.mjs";
|
||||
import {LiturgyDialog} from "../dialog/modify-liturgy.mjs";
|
||||
import {TalentDialog} from "../dialog/talentDialog.mjs";
|
||||
|
||||
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
|
||||
const {ActorSheetV2} = foundry.applications.sheets
|
||||
|
|
@ -103,10 +104,8 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
*/
|
||||
static #rollSkill(event) {
|
||||
const {id} = event.target.dataset
|
||||
const skill = this.document.items.get(id)
|
||||
if (skill?.system?.roll) {
|
||||
skill.system.roll("publicroll")
|
||||
}
|
||||
|
||||
new TalentDialog(this.document, id).render(true)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -481,7 +480,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
{
|
||||
eigenschaft: "ge",
|
||||
name: "GE",
|
||||
tooltip: "Geschicklichkeit",
|
||||
tooltip: "Gewandtheit",
|
||||
wert: context.derived.attribute.ge.aktuell ?? 0,
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
.Geschicklichkeit {
|
||||
.Gewandtheit {
|
||||
|
||||
.die svg path {
|
||||
fill: colours.$attribute-die-dx-color;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,103 @@
|
|||
@use "../molecules/attribute-die";
|
||||
|
||||
.dsa41.dialog.talent, .dsa41.dialog.eigenschaft {
|
||||
|
||||
section[data-application-part] {
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
height: 100%;
|
||||
|
||||
.attributes {
|
||||
@include attribute-die.attributes;
|
||||
top: 0;
|
||||
left: 0;
|
||||
justify-content: center;
|
||||
|
||||
hr.zier {
|
||||
flex: 1;
|
||||
align-self: center;
|
||||
border-top: 1px inset;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
table {
|
||||
tr {
|
||||
th:first-child {
|
||||
width: 48px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-y {
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
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 {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.malus-and-mod {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-template-rows: 1fr;
|
||||
gap: 0 8px;
|
||||
|
||||
label {
|
||||
|
||||
span {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
output {
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
line-height: 32px;
|
||||
vertical-align: middle;
|
||||
display: block;
|
||||
padding: 0 8px;
|
||||
border: 1px inset;
|
||||
border-radius: 4px;
|
||||
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.actions {
|
||||
align-self: center;
|
||||
flex: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -33,4 +33,5 @@
|
|||
@use "organisms/merchant-sheet";
|
||||
@use "organisms/resting-dialog";
|
||||
@use "organisms/battle-dialog";
|
||||
@use "organisms/liturgy-sheet";
|
||||
@use "organisms/liturgy-sheet";
|
||||
@use "organisms/dialog";
|
||||
|
|
@ -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>TaW</span>
|
||||
<output name="lkp" type="number">{{taw}}</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> Talenteinsatz {{#if modResult}}
|
||||
[{{displayModResult}}]{{/if}}</button>
|
||||
|
||||
</section>
|
||||
Loading…
Reference in New Issue