mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-22 15:33:37 +02:00
Merged with v14-Dev
This commit is contained in:
commit
8d84b8da48
70 changed files with 1076 additions and 936 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import { itemAbleRollParse } from '../helpers/utils.mjs';
|
||||
import { RefreshType } from '../systemRegistration/socket.mjs';
|
||||
|
||||
export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -111,37 +110,41 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
update.img = 'icons/magic/life/heart-cross-blue.webp';
|
||||
}
|
||||
|
||||
const existingEffect = this.actor.effects.find(x => x.origin === data.origin);
|
||||
const stacks = Boolean(data.system?.stacking);
|
||||
if (existingEffect && !stacks) return false;
|
||||
if (this.actor && data.origin) {
|
||||
const existingEffect = this.actor.effects.find(x => x.origin === data.origin);
|
||||
const stacks = Boolean(data.system?.stacking);
|
||||
if (existingEffect && !stacks) return false;
|
||||
|
||||
if (existingEffect && stacks) {
|
||||
const incrementedValue = existingEffect.system.stacking.value + 1;
|
||||
await existingEffect.update({
|
||||
'system.stacking.value': Math.min(incrementedValue, existingEffect.system.stacking.max ?? Infinity)
|
||||
});
|
||||
return false;
|
||||
if (existingEffect && stacks) {
|
||||
const incrementedValue = existingEffect.system.stacking.value + 1;
|
||||
await existingEffect.update({
|
||||
'system.stacking.value': Math.min(incrementedValue, existingEffect.system.stacking.max ?? Infinity)
|
||||
});
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const statuses = Object.keys(data.statuses ?? {});
|
||||
const immuneStatuses =
|
||||
statuses.filter(
|
||||
status =>
|
||||
this.parent.system.rules?.conditionImmunities &&
|
||||
this.parent.system.rules.conditionImmunities[status]
|
||||
) ?? [];
|
||||
if (immuneStatuses.length > 0) {
|
||||
update.statuses = statuses.filter(x => !immuneStatuses.includes(x));
|
||||
const conditions = CONFIG.DH.GENERAL.conditions();
|
||||
const scrollingTexts = immuneStatuses.map(status => ({
|
||||
text: game.i18n.format('DAGGERHEART.ACTIVEEFFECT.immuneStatusText', {
|
||||
status: game.i18n.localize(conditions[status].name)
|
||||
})
|
||||
}));
|
||||
if (update.statuses.length > 0) {
|
||||
setTimeout(() => scrollingTexts, 500);
|
||||
} else {
|
||||
this.parent.queueScrollText(scrollingTexts);
|
||||
if (this.parent) {
|
||||
const statuses = Object.keys(data.statuses ?? {});
|
||||
const immuneStatuses =
|
||||
statuses.filter(
|
||||
status =>
|
||||
this.parent.system.rules?.conditionImmunities &&
|
||||
this.parent.system.rules.conditionImmunities[status]
|
||||
) ?? [];
|
||||
if (immuneStatuses.length > 0) {
|
||||
update.statuses = statuses.filter(x => !immuneStatuses.includes(x));
|
||||
const conditions = CONFIG.DH.GENERAL.conditions();
|
||||
const scrollingTexts = immuneStatuses.map(status => ({
|
||||
text: game.i18n.format('DAGGERHEART.ACTIVEEFFECT.immuneStatusText', {
|
||||
status: game.i18n.localize(conditions[status].name)
|
||||
})
|
||||
}));
|
||||
if (update.statuses.length > 0) {
|
||||
setTimeout(() => scrollingTexts, 500);
|
||||
} else {
|
||||
this.parent.queueScrollText(scrollingTexts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -152,20 +155,6 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
|||
await super._preCreate(data, options, user);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
_onCreate(data, options, userId) {
|
||||
super._onCreate(data, options, userId);
|
||||
|
||||
Hooks.callAll(RefreshType.EffectsDisplay);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
_onDelete(data, options, userId) {
|
||||
super._onDelete(data, options, userId);
|
||||
|
||||
Hooks.callAll(RefreshType.EffectsDisplay);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Methods */
|
||||
/* -------------------------------------------- */
|
||||
|
|
|
|||
|
|
@ -30,6 +30,18 @@ export default class DhpActor extends Actor {
|
|||
return this.system.metadata.isNPC;
|
||||
}
|
||||
|
||||
prepareData() {
|
||||
super.prepareData();
|
||||
|
||||
// Update effects if it is the user's character or is controlled
|
||||
if (canvas.ready) {
|
||||
const controlled = canvas.tokens.controlled.some(t => t.actor === this);
|
||||
if (game.user.character === this || controlled) {
|
||||
ui.effectsDisplay.render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/** @inheritDoc */
|
||||
|
|
@ -122,14 +134,6 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
}
|
||||
|
||||
_onUpdateDescendantDocuments(parent, collection, documents, changes, options, userId) {
|
||||
if (collection === 'effects') {
|
||||
ui.effectsDisplay.render();
|
||||
}
|
||||
|
||||
super._onUpdateDescendantDocuments(parent, collection, documents, changes, options, userId);
|
||||
}
|
||||
|
||||
async updateLevel(newLevel) {
|
||||
if (!['character', 'companion'].includes(this.type) || newLevel === this.system.levelData.level.changed) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { emitAsGM, GMUpdateEvent, RefreshType, socketEvent } from '../systemRegistration/socket.mjs';
|
||||
import { emitAsGM, GMUpdateEvent } from '../systemRegistration/socket.mjs';
|
||||
|
||||
export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
||||
targetHook = null;
|
||||
|
|
@ -78,25 +78,14 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
|
|||
if (this.isContentVisible) {
|
||||
if (this.type === 'dualityRoll') {
|
||||
html.classList.add('duality');
|
||||
switch (this.system.roll?.result?.duality) {
|
||||
case 1:
|
||||
html.classList.add('hope');
|
||||
break;
|
||||
case -1:
|
||||
html.classList.add('fear');
|
||||
break;
|
||||
default:
|
||||
html.classList.add('critical');
|
||||
break;
|
||||
}
|
||||
if (this.system.roll.withHope) html.classList.add('hope');
|
||||
else if (this.system.roll.withFear) html.classList.add('fear');
|
||||
else html.classList.add('critical');
|
||||
}
|
||||
if (this.type === 'fateRoll') {
|
||||
html.classList.add('fate');
|
||||
if (this.system.roll?.fate.fateDie == 'Hope') {
|
||||
html.classList.add('hope');
|
||||
}
|
||||
if (this.system.roll?.fate.fateDie == 'Fear') {
|
||||
html.classList.add('fear');
|
||||
if (this.system.roll?.fateDie) {
|
||||
html.classList.add(this.system.roll.fateDie.toLowerCase());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -197,7 +197,6 @@ export default class DHItem extends foundry.documents.Item {
|
|||
actor: item.parent,
|
||||
speaker: cls.getSpeaker(),
|
||||
system: systemData,
|
||||
title: game.i18n.localize('DAGGERHEART.ACTIONS.Config.displayInChat'),
|
||||
content: await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/ui/chat/ability-use.hbs',
|
||||
systemData
|
||||
|
|
|
|||
|
|
@ -494,62 +494,4 @@ export default class DHToken extends CONFIG.Token.documentClass {
|
|||
game.system.registeredTriggers.unregisterItemTriggers(this.actor.items);
|
||||
}
|
||||
}
|
||||
|
||||
/* V14 TEMP until foundry fixes: https://discord.com/channels/170995199584108546/1421197211194228907/1467296028700049566 */
|
||||
_onRelatedUpdate(update = {}, operation = {}) {
|
||||
this.#refreshOverrides(operation);
|
||||
this._prepareBars();
|
||||
|
||||
// Update tracked Combat resource
|
||||
const combatant = this.combatant;
|
||||
if (combatant) {
|
||||
const isActorUpdate = [this, null, undefined].includes(operation.parent);
|
||||
const resource = game.combat.settings.resource;
|
||||
const updates = Array.isArray(update) ? update : [update];
|
||||
if (isActorUpdate && resource && updates.some(u => foundry.utils.hasProperty(u.system ?? {}, resource))) {
|
||||
combatant.updateResource();
|
||||
}
|
||||
ui.combat.render();
|
||||
}
|
||||
|
||||
// Trigger redraws on the token
|
||||
if (this.parent.isView) {
|
||||
if (this.object?.hasActiveHUD) canvas.tokens.hud.render();
|
||||
this.object?.renderFlags.set({ redrawEffects: true });
|
||||
for (const key of ['bar1', 'bar2']) {
|
||||
const name = `${this.object?.objectId}.animate${key.capitalize()}`;
|
||||
const easing = foundry.canvas.animation.CanvasAnimation.easeInOutCosine;
|
||||
this.object?.animate({ [key]: this[key] }, { name, easing });
|
||||
}
|
||||
for (const app of foundry.applications.sheets.TokenConfig.instances()) {
|
||||
app._preview?.updateSource({ delta: this.toObject().delta }, { diff: false, recursive: false });
|
||||
app._preview?.object?.renderFlags.set({ refreshBars: true, redrawEffects: true });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* V14 TEMP until foundry fixes: https://discord.com/channels/170995199584108546/1421197211194228907/1467296028700049566 */
|
||||
#refreshOverrides(operation) {
|
||||
if (!this.actor) return;
|
||||
|
||||
const { deepClone, mergeObject, equals, isEmpty } = foundry.utils;
|
||||
const oldOverrides = deepClone(this._overrides) ?? {};
|
||||
const newOverrides = deepClone(this.actor?.tokenOverrides ?? {}, { prune: true });
|
||||
if (!equals(oldOverrides, newOverrides)) {
|
||||
this._overrides = newOverrides;
|
||||
this.reset();
|
||||
|
||||
// Send emulated update data to the PlaceableObject
|
||||
if (!canvas.ready || canvas.scene !== this.scene) return;
|
||||
const { width, height, depth, ...changes } = mergeObject(
|
||||
mergeObject(oldOverrides, this, { insertKeys: false, insertValues: false }),
|
||||
this._overrides
|
||||
);
|
||||
this.object?._onUpdate(changes, {}, game.user.id);
|
||||
|
||||
// Hand off size changes to a secondary handler requiring downstream implementation.
|
||||
const sizeChanges = deepClone({ width, height, depth }, { prune: true });
|
||||
if (!isEmpty(sizeChanges)) this._onOverrideSize(sizeChanges, operation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,12 +31,39 @@ export default class DhTooltipManager extends foundry.helpers.interaction.Toolti
|
|||
this.#bordered = true;
|
||||
let effect = {};
|
||||
if (element.dataset.uuid) {
|
||||
const effectData = (await foundry.utils.fromUuid(element.dataset.uuid)).toObject();
|
||||
const effectItem = await foundry.utils.fromUuid(element.dataset.uuid);
|
||||
const effectData = effectItem.toObject();
|
||||
|
||||
effect = {
|
||||
...effectData,
|
||||
name: game.i18n.localize(effectData.name),
|
||||
description: game.i18n.localize(effectData.description ?? effectData.parent.system.description)
|
||||
name: game.i18n.localize(effectData.name)
|
||||
};
|
||||
|
||||
if (effectData.type === 'beastform') {
|
||||
const beastformData = {
|
||||
features: [],
|
||||
advantageOn: effectData.system.advantageOn,
|
||||
beastformAttackData: game.system.api.data.items.DHBeastform.getBeastformAttackData(effectItem)
|
||||
};
|
||||
|
||||
const features = effectItem.parent.items.filter(x => effectItem.system.featureIds.includes(x.id));
|
||||
for (const feature of features) {
|
||||
const featureData = feature.toObject();
|
||||
featureData.enrichedDescription = await feature.system.getEnrichedDescription();
|
||||
beastformData.features.push(featureData);
|
||||
}
|
||||
|
||||
effect.description = await foundry.applications.handlebars.renderTemplate(
|
||||
'systems/daggerheart/templates/ui/tooltip/parts/beastformData.hbs',
|
||||
{
|
||||
item: { system: beastformData }
|
||||
}
|
||||
);
|
||||
} else {
|
||||
effect.description = game.i18n.localize(
|
||||
effectData.description ?? effectData.parent.system.description
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const conditions = CONFIG.DH.GENERAL.conditions();
|
||||
const condition = conditions[element.dataset.condition];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue