implements #84 in two distinct ways: left click for a touch friendly dialog, right click for inline editing of a resource.
parent
25152ff8db
commit
a42accc7ec
|
|
@ -55,5 +55,19 @@
|
|||
},
|
||||
"ITEM_BROWSER": {
|
||||
"progress": "{current}/{max}: Importiere von {compendium}"
|
||||
},
|
||||
"RESOURCE_DIALOG": {
|
||||
"Lep": {
|
||||
"title": "Lebenspunkte anpassen"
|
||||
},
|
||||
"Aup": {
|
||||
"title": "Ausdauerpunkte anpassen"
|
||||
},
|
||||
"Asp": {
|
||||
"title": "Astralpunkte anpassen"
|
||||
},
|
||||
"Kap": {
|
||||
"title": "Karmapunkte anpassen"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,20 @@ const {
|
|||
ArrayField,
|
||||
} = foundry.data.fields;
|
||||
|
||||
/**
|
||||
*
|
||||
* @property LE
|
||||
* @property AU
|
||||
* @property AE
|
||||
* @property KE
|
||||
*/
|
||||
export const ResourceType = {
|
||||
LE: "Lep",
|
||||
AU: "Aup",
|
||||
AE: "Asp",
|
||||
KE: "Kap"
|
||||
}
|
||||
|
||||
export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
|
||||
|
||||
static defineSchema() {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,113 @@
|
|||
import {ResourceType} from "../data/character.mjs";
|
||||
|
||||
const {
|
||||
ApplicationV2,
|
||||
HandlebarsApplicationMixin
|
||||
} = foundry.applications.api
|
||||
|
||||
export class EditResourceDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
static DEFAULT_OPTIONS = {
|
||||
classes: ['dsa41', 'dialog', 'resource'],
|
||||
tag: "form",
|
||||
position: {
|
||||
width: 480,
|
||||
height: 480
|
||||
},
|
||||
window: {
|
||||
resizable: false,
|
||||
title: "Resource anpassen"
|
||||
},
|
||||
form: {
|
||||
submitOnChange: false,
|
||||
closeOnSubmit: false,
|
||||
handler: EditResourceDialog.#onSubmitForm
|
||||
},
|
||||
actions: {
|
||||
setResource: EditResourceDialog.#onSetResource,
|
||||
}
|
||||
}
|
||||
|
||||
static PARTS = {
|
||||
form: {
|
||||
template: 'systems/DSA_4-1/templates/dialog/resource-dialog.hbs',
|
||||
}
|
||||
}
|
||||
|
||||
_actor = null;
|
||||
_resourceType = null;
|
||||
_min = 0;
|
||||
_current = 0;
|
||||
_max = 0;
|
||||
|
||||
constructor(actor, resourceType, min, current, max) {
|
||||
super();
|
||||
this._actor = actor;
|
||||
this._resourceType = resourceType;
|
||||
this._min = min;
|
||||
this._current = current;
|
||||
this._max = max;
|
||||
}
|
||||
|
||||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
this.close()
|
||||
}
|
||||
|
||||
static async #onSetResource(event, target) {
|
||||
const {value} = target.dataset;
|
||||
switch(this._resourceType) {
|
||||
case ResourceType.LE:
|
||||
await this._actor.update({"system.lep.aktuell": value});
|
||||
break;
|
||||
case ResourceType.AU:
|
||||
await this._actor.update({"system.aup.aktuell": value});
|
||||
break;
|
||||
case ResourceType.AE:
|
||||
await this._actor.update({"system.asp.aktuell": value});
|
||||
break;
|
||||
case ResourceType.KE:
|
||||
await this._actor.update({"system.kap.aktuell": value});
|
||||
}
|
||||
this.close();
|
||||
}
|
||||
|
||||
async _prepareContext(options) {
|
||||
const context = await super._prepareContext(options)
|
||||
|
||||
context.steps = [];
|
||||
|
||||
for (let i = this._min; i <= this._max; ++i ) {
|
||||
if (i < this._current) {
|
||||
context.steps.push({
|
||||
display: i - this._current,
|
||||
value: i,
|
||||
isReduction: true,
|
||||
isIncreasing: false,
|
||||
});
|
||||
} else if (i === this._current) {
|
||||
context.steps.push({
|
||||
display: i - this._current,
|
||||
value: i,
|
||||
isReduction: false,
|
||||
isIncreasing: false,
|
||||
});
|
||||
} else {
|
||||
context.steps.push({
|
||||
display: "+" + (i - this._current),
|
||||
value: i,
|
||||
isReduction: false,
|
||||
isIncreasing: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
return context
|
||||
}
|
||||
|
||||
_configureRenderOptions(options) {
|
||||
super._configureRenderOptions(options)
|
||||
if (options.window) {
|
||||
options.window.title = game.i18n.format("RESOURCE_DIALOG." + this._resourceType + ".title")
|
||||
}
|
||||
return options
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,8 @@ import {StandaloneLiturgies} from "./character-standalone/liturgies.mjs";
|
|||
import {StandaloneHealth} from "./character-standalone/health.mjs";
|
||||
import {SpellDialog} from "../dialog/spellDialog.mjs";
|
||||
import {displayRoll} from "../globals/displayRoll.js";
|
||||
import {ResourceType} from "../data/character.mjs";
|
||||
import {EditResourceDialog} from "../dialog/resourceDialog.mjs";
|
||||
|
||||
const {HandlebarsApplicationMixin, DocumentSheetV2} = foundry.applications.api
|
||||
const {ActorSheetV2} = foundry.applications.sheets
|
||||
|
|
@ -76,7 +78,10 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
setWounds: CharacterSheet.#setWounds,
|
||||
switchSet: CharacterSheet.#switchSet,
|
||||
openInitiative: CharacterSheet.#openInitiative,
|
||||
|
||||
editLep: CharacterSheet.#editLep,
|
||||
editAup: CharacterSheet.#editAup,
|
||||
editAsp: CharacterSheet.#editAsp,
|
||||
editKap: CharacterSheet.#editKap,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,6 +277,59 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
new SpellDialog(this.document, itemId).render(true)
|
||||
}
|
||||
|
||||
static #editAup(event, target, isRightClicked) {
|
||||
|
||||
if (!isRightClicked) {
|
||||
const min = 0
|
||||
const current = this.document.system.aup.aktuell
|
||||
const max = this.document.system.aup.max
|
||||
|
||||
const dialog = new EditResourceDialog(this.document, ResourceType.AU, min, current, max)
|
||||
dialog.render(true)
|
||||
target.parentElement.querySelector('input').blur();
|
||||
}
|
||||
}
|
||||
|
||||
static #editLep(event, target, isRightClicked) {
|
||||
|
||||
if (!isRightClicked) {
|
||||
const min = 0
|
||||
const current = this.document.system.lep.aktuell
|
||||
const max = this.document.system.lep.max
|
||||
|
||||
const dialog = new EditResourceDialog(this.document, ResourceType.LE, min, current, max)
|
||||
dialog.render(true)
|
||||
target.parentElement.querySelector('input').blur();
|
||||
}
|
||||
}
|
||||
|
||||
static #editAsp(event, target, isRightClicked) {
|
||||
|
||||
if (!isRightClicked) {
|
||||
const min = 0
|
||||
|
||||
const current = this.document.system.asp.aktuell
|
||||
const max = this.document.system.asp.max
|
||||
|
||||
const dialog = new EditResourceDialog(this.document, ResourceType.AE, min, current, max)
|
||||
dialog.render(true)
|
||||
target.parentElement.querySelector('input').blur();
|
||||
}
|
||||
}
|
||||
|
||||
static #editKap(event, target, isRightClicked) {
|
||||
|
||||
if (!isRightClicked) {
|
||||
const min = 0
|
||||
const current = this.document.system.kap.aktuell
|
||||
const max = this.document.system.kap.max
|
||||
|
||||
const dialog = new EditResourceDialog(this.document, ResourceType.KE, min, current, max)
|
||||
dialog.render(true)
|
||||
target.parentElement.querySelector('input').blur();
|
||||
}
|
||||
}
|
||||
|
||||
static #startResting(event, target) {
|
||||
|
||||
const dialog = new RestingDialog(this.document)
|
||||
|
|
@ -374,6 +432,22 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
static async #onSubmitForm(event, form, formData) {
|
||||
event.preventDefault()
|
||||
|
||||
if (formData.object["system.lep.aktuell"]?.[1]) {
|
||||
formData.object["system.lep.aktuell"] = formData.object["system.lep.aktuell"][0]
|
||||
}
|
||||
|
||||
if (formData.object["system.aup.aktuell"]?.[1]) {
|
||||
formData.object["system.aup.aktuell"] = formData.object["system.aup.aktuell"][0]
|
||||
}
|
||||
|
||||
if (formData.object["system.asp.aktuell"]?.[1]) {
|
||||
formData.object["system.asp.aktuell"] = formData.object["system.asp.aktuell"][0]
|
||||
}
|
||||
|
||||
if (formData.object["system.kap.aktuell"]?.[1]) {
|
||||
formData.object["system.kap.aktuell"] = formData.object["system.kap.aktuell"][0]
|
||||
}
|
||||
|
||||
await this.document.update(formData.object)
|
||||
|
||||
return false
|
||||
|
|
@ -797,6 +871,17 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
|
|||
}
|
||||
}
|
||||
|
||||
async _postRender() {
|
||||
this.element.querySelectorAll('.sidebar-element.resource-bar[data-action]').forEach( e => {
|
||||
const { action} = e.dataset;
|
||||
e.addEventListener('contextmenu', (event) => {
|
||||
if (CharacterSheet.DEFAULT_OPTIONS.actions[action]) {
|
||||
CharacterSheet.DEFAULT_OPTIONS.actions[action].bind(this)(event, event.target, true);
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default CharacterSheet
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ $talent-language-text-color: #000;
|
|||
$talent-crafting-color: #cd9551;
|
||||
$talent-crafting-text-color: #000;
|
||||
|
||||
$help-fill-color: #60d060ff;
|
||||
$help-border-color: #308030ff;
|
||||
|
||||
$harm-fill-color: #ff0000ff;
|
||||
$harm-border-color: #3c0000ff;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
.resource-bar {
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
height: 24px;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
|
|
@ -16,18 +18,43 @@
|
|||
margin: 8px 0;
|
||||
|
||||
label {
|
||||
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 3;
|
||||
width: 40px;
|
||||
line-height: 24px;
|
||||
vertical-align: middle;
|
||||
text-indent: 8px;
|
||||
color: white;
|
||||
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
input {
|
||||
position: absolute;
|
||||
left: 40px;
|
||||
top: 0;
|
||||
width: calc(100% - 40px);
|
||||
z-index: 4;
|
||||
height: 22px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
line-height: 24px;
|
||||
vertical-align: middle;
|
||||
text-indent: 8px;
|
||||
color: white;
|
||||
font-size: large;
|
||||
background: transparent;
|
||||
text-shadow: 2px 2px 1px rgba(0, 0, 0, 0.3);
|
||||
border: 0;
|
||||
&:hover {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
}
|
||||
span.resource-fill {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
@use "../atoms/colours" as colour;
|
||||
|
||||
.dsa41.dialog.resource {
|
||||
|
||||
section.steps {
|
||||
overflow: auto;
|
||||
flex: 1;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
|
||||
.step {
|
||||
display: inline-block;
|
||||
border: 1px solid black;
|
||||
width: 64px;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
vertical-align: middle;
|
||||
text-align: center;
|
||||
justify-self: center;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
|
||||
margin: 4px;
|
||||
box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.5),
|
||||
2px 2px inset rgba(0, 0, 0, 0.2);
|
||||
|
||||
&.reducing {
|
||||
background-color: colour.$harm-fill-color;
|
||||
border-color: colour.$harm-border-color;
|
||||
background-blend-mode: hue;
|
||||
}
|
||||
|
||||
&.increasing {
|
||||
background-color: colour.$help-fill-color;
|
||||
border-color: colour.$help-border-color;
|
||||
background-blend-mode: hue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -39,4 +39,5 @@
|
|||
@use "organisms/dialog";
|
||||
@use "organisms/deity-sheet";
|
||||
@use "organisms/item-browser-dialog";
|
||||
@use "organisms/resource-dialog";
|
||||
@use "atoms/chat";
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "DSA_4-1",
|
||||
"title": "Das Schwarze Auge 4.1",
|
||||
"description": "Noch ein Spielsystem für Das Schwarze Auge 4.1",
|
||||
"version": "0.11.2",
|
||||
"version": "0.0.1",
|
||||
"compatibility": {
|
||||
"minimum": 12,
|
||||
"verified": 13
|
||||
|
|
@ -364,5 +364,5 @@
|
|||
"primaryTokenAttribute": "lep.aktuell",
|
||||
"url": "https://git.macniel.online/macniel/foundry-dsa41-game",
|
||||
"manifest": "https://git.macniel.online/macniel/foundry-dsa41-game/raw/branch/main/src/system.json",
|
||||
"download": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/0.11.2/release.zip"
|
||||
"download": "https://git.macniel.online/macniel/foundry-dsa41-game/releases/download/0.0.1/release.zip"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,27 +31,27 @@
|
|||
|
||||
<img class="profile-img" src="{{img}}" data-action="editImage" data-edit="img" title="{{name}}"/>
|
||||
|
||||
<div class="sidebar-element resource-bar">
|
||||
<label>LeP: {{this.lepcurrent}}</label><span class="resource-fill lep"
|
||||
<div class="sidebar-element resource-bar" data-action="editLep">
|
||||
<label>LeP:</label> <input type="number" name="system.lep.aktuell" value="{{this.system.lep.aktuell}}"/><span class="resource-fill lep"
|
||||
style="width: {{this.lepper}}%"></span>
|
||||
</div>
|
||||
|
||||
{{#if ausdauer}}
|
||||
<div class="sidebar-element resource-bar">
|
||||
<label>AuP: {{this.aupcurrent}}</label><span class="resource-fill aup"
|
||||
<div class="sidebar-element resource-bar" data-action="editAup">
|
||||
<label>AuP:</label> <input type="number" name="system.aup.aktuell" value="{{this.system.aup.aktuell}}><span class="resource-fill aup"
|
||||
style="width: {{this.aupper}}%"></span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.hasLiturgies}}
|
||||
<div class="sidebar-element resource-bar">
|
||||
<label>KaP: {{this.kapcurrent}}</label><span class="resource-fill kap" style="width: {{this.keper}}%"></span>
|
||||
<div class="sidebar-element resource-bar" data-action="editKap">
|
||||
<label>KaP:</label> <input type="number" name="system.kap.aktuell" value="{{this.kapcurrent}}"><span class="resource-fill kap" style="width: {{this.keper}}%"></span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.hasSpells}}
|
||||
<div class="sidebar-element resource-bar">
|
||||
<label>AsP: {{this.aspcurrent}}</label><span class="resource-fill asp" style="width: {{this.aspper}}%"></span>
|
||||
<div class="sidebar-element resource-bar" data-action="editAsp">
|
||||
<label>AsP:</label> <input type="number" name="system.asp.aktuell" value="{{this.aspcurrent}}"><span class="resource-fill asp" style="width: {{this.aspper}}%"></span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
<section class="steps">
|
||||
|
||||
{{#each steps}}<div class="step{{#if this.isReduction}} reducing{{/if}}{{#if this.isIncreasing}} increasing{{/if}}" data-action="setResource" data-value="{{this.value}}">{{this.display}}</div>{{/each}}
|
||||
|
||||
</section>
|
||||
Loading…
Reference in New Issue