mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-07-22 18:39:55 +02:00
Merge branch 'main' into feature/enhance-fear-tracker
This commit is contained in:
commit
5e28d34729
76 changed files with 1641 additions and 1058 deletions
|
|
@ -111,7 +111,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
const message = game.messages.get(li.dataset.messageId);
|
||||
return message.system.hasRoll && (game.user.isGM || message.isAuthor);
|
||||
},
|
||||
callback: async li => {
|
||||
onClick: async (_event, li) => {
|
||||
const message = game.messages.get(li.dataset.messageId);
|
||||
const reroll = await message.rolls[0].reroll({ liveRoll: true });
|
||||
message.update({ rolls: [reroll] });
|
||||
|
|
@ -127,7 +127,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
: false;
|
||||
return (game.user.isGM || message.isAuthor) && hasRolledDamage;
|
||||
},
|
||||
callback: async li => {
|
||||
onClick: async (_event, li) => {
|
||||
const message = game.messages.get(li.dataset.messageId);
|
||||
const update = await message.system.getRerolledDamage();
|
||||
message.update(update);
|
||||
|
|
@ -153,6 +153,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
html.querySelectorAll('.risk-it-all-button').forEach(element =>
|
||||
element.addEventListener('click', event => this.riskItAllClearStressAndHitPoints(event, data))
|
||||
);
|
||||
for (const element of html.querySelectorAll('.roll-reload-check')) {
|
||||
element.addEventListener('click', event => this.onRollReloadCheck(event, message));
|
||||
}
|
||||
};
|
||||
|
||||
setupHooks() {
|
||||
|
|
@ -180,28 +183,15 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
}
|
||||
|
||||
async onRollSimple(event, message) {
|
||||
const buttonType = event.target.dataset.type ?? 'damage',
|
||||
total = message.rolls.reduce((a, c) => a + Roll.fromJSON(c).total, 0),
|
||||
damages = {
|
||||
hitPoints: {
|
||||
parts: [
|
||||
{
|
||||
applyTo: 'hitPoints',
|
||||
damageTypes: [],
|
||||
total
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
targets = Array.from(game.user.targets);
|
||||
|
||||
const buttonType = event.target.dataset.type ?? 'damage';
|
||||
const total = message.rolls.reduce((a, c) => a + Roll.fromJSON(c).total, 0);
|
||||
const targets = Array.from(game.user.targets);
|
||||
if (targets.length === 0)
|
||||
return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected'));
|
||||
|
||||
targets.forEach(target => {
|
||||
if (buttonType === 'healing') target.actor.takeHealing(damages);
|
||||
else target.actor.takeDamage(damages);
|
||||
});
|
||||
for (const target of targets) {
|
||||
if (buttonType === 'healing') target.actor.takeHealing({ hitPoints: total });
|
||||
else target.actor.takeDamage({ total });
|
||||
}
|
||||
}
|
||||
|
||||
async abilityUseButton(event, message) {
|
||||
|
|
@ -257,26 +247,17 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
}
|
||||
|
||||
const message = game.messages.get(messageData._id);
|
||||
const target = event.target.closest('[data-die-index]');
|
||||
const target = event.target.closest('[data-result]');
|
||||
|
||||
if (target.dataset.type === 'damage') {
|
||||
const { damageType, part, dice, result } = target.dataset;
|
||||
const damagePart = message.system.damage[damageType].parts[part];
|
||||
const { parsedRoll, rerolledDice } = await game.system.api.dice.DamageRoll.reroll(damagePart, dice, result);
|
||||
const damageParts = message.system.damage[damageType].parts.map((damagePart, index) => {
|
||||
if (index !== Number(part)) return damagePart;
|
||||
return {
|
||||
...damagePart,
|
||||
total: parsedRoll.total,
|
||||
dice: rerolledDice
|
||||
};
|
||||
});
|
||||
const updateMessage = game.messages.get(message._id);
|
||||
await updateMessage.update({
|
||||
[`system.damage.${damageType}`]: {
|
||||
total: parsedRoll.total,
|
||||
parts: damageParts
|
||||
}
|
||||
const { isResource, damageType, dice, result } = target.dataset;
|
||||
await message.system.damage.rerollDamageDie(isResource, damageType, dice, result);
|
||||
|
||||
const updatePath = isResource ? `system.damage.resources.${damageType}` : 'system.damage.main';
|
||||
const updateValue = isResource ?
|
||||
message.system.damage.resources[damageType] : message.system.damage.main;
|
||||
await message.update({
|
||||
[updatePath]: updateValue.toJSON()
|
||||
});
|
||||
} else {
|
||||
const rerollDice = message.system.roll.dice[target.dataset.dieIndex];
|
||||
|
|
@ -303,4 +284,10 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
super._toggleNotifications(closing)
|
||||
FearTracker.handleOffSet();
|
||||
}
|
||||
|
||||
async onRollReloadCheck(_event, messageData) {
|
||||
const message = game.messages.get(messageData._id);
|
||||
const needsReload = await message.system.action.handleReload?.({ awaitRoll: true });
|
||||
await message.update({ 'system.needsReload': needsReload });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,6 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
|||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
});
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||
}
|
||||
|
||||
static #addCountdown() {
|
||||
|
|
|
|||
|
|
@ -12,14 +12,11 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
|||
|
||||
export default class DhCountdowns extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
previousCountdownData = null;
|
||||
changedCountdownsForAnimation = new Set();
|
||||
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
|
||||
this.previousCountdownData =
|
||||
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns).countdowns;
|
||||
this.setupHooks();
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
|
|
@ -80,7 +77,15 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
return frame;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
async _onFirstRender(context, options) {
|
||||
await super._onFirstRender(context, options);
|
||||
this._createContextMenu(this._getCountdownContextOptions, '.countdown-container[data-countdown]', {
|
||||
parentClassHooks: false, fixed: true
|
||||
});
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
|
||||
|
|
@ -95,7 +100,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
|
||||
/* Handle animations to draw attention to countdown values changing */
|
||||
const typesToAnimate = new Set();
|
||||
for (const countdownKey of this.changedCountdownsForAnimation) {
|
||||
for (const countdownKey of options.animate ?? []) {
|
||||
const shimmerAnimation = [
|
||||
{ backgroundPositionX: '98%' },
|
||||
{ backgroundPositionX: '0%' }
|
||||
|
|
@ -127,8 +132,6 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
const element = this.element.querySelector(`.header-type-toggles .header-type[data-type="${type}"]`);
|
||||
element?.animate(pulseAnimation, pulseTiming);
|
||||
}
|
||||
|
||||
this.changedCountdownsForAnimation.clear();
|
||||
}
|
||||
|
||||
/** Returns countdown data filtered by ownership */
|
||||
|
|
@ -137,17 +140,15 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
const values = Object.entries(setting.countdowns).map(([key, countdown]) => ({
|
||||
key,
|
||||
countdown,
|
||||
ownership: DhCountdowns.#getPlayerOwnership(game.user, setting, countdown)
|
||||
ownership: countdown.getUserLevel(game.user)
|
||||
}));
|
||||
return values.filter(v => v.ownership !== CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE);
|
||||
}
|
||||
|
||||
_getCountdownData() {
|
||||
const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
|
||||
return this.#getCountdowns().reduce((acc, { key, countdown, ownership }) => {
|
||||
const playersWithAccess = game.users.reduce((acc, user) => {
|
||||
const ownership = DhCountdowns.#getPlayerOwnership(user, setting, countdown);
|
||||
const ownership = countdown.getUserLevel(user);
|
||||
if (!user.isGM && ownership && ownership !== CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE) {
|
||||
acc.push(user);
|
||||
}
|
||||
|
|
@ -213,19 +214,6 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
return context;
|
||||
}
|
||||
|
||||
static #getPlayerOwnership(user, setting, countdown) {
|
||||
if (user.isGM) return CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER;
|
||||
|
||||
const playerOwnership = countdown.ownership[user.id];
|
||||
return playerOwnership === undefined || playerOwnership === CONST.DOCUMENT_OWNERSHIP_LEVELS.INHERIT
|
||||
? setting.defaultOwnership
|
||||
: playerOwnership;
|
||||
}
|
||||
|
||||
cooldownRefresh = ({ refreshType }) => {
|
||||
if (refreshType === RefreshType.Countdown) this.render();
|
||||
};
|
||||
|
||||
static canPerformEdit() {
|
||||
if (game.user.isGM) return true;
|
||||
|
||||
|
|
@ -323,18 +311,12 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
});
|
||||
Hooks.callAll(socketEvent.Refresh, { refreshType: RefreshType.Countdown });
|
||||
}
|
||||
|
||||
setupHooks() {
|
||||
Hooks.on(socketEvent.Refresh, this.cooldownRefresh.bind());
|
||||
}
|
||||
|
||||
async close(options) {
|
||||
/* Opt out of Foundry's standard behavior of closing all application windows marked as UI when Escape is pressed */
|
||||
if (options.closeKey) return;
|
||||
|
||||
Hooks.off(socketEvent.Refresh, this.cooldownRefresh);
|
||||
return super.close(options);
|
||||
}
|
||||
|
||||
|
|
@ -377,4 +359,30 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
refreshType: RefreshType.Countdown
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]}
|
||||
*/
|
||||
_getCountdownContextOptions() {
|
||||
/** @param {HTMLElement} element */
|
||||
const getCountdownFromElement = element => {
|
||||
const id = element.closest('[data-countdown]').dataset.countdown;
|
||||
if (!id) return null;
|
||||
const setting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
return setting.countdowns[id ?? ''];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'CONTROLS.CommonDelete',
|
||||
icon: 'fa-solid fa-trash',
|
||||
visible: element => {
|
||||
return getCountdownFromElement(element)?.isOwner;
|
||||
},
|
||||
onClick: (_, target) => {
|
||||
getCountdownFromElement(target)?.delete();
|
||||
}
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue