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(),
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({
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

View File

@ -105,6 +105,19 @@ export class Character extends Actor {
systemData.ausweichen.basis = systemData.pa.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")) {
systemData.rs = {
@ -119,11 +132,11 @@ export class Character extends Actor {
} else {
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
systemData.wunden.max = ko / 2;
systemData.wunden.max = Math.round(ko / 2);
if (game.settings.get("DSA_4-1", "optional_trefferzonen")) {
systemData.wunden.kopf = 0
systemData.wunden.brust = 0

View File

@ -36,6 +36,18 @@ function initGlobalSettings(settings) {
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', {
name: "Optional: 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.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 = []
for (let i = 0; i < actorData.appliedEffects.length; i++) {
const item = actorData.appliedEffects[i]

View File

@ -67,6 +67,7 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
openBagpack: CharacterSheet.#openBagpack,
openStandaloneSpells: CharacterSheet.#openStandaloneSpells,
openStandaloneLiturgies: CharacterSheet.#openStandaloneLiturgies,
setWounds: CharacterSheet.#setWounds,
}
}
@ -320,6 +321,12 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
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) {
super._configureRenderOptions(options)
@ -445,13 +452,6 @@ class CharacterSheet extends HandlebarsApplicationMixin(ActorSheetV2) {
context.img = actorData.img
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.trefferzonen = game.settings.get("DSA_4-1", "optional_trefferzonen")
context.ausdauer = game.settings.get("DSA_4-1", "optional_ausdauer")

View File

@ -3,8 +3,8 @@
display: grid;
grid-template-columns: 1fr 320px;
grid-template-rows: 32px 32px 1fr;
grid-template-areas: "res res" "wounds wounds" "actions actions" "cooldowns cooldowns";
grid-template-rows: 32px 32px 32px 1fr;
grid-template-areas: "res res" "wounds wounds" "fatigue fatigue" "effects effects" "effects effects";
padding: 8px;
gap: 8px;
@ -31,7 +31,7 @@
}
.wounds {
.wounds, .fatigue {
position: relative;
height: 24px;
display: flex;
@ -90,22 +90,46 @@
}
.actions {
grid-area: actions;
padding: 0;
.fatigue {
grid-area: fatigue;
flex-direction: row;
.grid-of-actions {
display: unset;
label {
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 {
grid-area: cooldowns;
.effects {
grid-area: effects;
}
&.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 {
grid-area: paperdoll;

View File

@ -42,31 +42,48 @@
</div>
{{#if (not trefferzonen)}}
<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}}
{{#if this}}
<div class="filled-segment" data-operation="reduceWounds"
<div class="filled-segment" data-action="setWounds"
data-value="{{@index}}">{{@index}}</div>
{{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}}
{{/each}}
</div>
{{/if}}
<div>
<label>Überanstrengung
<input type="number"/>
</label>
</div>
{{#if withErschoepfung}}
<div class="fatigue">
<label><span>Erschöpfung</span>
<input type="number" name="system.erschoepfung.aktuell" value="{{system.erschoepfung.aktuell}}"/>
</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>
<label>Erschöpfung
<input type="number"/>
</label>
</div>
{{#if (gt this.ueberanstrengung 0)}}
<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}}>{{system.erschoepfung.aktuell}}</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>
<ul>
{{#each effects}}