Merge branch 'hotfix' into joaquinpereyra98/issue792

This commit is contained in:
Joaquin Pereyra 2025-08-10 15:47:09 -03:00
commit 56f2178876
48 changed files with 550 additions and 377 deletions

View file

@ -359,6 +359,11 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
context.community = { ...this.setup.community, compendium: 'communities' };
context.class = { ...this.setup.class, compendium: 'classes' };
context.subclass = { ...this.setup.subclass, compendium: 'subclasses' };
const allDomainData = CONFIG.DH.DOMAIN.allDomains();
context.classDomains = context.class.uuid
? context.class.system.domains.map(key => game.i18n.localize(allDomainData[key].label))
: [];
context.domainCards = Object.keys(this.setup.domainCards).reduce((acc, x) => {
acc[x] = { ...this.setup.domainCards[x], compendium: 'domains' };
return acc;

View file

@ -419,7 +419,7 @@ export default function DHApplicationMixin(Base) {
: this.document.system.actions?.get(actionId);
if (!doc) return;
const description = doc.system?.description ?? doc.description;
const description = game.i18n.localize(doc.system?.description ?? doc.description);
const isAction = !!actionId;
descriptionElement.innerHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(
description,

View file

@ -183,11 +183,11 @@ export const conditions = {
icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp',
description: 'DAGGERHEART.CONFIG.Condition.restrained.description'
},
unconcious: {
id: 'unconcious',
name: 'DAGGERHEART.CONFIG.Condition.unconcious.name',
unconscious: {
id: 'unconscious',
name: 'DAGGERHEART.CONFIG.Condition.unconscious.name',
icon: 'icons/magic/control/sleep-bubble-purple.webp',
description: 'DAGGERHEART.CONFIG.Condition.unconcious.description'
description: 'DAGGERHEART.CONFIG.Condition.unconscious.description'
},
dead: {
id: 'dead',
@ -533,6 +533,10 @@ export const getDiceSoNicePresets = async (hopeFaces, fearFaces, advantageFaces
};
export const refreshTypes = {
scene: {
id: 'session',
label: 'DAGGERHEART.GENERAL.RefreshType.scene'
},
session: {
id: 'session',
label: 'DAGGERHEART.GENERAL.RefreshType.session'

View file

@ -780,7 +780,15 @@ export const weaponFeatures = {
mode: 2,
value: '1'
}
]
],
system: {
rangeDependence: {
enabled: true,
range: 'melee',
target: 'hostile',
type: 'withinRange'
}
}
}
]
},
@ -1079,7 +1087,15 @@ export const weaponFeatures = {
mode: 2,
value: '2'
}
]
],
system: {
rangeDependence: {
enabled: true,
range: 'melee',
target: 'hostile',
type: 'withinRange'
}
}
}
]
},
@ -1208,7 +1224,7 @@ export const weaponFeatures = {
img: 'icons/skills/melee/strike-sword-slashing-red.webp',
changes: [
{
key: 'system.bonuses.roll.primaryWeapon.attack',
key: 'system.bonuses.roll.primaryWeapon.bonus',
mode: 2,
value: 1
}

View file

@ -208,7 +208,14 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
}
async consume(config, successCost = false) {
const usefulResources = foundry.utils.deepClone(this.actor.system.resources);
const usefulResources = {
...foundry.utils.deepClone(this.actor.system.resources),
fear: {
value: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear),
max: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear,
reversed: false
}
};
for (var cost of config.costs) {
if (cost.keyIsID) {

View file

@ -32,7 +32,7 @@ export default class BeastformEffect extends BaseEffect {
if (this.parent.parent?.type === 'character') {
this.parent.parent.system.primaryWeapon?.update?.({ 'system.equipped': false });
this.parent.parent.system.secondayWeapon?.update?.({ 'system.equipped': false });
this.parent.parent.system.secondaryWeapon?.update?.({ 'system.equipped': false });
}
}

View file

@ -60,7 +60,7 @@ export default class DHArmor extends AttachableItem {
const allowed = await super._preUpdate(changes, options, user);
if (allowed === false) return false;
if (changes.system.armorFeatures) {
if (changes.system?.armorFeatures) {
const removed = this.armorFeatures.filter(x => !changes.system.armorFeatures.includes(x));
const added = changes.system.armorFeatures.filter(x => !this.armorFeatures.includes(x));

View file

@ -60,6 +60,17 @@ export default class DHClass extends BaseDataItem {
/* -------------------------------------------- */
get domainData() {
const allDomainData = CONFIG.DH.DOMAIN.allDomains();
return this.domains.map(key => {
const domain = allDomainData[key];
return {
...domain,
label: game.i18n.localize(domain.label)
};
});
}
get hopeFeatures() {
return this.features.filter(x => x.type === CONFIG.DH.ITEM.featureSubTypes.hope).map(x => x.item);
}

View file

@ -33,6 +33,11 @@ export default class DHDomainCard extends BaseDataItem {
};
}
get domainLabel() {
const allDomainData = CONFIG.DH.DOMAIN.allDomains();
return game.i18n.localize(allDomainData[this.domain].label);
}
/* -------------------------------------------- */
/**@override */
@ -71,7 +76,7 @@ export default class DHDomainCard extends BaseDataItem {
_getTags() {
const tags = [
game.i18n.localize(`DAGGERHEART.CONFIG.DomainCardTypes.${this.type}`),
game.i18n.localize(`DAGGERHEART.GENERAL.Domain.${this.domain}.label`),
this.domainLabel,
`${game.i18n.localize('DAGGERHEART.ITEMS.DomainCard.recallCost')}: ${this.recallCost}`
];
@ -85,7 +90,7 @@ export default class DHDomainCard extends BaseDataItem {
_getLabels() {
const labels = [
game.i18n.localize(`DAGGERHEART.CONFIG.DomainCardTypes.${this.type}`),
game.i18n.localize(`DAGGERHEART.GENERAL.Domain.${this.domain}.label`),
this.domainLabel,
{
value: `${this.recallCost}`, //converts the number to a string
icons: ['fa-bolt']

View file

@ -159,25 +159,28 @@ export default class DamageRoll extends DHRoll {
if (config.data?.parent) {
if (config.data.parent.appliedEffects) {
// Bardic Rally
mods.rally = {
label: 'DAGGERHEART.CLASS.Feature.rallyDice',
values: config.data?.parent?.appliedEffects.reduce((a, c) => {
const rallyChoices = config.data?.parent?.appliedEffects.reduce((a, c) => {
const change = c.changes.find(ch => ch.key === 'system.bonuses.rally');
if (change) a.push({ value: c.id, label: change.value });
return a;
}, []),
value: null,
beforeCrit: true,
callback: part => {
const rallyFaces = config.modifiers.rally.values.find(
r => r.value === config.modifiers.rally.value
)?.label;
part.roll.terms.push(
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
...this.parse(`1${rallyFaces}`)
);
}
};
}, [])
if(rallyChoices.length) {
mods.rally = {
label: 'DAGGERHEART.CLASS.Feature.rallyDice',
values: rallyChoices,
value: null,
beforeCrit: true,
callback: part => {
const rallyFaces = config.modifiers.rally.values.find(
r => r.value === config.modifiers.rally.value
)?.label;
part.roll.terms.push(
new foundry.dice.terms.OperatorTerm({ operator: '+' }),
...this.parse(`1${rallyFaces}`)
);
}
};
}
}
const item = config.data.parent.items?.get(config.source.item);

View file

@ -238,7 +238,7 @@ export const registerRollDiceHooks = () => {
if (updates.length) {
const target = actor.system.partner ?? actor;
if (!['dead', 'unconcious'].some(x => actor.statuses.has(x))) {
if (!['dead', 'unconscious'].some(x => actor.statuses.has(x))) {
setTimeout(() => {
target.modifyResource(updates);
}, 50);

View file

@ -69,6 +69,11 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage {
break;
}
}
if(!game.user.isGM && !this.isAuthor && !this.speakerActor?.isOwner) {
const buttons = html.querySelectorAll(".ability-card-footer > .ability-use-button");
buttons.forEach(b => b.remove());
}
}
addChatListeners(html) {

View file

@ -60,7 +60,7 @@ export default class RegisterHandlebarsHelpers {
static rollParsed(value, actor, item, numerical) {
const isNumerical = typeof numerical === 'boolean' ? numerical : false;
const result = itemAbleRollParse(value, actor.getRollData(), item);
const result = itemAbleRollParse(value, actor?.getRollData() ?? {}, item);
return isNumerical ? (!result ? 0 : Number(result)) : result;
}
@ -69,7 +69,7 @@ export default class RegisterHandlebarsHelpers {
}
static empty(object) {
if(!(typeof object === 'object')) return true;
if (!(typeof object === 'object')) return true;
return Object.keys(object).length === 0;
}
}

View file

@ -85,7 +85,13 @@ export const chunkify = (array, chunkSize, mappingFunc) => {
export const tagifyElement = (element, baseOptions, onChange, tagifyOptions = {}) => {
const { maxTags } = tagifyOptions;
const options = typeof baseOptions === 'object' ? Object.values(baseOptions) : baseOptions;
const options =
typeof baseOptions === 'object'
? Object.keys(baseOptions).map(optionKey => ({
...baseOptions[optionKey],
id: optionKey
}))
: baseOptions;
const tagifyElement = new Tagify(element, {
tagTextProp: 'name',