diff --git a/src/lang/de.json b/src/lang/de.json
index 7c84a0e8..98a53114 100644
--- a/src/lang/de.json
+++ b/src/lang/de.json
@@ -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"
+ }
}
}
diff --git a/src/module/data/character.mjs b/src/module/data/character.mjs
index c571c246..9b127d60 100644
--- a/src/module/data/character.mjs
+++ b/src/module/data/character.mjs
@@ -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() {
diff --git a/src/module/dialog/resourceDialog.mjs b/src/module/dialog/resourceDialog.mjs
new file mode 100644
index 00000000..c9717873
--- /dev/null
+++ b/src/module/dialog/resourceDialog.mjs
@@ -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
+ }
+}
diff --git a/src/module/sheets/characterSheet.mjs b/src/module/sheets/characterSheet.mjs
index 6cf3a150..6df735c9 100644
--- a/src/module/sheets/characterSheet.mjs
+++ b/src/module/sheets/characterSheet.mjs
@@ -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
diff --git a/src/style/atoms/_colours.scss b/src/style/atoms/_colours.scss
index 774e4429..8ebd247c 100644
--- a/src/style/atoms/_colours.scss
+++ b/src/style/atoms/_colours.scss
@@ -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;
diff --git a/src/style/molecules/_sidebar-elements.scss b/src/style/molecules/_sidebar-elements.scss
index f8a5ba5c..e5e2ec84 100644
--- a/src/style/molecules/_sidebar-elements.scss
+++ b/src/style/molecules/_sidebar-elements.scss
@@ -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;
diff --git a/src/style/organisms/_resource-dialog.scss b/src/style/organisms/_resource-dialog.scss
new file mode 100644
index 00000000..200c3784
--- /dev/null
+++ b/src/style/organisms/_resource-dialog.scss
@@ -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;
+ }
+ }
+
+ }
+
+}
diff --git a/src/style/styles.scss b/src/style/styles.scss
index fa9bdc0a..5274d255 100644
--- a/src/style/styles.scss
+++ b/src/style/styles.scss
@@ -39,4 +39,5 @@
@use "organisms/dialog";
@use "organisms/deity-sheet";
@use "organisms/item-browser-dialog";
+@use "organisms/resource-dialog";
@use "atoms/chat";
\ No newline at end of file
diff --git a/src/system.json b/src/system.json
index 89c4f26a..21932c0f 100644
--- a/src/system.json
+++ b/src/system.json
@@ -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"
}
diff --git a/src/templates/actor/character/main-sheet.hbs b/src/templates/actor/character/main-sheet.hbs
index 798e5c2e..2389e217 100644
--- a/src/templates/actor/character/main-sheet.hbs
+++ b/src/templates/actor/character/main-sheet.hbs
@@ -31,27 +31,27 @@
-