mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-13 04:01:06 +01:00
.
This commit is contained in:
parent
4b76223e45
commit
de9a66e1bc
36 changed files with 328 additions and 116 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { DhCountdown } from '../../data/countdowns.mjs';
|
||||
import { waitForDiceSoNice } from '../../helpers/utils.mjs';
|
||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
|
@ -26,6 +27,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
|||
toggleCountdownEdit: CountdownEdit.#toggleCountdownEdit,
|
||||
editCountdownImage: CountdownEdit.#editCountdownImage,
|
||||
editCountdownOwnership: CountdownEdit.#editCountdownOwnership,
|
||||
randomiseCountdownStart: CountdownEdit.#randomiseCountdownStart,
|
||||
removeCountdown: CountdownEdit.#removeCountdown
|
||||
},
|
||||
form: { handler: this.updateData, submitOnChange: true }
|
||||
|
|
@ -57,6 +59,9 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
|||
? 'DAGGERHEART.UI.Countdowns.decreasingLoop'
|
||||
: 'DAGGERHEART.UI.Countdowns.loop'
|
||||
: null;
|
||||
const randomizeValid = Roll.parse(countdown.progress.startFormula ?? '').some(
|
||||
x => x instanceof foundry.dice.terms.Die
|
||||
);
|
||||
acc[key] = {
|
||||
...countdown,
|
||||
typeName: game.i18n.localize(CONFIG.DH.GENERAL.countdownBaseTypes[countdown.type].label),
|
||||
|
|
@ -67,6 +72,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
|||
)
|
||||
},
|
||||
editing: this.editingCountdowns.has(key),
|
||||
randomizeValid,
|
||||
loopTooltip
|
||||
};
|
||||
|
||||
|
|
@ -123,18 +129,26 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
|||
// Sync current and max if max is changing and they were equal before
|
||||
for (const [id, countdown] of Object.entries(settingsData.countdowns ?? {})) {
|
||||
const existing = this.data.countdowns[id];
|
||||
const wasEqual = existing && existing.progress.current === existing.progress.max;
|
||||
if (wasEqual && countdown.progress.max !== existing.progress.max) {
|
||||
countdown.progress.current = countdown.progress.max;
|
||||
} else {
|
||||
countdown.progress.current = Math.min(countdown.progress.current, countdown.progress.max);
|
||||
}
|
||||
countdown.progress.current = this.getMatchingCurrentValue(
|
||||
existing,
|
||||
countdown.progress.start,
|
||||
countdown.progress.current
|
||||
);
|
||||
}
|
||||
|
||||
this.hideNewCountdowns = hideNewCountdowns;
|
||||
this.updateSetting(settingsData);
|
||||
}
|
||||
|
||||
getMatchingCurrentValue(oldCount, newStart, newCurrent) {
|
||||
const wasEqual = oldCount && oldCount.progress.current === oldCount.progress.start;
|
||||
if (wasEqual && newStart !== oldCount.progress.start) {
|
||||
return newStart;
|
||||
} else {
|
||||
return Math.min(newCurrent, newStart);
|
||||
}
|
||||
}
|
||||
|
||||
async gmSetSetting(data) {
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data),
|
||||
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
|
|
@ -190,6 +204,23 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
|||
this.updateSetting({ [`countdowns.${button.dataset.countdownId}`]: data });
|
||||
}
|
||||
|
||||
static async #randomiseCountdownStart(_, button) {
|
||||
const countdown = this.data.countdowns[button.dataset.countdownId];
|
||||
const roll = await new Roll(countdown.progress.startFormula).roll();
|
||||
const message = await roll.toMessage({ title: 'Countdown' });
|
||||
const update = async () => {
|
||||
await this.updateSetting({
|
||||
[`countdowns.${button.dataset.countdownId}.progress`]: {
|
||||
start: roll.total,
|
||||
current: this.getMatchingCurrentValue(countdown, roll.total, countdown.progress.current)
|
||||
}
|
||||
});
|
||||
this.render();
|
||||
};
|
||||
|
||||
waitForDiceSoNice(message, update);
|
||||
}
|
||||
|
||||
static async #removeCountdown(event, button) {
|
||||
const { countdownId } = button.dataset;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { waitForDiceSoNice } from '../../helpers/utils.mjs';
|
||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../systemRegistration/socket.mjs';
|
||||
|
||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||
|
|
@ -123,13 +124,14 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
: 'DAGGERHEART.UI.Countdowns.loop'
|
||||
: null;
|
||||
const loopDisabled =
|
||||
!countdownEditable || (isLooping && (countdown.progress.current > 0 || countdown.progress.max === '0'));
|
||||
!countdownEditable ||
|
||||
(isLooping && (countdown.progress.current > 0 || countdown.progress.start === '0'));
|
||||
|
||||
acc[key] = {
|
||||
...countdown,
|
||||
editable: countdownEditable,
|
||||
noPlayerAccess: nonGmPlayers.length && playersWithAccess.length === 0,
|
||||
shouldLoop: isLooping && countdown.progress.current === 0 && countdown.progress.max > 0,
|
||||
shouldLoop: isLooping && countdown.progress.current === 0 && countdown.progress.start > 0,
|
||||
loopDisabled: isLooping ? loopDisabled : null,
|
||||
loopTooltip: isLooping && game.i18n.localize(loopTooltip)
|
||||
};
|
||||
|
|
@ -182,21 +184,36 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
|
||||
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
const countdown = settings.countdowns[target.id];
|
||||
|
||||
let progressMax = countdown.progress.start;
|
||||
let message = null;
|
||||
if (countdown.progress.startFormula) {
|
||||
const roll = await new Roll(countdown.progress.startFormula).evaluate();
|
||||
progressMax = roll.total;
|
||||
message = await roll.toMessage();
|
||||
}
|
||||
|
||||
const newMax =
|
||||
countdown.progress.looping === CONFIG.DH.GENERAL.countdownLoopingTypes.increasing.id
|
||||
? Number(countdown.progress.max) + 1
|
||||
? Number(progressMax) + 1
|
||||
: countdown.progress.looping === CONFIG.DH.GENERAL.countdownLoopingTypes.decreasing.id
|
||||
? Math.max(Number(countdown.progress.max) - 1, 0)
|
||||
: countdown.progress.max;
|
||||
await settings.updateSource({
|
||||
[`countdowns.${target.id}.progress`]: {
|
||||
current: newMax,
|
||||
max: newMax
|
||||
}
|
||||
});
|
||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||
refreshType: RefreshType.Countdown
|
||||
});
|
||||
? Math.max(Number(progressMax) - 1, 0)
|
||||
: progressMax;
|
||||
|
||||
const update = async () => {
|
||||
await settings.updateSource({
|
||||
[`countdowns.${target.id}.progress`]: {
|
||||
current: newMax,
|
||||
start: newMax
|
||||
}
|
||||
});
|
||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||
refreshType: RefreshType.Countdown
|
||||
});
|
||||
};
|
||||
|
||||
if (message) waitForDiceSoNice(message, update);
|
||||
else update();
|
||||
}
|
||||
|
||||
static async editCountdown(increase, target) {
|
||||
|
|
@ -205,7 +222,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
const countdown = settings.countdowns[target.id];
|
||||
const newCurrent = increase
|
||||
? Math.min(countdown.progress.current + 1, countdown.progress.max)
|
||||
? Math.min(countdown.progress.current + 1, countdown.progress.start)
|
||||
: Math.max(countdown.progress.current - 1, 0);
|
||||
await settings.updateSource({ [`countdowns.${target.id}.progress.current`]: newCurrent });
|
||||
await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ export default class DhCountdownAction extends DHBaseAction {
|
|||
...super.defaultValues,
|
||||
countdown: {
|
||||
name: this.parent.parent.name,
|
||||
img: this.img
|
||||
img: this.img,
|
||||
progress: {
|
||||
startFormula: '1'
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -21,10 +24,26 @@ export default class DhCountdownAction extends DHBaseAction {
|
|||
{
|
||||
...game.system.api.data.countdowns.DhCountdown.defaultCountdown(),
|
||||
name: parent.parent.name,
|
||||
img: parent.parent.img
|
||||
img: parent.parent.img,
|
||||
progress: {
|
||||
startFormula: '1'
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
return updateSource;
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static migrateData(source) {
|
||||
for (let countdown of source.countdown) {
|
||||
if (countdown.progress.max) {
|
||||
countdown.progress.startFormula = countdown.progress.max;
|
||||
countdown.progress.start = 1;
|
||||
countdown.progress.max = null;
|
||||
}
|
||||
}
|
||||
|
||||
return super.migrateData(source);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -167,10 +167,15 @@ export class DhCountdown extends foundry.abstract.DataModel {
|
|||
initial: 1,
|
||||
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.current.label'
|
||||
}),
|
||||
max: new FormulaField({
|
||||
start: new fields.NumberField({
|
||||
required: true,
|
||||
integer: true,
|
||||
initial: 1,
|
||||
label: 'DAGGERHEART.APPLICATIONS.Countdown.FIELDS.countdowns.element.progress.max.label',
|
||||
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({
|
||||
|
|
@ -206,7 +211,7 @@ export class DhCountdown extends foundry.abstract.DataModel {
|
|||
ownership: ownership,
|
||||
progress: {
|
||||
current: 1,
|
||||
max: 1
|
||||
start: 1
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
@ -225,4 +230,15 @@ export class DhCountdown extends foundry.abstract.DataModel {
|
|||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
static migrateData(source) {
|
||||
if (source.progress.max) {
|
||||
source.progress.startFormula = source.progress.max;
|
||||
source.progress.start = Number(source.progress.max);
|
||||
source.progress.max = null;
|
||||
}
|
||||
|
||||
return super.migrateData(source);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { waitForDiceSoNice } from '../../../helpers/utils.mjs';
|
||||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../../../systemRegistration/socket.mjs';
|
||||
|
||||
const fields = foundry.data.fields;
|
||||
|
|
@ -40,40 +41,69 @@ export default class CountdownField extends fields.ArrayField {
|
|||
}
|
||||
|
||||
const data = { countdowns: {} };
|
||||
const countdownMessages = [];
|
||||
for (let countdown of config.countdowns) {
|
||||
const { total: max } = await new Roll(countdown.progress.max).evaluate();
|
||||
let startFormula = countdown.progress.startFormula ? countdown.progress.startFormula : null;
|
||||
let countdownStart = startFormula ?? '1';
|
||||
if (startFormula) {
|
||||
const roll = await new Roll(startFormula).roll();
|
||||
if (roll.dice.length > 0) {
|
||||
countdownStart = roll.total;
|
||||
const message = await roll.toMessage();
|
||||
countdownMessages.push(message);
|
||||
} else {
|
||||
startFormula = null;
|
||||
}
|
||||
}
|
||||
|
||||
data.countdowns[foundry.utils.randomID()] = {
|
||||
...countdown,
|
||||
progress: {
|
||||
...countdown.progress,
|
||||
current: max,
|
||||
max: max
|
||||
current: countdownStart,
|
||||
start: countdownStart,
|
||||
startFormula
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
await emitAsGM(
|
||||
GMUpdateEvent.UpdateCountdowns,
|
||||
async () => {
|
||||
const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
await countdownSetting.updateSource(data);
|
||||
await game.settings.set(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Countdowns,
|
||||
countdownSetting.toObject()
|
||||
),
|
||||
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
});
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||
},
|
||||
data,
|
||||
null,
|
||||
{
|
||||
refreshType: RefreshType.Countdown
|
||||
}
|
||||
);
|
||||
const update = async () => {
|
||||
await emitAsGM(
|
||||
GMUpdateEvent.UpdateCountdowns,
|
||||
async () => {
|
||||
const countdownSetting = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Countdowns
|
||||
);
|
||||
await countdownSetting.updateSource(data);
|
||||
await game.settings.set(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Countdowns,
|
||||
countdownSetting.toObject()
|
||||
),
|
||||
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
});
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||
},
|
||||
data,
|
||||
null,
|
||||
{
|
||||
refreshType: RefreshType.Countdown
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (game.modules.get('dice-so-nice')?.active) {
|
||||
Promise.all(
|
||||
countdownMessages.map(message => {
|
||||
return game.dice3d.waitFor3DAnimationByMessageID(message.id);
|
||||
})
|
||||
).then(update);
|
||||
} else {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -445,3 +445,11 @@ export function itemIsIdentical(a, b) {
|
|||
|
||||
return compendiumSource && name & description;
|
||||
}
|
||||
|
||||
export function waitForDiceSoNice(message, update) {
|
||||
if (game.modules.get('dice-so-nice')?.active) {
|
||||
game.dice3d.waitFor3DAnimationByMessageID(message.id).then(async () => await update());
|
||||
} else {
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue