daggerheart/module/data/countdowns.mjs
WBHarry d2e87e4eb9
[Feature] CountdownsType Split (#1990)
* Toggle pills

* Finished animation framework

* .

* Fixed localization

* Fixed iconOnly

* Updated SRD Action Countdown types

* feat: add shimmer animation when change countdown value

* Fixed so that hidden countdowns don't take up space

* Fixed countdowns.hbs part using wrong context for iconOnly

* Restored glow animation for category chip

* Changed back to a single sheen effect

* [Review] Move visible countdown types to getter (#1999)

* Move visible countdown types to getter

* Punchier shimmer animation

* Restored encounter/narrative

* Lang cleanup

* .

---------

Co-authored-by: Murilo Brito <dev.murilobrito@gmail.com>
Co-authored-by: Carlos Fernandez <CarlosFdez@users.noreply.github.com>
2026-06-16 22:23:13 +02:00

139 lines
5.3 KiB
JavaScript

import FormulaField from './fields/formulaField.mjs';
export default class DhCountdowns extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
countdowns: new fields.TypedObjectField(new fields.EmbeddedDataField(DhCountdown)),
defaultOwnership: new fields.NumberField({
required: true,
choices: CONFIG.DH.GENERAL.basicOwnershiplevels,
initial: CONST.DOCUMENT_OWNERSHIP_LEVELS.OBSERVER
})
};
}
handleChange() {
const previousCountdowns = foundry.ui.countdowns.previousCountdownData;
const changedCountdowns = Object.entries(this.countdowns).reduce((acc, [key, countdown]) => {
const previousCountdown = previousCountdowns[key];
if (!previousCountdown || (previousCountdown.progress.current !== countdown.progress.current)) {
acc.push(key);
}
return acc;
}, []);
foundry.ui.countdowns.changedCountdownsForAnimation.add(...changedCountdowns);
}
}
export class DhCountdown extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
type: new fields.StringField({
required: true,
choices: CONFIG.DH.GENERAL.countdownTypes,
initial: CONFIG.DH.GENERAL.countdownTypes.encounter.id,
label: 'DAGGERHEART.GENERAL.type'
}),
name: new fields.StringField({
required: true,
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.name.label'
}),
img: new fields.FilePathField({
categories: ['IMAGE'],
base64: false,
initial: 'icons/magic/time/hourglass-yellow-green.webp'
}),
ownership: new fields.TypedObjectField(
new fields.NumberField({
required: true,
choices: CONFIG.DH.GENERAL.simpleOwnershiplevels,
initial: CONST.DOCUMENT_OWNERSHIP_LEVELS.INHERIT
})
),
progress: new fields.SchemaField({
current: new fields.NumberField({
required: true,
integer: true,
initial: 1,
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.current.label'
}),
start: new fields.NumberField({
required: true,
integer: true,
initial: 1,
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.start.label',
deterministic: false
}),
startFormula: new FormulaField({
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.startFormula.label',
deterministic: false
}),
looping: new fields.StringField({
required: true,
choices: CONFIG.DH.GENERAL.countdownLoopingTypes,
initial: CONFIG.DH.GENERAL.countdownLoopingTypes.noLooping.id,
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.looping.label'
}),
type: new fields.StringField({
required: true,
choices: CONFIG.DH.GENERAL.countdownProgressionTypes,
initial: CONFIG.DH.GENERAL.countdownProgressionTypes.custom.id,
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.type.label'
})
})
};
}
static defaultCountdown(type, playerHidden) {
const ownership = playerHidden
? game.users.reduce((acc, user) => {
if (!user.isGM) {
acc[user.id] = CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE;
}
return acc;
}, {})
: undefined;
return {
type: type ?? CONFIG.DH.GENERAL.countdownTypes.encounter.id,
name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Countdown.newCountdown'),
img: 'icons/magic/time/hourglass-yellow-green.webp',
ownership: ownership,
progress: {
current: 1,
start: 1
}
};
}
get playerOwnership() {
return Array.from(game.users).reduce((acc, user) => {
acc[user.id] = {
value: user.isGM
? CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER
: this.ownership.players[user.id] && this.ownership.players[user.id].type !== -1
? this.ownership.players[user.id].type
: this.ownership.default,
isGM: user.isGM
};
return acc;
}, {});
}
/** @inheritDoc */
static migrateData(source) {
if (source.progress.max) {
source.progress.start = Number(source.progress.max);
source.progress.max = null;
source.progress.startFormula = null;
}
return super.migrateData(source);
}
}