implements optional fatigue system.

pull/65/head
macniel 2025-11-16 16:07:42 +01:00
parent c00a6b11b7
commit 182aeb2dc6
7 changed files with 122 additions and 34 deletions

View File

@ -138,6 +138,10 @@ export class PlayerCharacterDataModel extends foundry.abstract.TypeDataModel {
key: new StringField(), key: new StringField(),
notiz: new StringField(), notiz: new StringField(),
})), })),
erschoepfung: new SchemaField({ // only with DSA_4-1.optional_erschoepfung
max: new NumberField({required: true, integer: true}),
aktuell: new NumberField({required: true, integer: true}),
}),
wunden: new SchemaField({ wunden: new SchemaField({
aktuell: new NumberField({required: true, integer: true}), // only with DSA_4-1.optional_trefferzonen = false aktuell: new NumberField({required: true, integer: true}), // only with DSA_4-1.optional_trefferzonen = false
max: new NumberField({required: true, integer: true}), // only with DSA_4-1.optional_trefferzonen = false max: new NumberField({required: true, integer: true}), // only with DSA_4-1.optional_trefferzonen = false

View File

@ -105,6 +105,19 @@ export class Character extends Actor {
systemData.ausweichen.basis = systemData.pa.basis systemData.ausweichen.basis = systemData.pa.basis
systemData.ausweichen.aktuell = systemData.ausweichen.basis systemData.ausweichen.aktuell = systemData.ausweichen.basis
systemData.ueberanstrengung = 0
if (game.settings.get("DSA_4-1", "optional_erschoepfung")) {
systemData.erschoepfung = {
aktuell: systemData.erschoepfung.aktuell ?? 0,
max: ko
}
if (systemData.erschoepfung.aktuell > systemData.erschoepfung.max) {
systemData.ueberanstrengung = systemData.erschoepfung.aktuell - systemData.erschoepfung.max
}
}
if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) { if (game.settings.get("DSA_4-1", "optional_ruestungzonen")) {
systemData.rs = { systemData.rs = {
@ -119,11 +132,11 @@ export class Character extends Actor {
} else { } else {
systemData.rs = 0; // only with DSA_4-1.optional_trefferzonen = false systemData.rs = 0; // only with DSA_4-1.optional_trefferzonen = false
} }
systemData.be = 0; systemData.be = 0 + systemData.ueberanstrengung;
// half KO is the maximum a character can sustain wounds before collapsing // half KO is the maximum a character can sustain wounds before collapsing
systemData.wunden.max = ko / 2; systemData.wunden.max = Math.round(ko / 2);
if (game.settings.get("DSA_4-1", "optional_trefferzonen")) { if (game.settings.get("DSA_4-1", "optional_trefferzonen")) {
systemData.wunden.kopf = 0 systemData.wunden.kopf = 0
systemData.wunden.brust = 0 systemData.wunden.brust = 0

View File

@ -36,6 +36,18 @@ function initGlobalSettings(settings) {
requiresReload: true requiresReload: true
}) })
settings.register('DSA_4-1', 'optional_erschoepfung', {
name: "Optional: Erschöpfung",
hint: "Aktiviert Regeln für das Spiel mit Erschöpfung und Überanstregung",
scope: "world",
config: true,
type: Boolean,
default: false,
onChange: value => {
},
requiresReload: true
})
settings.register('DSA_4-1', 'optional_distanzklassen', { settings.register('DSA_4-1', 'optional_distanzklassen', {
name: "Optional: Distanzklassen", name: "Optional: Distanzklassen",
hint: "Aktiviert Regeln für das Spiel mit Distanzklassen", hint: "Aktiviert Regeln für das Spiel mit Distanzklassen",

View File

@ -27,6 +27,24 @@ export default {
context.aspcurrent = actorData.system.asp.aktuell ?? 0 context.aspcurrent = actorData.system.asp.aktuell ?? 0
context.kapcurrent = actorData.system.kap.aktuell ?? 0 context.kapcurrent = actorData.system.kap.aktuell ?? 0
context.maxWounds = actorData.system.wunden.max ?? 3
context.wounds = actorData.system.wunden.aktuell ?? 0
context.woundsFilled = []
for (let i = 1; i <= context.maxWounds; i++) {
context.woundsFilled[i] = i <= context.wounds
}
context.withErschoepfung = game.settings.get("DSA_4-1", "optional_erschoepfung")
context.ueberanstrengung = actorData.system.ueberanstrengung
context.erschoepfung = actorData.system.erschoepfung.aktuell
context.maxErschoepfung = actorData.system.erschoepfung.max
context.erschoepfungFilled = []
for (let i = 1; i <= context.maxErschoepfung; i++) {
context.erschoepfungFilled[i] = i <= context.erschoepfung
}
context.effects = [] context.effects = []
for (let i = 0; i < actorData.appliedEffects.length; i++) { for (let i = 0; i < actorData.appliedEffects.length; i++) {
const item = actorData.appliedEffects[i] const item = actorData.appliedEffects[i]

View File

@ -67,6 +67,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
openBagpack: CharacterSheet.#openBagpack, openBagpack: CharacterSheet.#openBagpack,
openStandaloneSpells: CharacterSheet.#openStandaloneSpells, openStandaloneSpells: CharacterSheet.#openStandaloneSpells,
openStandaloneLiturgies: CharacterSheet.#openStandaloneLiturgies, openStandaloneLiturgies: CharacterSheet.#openStandaloneLiturgies,
setWounds: CharacterSheet.#setWounds,
} }
} }
@ -320,6 +321,12 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
new StandaloneLiturgies(this.document) new StandaloneLiturgies(this.document)
} }
static async #setWounds(event, target) {
const {value} = target.dataset
this.document.update({"system.wunden.aktuell": value})
this.render(true)
}
_configureRenderOptions(options) { _configureRenderOptions(options) {
super._configureRenderOptions(options) super._configureRenderOptions(options)
@ -445,13 +452,6 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
context.img = actorData.img context.img = actorData.img
context.effects = actorData.effects ?? [] context.effects = actorData.effects ?? []
context.maxWounds = actorData.system.wunden.max ?? 3
context.wounds = actorData.system.wunden.gesamt ?? 0
context.woundsFilled = []
for (let i = 1; i <= context.maxWounds; i++) {
context.woundsFilled[i] = i <= context.wounds
}
context.zonenruestung = game.settings.get("DSA_4-1", "optional_ruestungzonen") context.zonenruestung = game.settings.get("DSA_4-1", "optional_ruestungzonen")
context.trefferzonen = game.settings.get("DSA_4-1", "optional_trefferzonen") context.trefferzonen = game.settings.get("DSA_4-1", "optional_trefferzonen")
context.ausdauer = game.settings.get("DSA_4-1", "optional_ausdauer") context.ausdauer = game.settings.get("DSA_4-1", "optional_ausdauer")

View File

@ -3,8 +3,8 @@
display: grid; display: grid;
grid-template-columns: 1fr 320px; grid-template-columns: 1fr 320px;
grid-template-rows: 32px 32px 1fr; grid-template-rows: 32px 32px 32px 1fr;
grid-template-areas: "res res" "wounds wounds" "actions actions" "cooldowns cooldowns"; grid-template-areas: "res res" "wounds wounds" "fatigue fatigue" "effects effects" "effects effects";
padding: 8px; padding: 8px;
gap: 8px; gap: 8px;
@ -31,7 +31,7 @@
} }
.wounds { .wounds, .fatigue {
position: relative; position: relative;
height: 24px; height: 24px;
display: flex; display: flex;
@ -90,22 +90,46 @@
} }
.actions { .fatigue {
grid-area: actions; grid-area: fatigue;
padding: 0; flex-direction: row;
.grid-of-actions { label {
display: unset; span {
display: inline-block;
height: 26px;
line-height: 26px;
vertical-align: middle;
}
input {
position: absolute;
right: 0;
height: 26px;
text-align: center;
padding: 0;
margin: 0;
width: 28px;
}
} }
.filled-segment {
background-color: rgba(0, 128, 0, 0.8);
&.danger {
background-color: rgba(255, 0, 0, 0.8);
}
}
} }
.cooldowns { .effects {
grid-area: cooldowns; grid-area: effects;
} }
&.zones { &.zones {
grid-template-areas: "res res" "wounds wounds" "actions paperdoll" "cooldowns paperdoll"; grid-template-areas: "res res" "wounds wounds" "fatigue fatigue" "effects paperdoll" "effects paperdoll";
.paperdoll { .paperdoll {
grid-area: paperdoll; grid-area: paperdoll;

View File

@ -42,31 +42,48 @@
</div> </div>
{{#if (not trefferzonen)}} {{#if (not trefferzonen)}}
<div class="wounds"> <div class="wounds">
<label data-operation="reduceWounds" data-value="0">Wunden: {{this.wounds}} / {{this.maxWounds}}</label> <label data-action="setWounds" data-value="0">Wunden: {{this.wounds}} / {{this.maxWounds}}</label>
{{#each this.woundsFilled}} {{#each this.woundsFilled}}
{{#if this}} {{#if this}}
<div class="filled-segment" data-operation="reduceWounds" <div class="filled-segment" data-action="setWounds"
data-value="{{@index}}">{{@index}}</div> data-value="{{@index}}">{{@index}}</div>
{{else}} {{else}}
<div class="empty-segment" data-operation="addWounds" data-value="{{@index}}">{{@index}}</div> <div class="empty-segment" data-action="setWounds" data-value="{{@index}}">{{@index}}</div>
{{/if}} {{/if}}
{{/each}} {{/each}}
</div> </div>
{{/if}} {{/if}}
<div> {{#if withErschoepfung}}
<label>Überanstrengung <div class="fatigue">
<input type="number"/> <label><span>Erschöpfung</span>
</label> <input type="number" name="system.erschoepfung.aktuell" value="{{system.erschoepfung.aktuell}}"/>
</div> </label>
{{#each this.erschoepfungFilled}}
{{#if this}}
<div class="filled-segment {{#if (gt ../ueberanstrengung 0)}}danger{{/if}}" {{#if
(gt ../ueberanstrengung 0)}}data-tooltip="Überanstrengt<hr/>Zusätzliche BE: {{../ueberanstrengung}}"
{{else}}data-tooltip="Erschöpft<br/>{{../system.erschoepfung.aktuell}} von maximal {{../system.erschoepfung.max}}"{{/if}}>{{@index}}</div>
{{else}}
<div class="empty-segment {{#if (gt ../ueberanstrengung 0)}}danger{{/if}}" {{#if
(gt ../ueberanstrengung 0)}}data-tooltip="Überanstrengt<hr/>Zusätzliche BE: {{../ueberanstrengung}}"
{{else}}data-tooltip="Erschöpft<br/>{{../system.erschoepfung.aktuell}} von maximal {{../system.erschoepfung.max}}"{{/if}}>{{@index}}</div>
{{/if}}
{{/each}}
<div> {{#if (gt this.ueberanstrengung 0)}}
<label>Erschöpfung <div class="filled-segment {{#if (gt ueberanstrengung 0)}}danger{{/if}}" {{#if
<input type="number"/> (gt ueberanstrengung 0)}}data-tooltip="Überanstrengt<hr/>Zusätzliche BE: {{ueberanstrengung}}"
</label> {{else}}data-tooltip="Erschöpft<br/>{{../system.erschoepfung.aktuell}} von maximal {{../system.erschoepfung.max}}"{{/if}}>{{system.erschoepfung.aktuell}}</div>
</div> {{else}}
<div class="empty-segment {{#if (gt ueberanstrengung 0)}}danger{{/if}}" {{#if
(gt ueberanstrengung 0)}}data-tooltip="Überanstrengt<hr/>Zusätzliche BE: {{ueberanstrengung}}"
{{else}}data-tooltip="Erschöpft<br/>{{../system.erschoepfung.aktuell}} von maximal {{../system.erschoepfung.max}}"{{/if}}></div>
{{/if}}
</div>
{{/if}}
<div> <div class="effects">
<label>Einflüsse</label> <label>Einflüsse</label>
<ul> <ul>
{{#each effects}} {{#each effects}}