Merged with main

This commit is contained in:
WBHarry 2025-06-20 13:06:16 +02:00
commit f80244a773
199 changed files with 8977 additions and 6490 deletions

View file

@ -9,49 +9,56 @@ import { registerDHSettings } from './module/applications/settings.mjs';
import DhpChatLog from './module/ui/chatLog.mjs';
import DhpRuler from './module/ui/ruler.mjs';
import DhpTokenRuler from './module/ui/tokenRuler.mjs';
import { dualityRollEnricher } from './module/enrichers/DualityRollEnricher.mjs';
import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs';
import { getCommandTarget, rollCommandToJSON, setDiceSoNiceForDualityRoll } from './module/helpers/utils.mjs';
import { abilities } from './module/config/actorConfig.mjs';
import Resources from './module/applications/resources.mjs';
import Countdowns from './module/applications/countdowns.mjs';
import DhCountdowns from './module/data/countdowns.mjs';
import DHDualityRoll from './module/data/chat-message/dualityRoll.mjs';
import { DualityRollColor } from './module/data/settings/Appearance.mjs';
import { DhMeasuredTemplate } from './module/placeables/_module.mjs';
import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs';
import { renderMeasuredTemplate } from './module/enrichers/TemplateEnricher.mjs';
globalThis.SYSTEM = SYSTEM;
Hooks.once('init', () => {
CONFIG.daggerheart = SYSTEM;
game.system.api = {
applications,
models,
documents
};
CONFIG.TextEditor.enrichers.push({
pattern: /\[\[\/dr\s?(.*?)\]\]/g,
enricher: dualityRollEnricher
});
CONFIG.TextEditor.enrichers.push(
...[
{
pattern: /\[\[\/dr\s?(.*?)\]\]/g,
enricher: DhDualityRollEnricher
},
{
pattern: /^@Template\[(.*)\]$/g,
enricher: DhTemplateEnricher
}
]
);
CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({
...x,
name: game.i18n.localize(x.name)
}));
CONFIG.MeasuredTemplate.objectClass = DhMeasuredTemplate;
CONFIG.Item.documentClass = documents.DhpItem;
CONFIG.Item.dataModels = {
ancestry: models.DhpAncestry,
community: models.DhpCommunity,
class: models.DhpClass,
subclass: models.DhpSubclass,
feature: models.DhpFeature,
domainCard: models.DhpDomainCard,
miscellaneous: models.DhpMiscellaneous,
consumable: models.DhpConsumable,
weapon: models.DhpWeapon,
armor: models.DhpArmor
};
//Registering the Item DataModel
CONFIG.Item.dataModels = models.items.config;
const { Items, Actors } = foundry.documents.collections;
Items.unregisterSheet('core', foundry.appv1.sheets.ItemSheet);
Items.unregisterSheet('core', foundry.applications.sheets.ItemSheetV2);
Items.registerSheet(SYSTEM.id, applications.DhpAncestry, { types: ['ancestry'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpCommunity, { types: ['community'], makeDefault: true });
Items.registerSheet(SYSTEM.id, applications.DhpClassSheet, { types: ['class'], makeDefault: true });
@ -64,16 +71,28 @@ Hooks.once('init', () => {
Items.registerSheet(SYSTEM.id, applications.DhpArmor, { types: ['armor'], makeDefault: true });
CONFIG.Actor.documentClass = documents.DhpActor;
CONFIG.Actor.dataModels = {
pc: models.DhpPC,
adversary: models.DhpAdversary,
environment: models.DhpEnvironment
};
Actors.unregisterSheet('core', foundry.appv1.sheets.ActorSheet);
Actors.registerSheet(SYSTEM.id, applications.DhpPCSheet, { types: ['pc'], makeDefault: true });
CONFIG.Actor.dataModels = models.actors.config;
Actors.unregisterSheet('core', foundry.applications.sheets.ActorSheetV2);
Actors.registerSheet(SYSTEM.id, applications.DhCharacterSheet, { types: ['character'], makeDefault: true });
Actors.registerSheet(SYSTEM.id, applications.DhpAdversarySheet, { types: ['adversary'], makeDefault: true });
Actors.registerSheet(SYSTEM.id, applications.DhpEnvironment, { types: ['environment'], makeDefault: true });
CONFIG.ActiveEffect.documentClass = documents.DhActiveEffect;
foundry.applications.apps.DocumentSheetConfig.unregisterSheet(
CONFIG.ActiveEffect.documentClass,
'core',
foundry.applications.sheets.ActiveEffectConfig
);
foundry.applications.apps.DocumentSheetConfig.registerSheet(
CONFIG.ActiveEffect.documentClass,
SYSTEM.id,
applications.DhActiveEffectConfig,
{
makeDefault: true
}
);
CONFIG.Combat.dataModels = {
base: models.DhCombat
};
@ -82,12 +101,7 @@ Hooks.once('init', () => {
base: models.DhCombatant
};
CONFIG.ChatMessage.dataModels = {
dualityRoll: models.DhpDualityRoll,
adversaryRoll: models.DhpAdversaryRoll,
damageRoll: models.DhpDamageRoll,
abilityUse: models.DhpAbilityUse
};
CONFIG.ChatMessage.dataModels = models.messages.config;
CONFIG.ChatMessage.documentClass = applications.DhpChatMessage;
CONFIG.Canvas.rulerClass = DhpRuler;
@ -113,7 +127,14 @@ Hooks.once('init', () => {
Hooks.on('ready', () => {
ui.resources = new CONFIG.ui.resources();
ui.resources.render({ force: true });
if (game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).displayFear !== 'hide')
ui.resources.render({ force: true });
document.body.classList.toggle(
'theme-colorful',
game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.appearance).dualityColorScheme ===
DualityRollColor.colorful.value
);
/* Temporary for ease of development. Countdown application should be opened through buttons somewhere */
new CONFIG.ui.countdowns(DhCountdowns.CountdownCategories.narrative).render({ force: true });
@ -145,56 +166,34 @@ Hooks.on(socketEvent.GMUpdate, async (action, uuid, update) => {
}
});
const renderDualityButton = async event => {
const button = event.currentTarget;
const attributeValue = button.dataset.attribute?.toLowerCase();
const target = getCommandTarget();
if (!target) return;
const rollModifier = attributeValue ? target.system.attributes[attributeValue].data.value : null;
const { roll, hope, fear, advantage, disadvantage, modifiers } = await target.diceRoll({
title: button.dataset.label,
value: rollModifier
});
const cls = getDocumentClass('ChatMessage');
const msgData = {
type: 'dualityRoll',
sound: CONFIG.sounds.dice,
system: {
title: button.dataset.label,
origin: target.id,
roll: roll._formula,
modifiers: modifiers,
hope: hope,
fear: fear,
advantage: advantage,
disadvantage: disadvantage
},
user: game.user.id,
content: 'systems/daggerheart/templates/chat/duality-roll.hbs',
rolls: [roll]
};
await cls.create(msgData);
};
Hooks.on('renderChatMessageHTML', (_, element) => {
element
.querySelectorAll('.duality-roll-button')
.forEach(element => element.addEventListener('click', renderDualityButton));
element
.querySelectorAll('.measured-template-button')
.forEach(element => element.addEventListener('click', renderMeasuredTemplate));
});
Hooks.on('renderJournalEntryPageProseMirrorSheet', (_, element) => {
element
.querySelectorAll('.duality-roll-button')
.forEach(element => element.addEventListener('click', renderDualityButton));
element
.querySelectorAll('.measured-template-button')
.forEach(element => element.addEventListener('click', renderMeasuredTemplate));
});
Hooks.on('renderHandlebarsApplication', (_, element) => {
element
.querySelectorAll('.duality-roll-button')
.forEach(element => element.addEventListener('click', renderDualityButton));
element
.querySelectorAll('.measured-template-button')
.forEach(element => element.addEventListener('click', renderMeasuredTemplate));
});
Hooks.on('chatMessage', (_, message) => {
@ -205,68 +204,60 @@ Hooks.on('chatMessage', (_, message) => {
return false;
}
const attributeValue = rollCommand.attribute?.toLowerCase();
const traitValue = rollCommand.trait?.toLowerCase();
const advantageState = rollCommand.advantage ? true : rollCommand.disadvantage ? false : null;
// Target not required if an attribute is not used.
const target = attributeValue ? getCommandTarget() : undefined;
if (target || !attributeValue) {
const target = traitValue ? getCommandTarget() : undefined;
if (target || !traitValue) {
new Promise(async (resolve, reject) => {
const attribute = target ? target.system.attributes[attributeValue] : undefined;
if (attributeValue && !attribute) {
const trait = target ? target.system.traits[traitValue] : undefined;
if (traitValue && !trait) {
ui.notifications.error(game.i18n.localize('DAGGERHEART.Notification.Error.AttributeFaulty'));
reject();
return;
}
const title = attributeValue
const title = traitValue
? game.i18n.format('DAGGERHEART.Chat.DualityRoll.AbilityCheckTitle', {
ability: game.i18n.localize(abilities[attributeValue].label)
ability: game.i18n.localize(abilities[traitValue].label)
})
: game.i18n.localize('DAGGERHEART.General.Duality');
const hopeAndFearRoll = `1${rollCommand.hope ?? 'd12'}+1${rollCommand.fear ?? 'd12'}`;
const advantageRoll = `${rollCommand.advantage && !rollCommand.disadvantage ? '+d6' : rollCommand.disadvantage && !rollCommand.advantage ? '-d6' : ''}`;
const attributeRoll = `${attribute?.data?.value ? `${attribute.data.value > 0 ? `+${attribute.data.value}` : `${attribute.data.value}`}` : ''}`;
const roll = new Roll(`${hopeAndFearRoll}${advantageRoll}${attributeRoll}`);
await roll.evaluate();
const advantageRoll = `${advantageState === true ? '+d6' : advantageState === false ? '-d6' : ''}`;
const attributeRoll = `${trait?.value ? `${trait.value > 0 ? `+${trait.value}` : `${trait.value}`}` : ''}`;
const roll = await Roll.create(`${hopeAndFearRoll}${advantageRoll}${attributeRoll}`).evaluate();
setDiceSoNiceForDualityRoll(
roll,
rollCommand.advantage && !rollCommand.disadvantage,
rollCommand.disadvantage && !rollCommand.advantage
);
setDiceSoNiceForDualityRoll(roll, advantageState);
resolve({
roll,
attribute: attribute
trait: trait
? {
value: attribute.data.value,
label: `${game.i18n.localize(abilities[attributeValue].label)} ${attribute.data.value >= 0 ? `+` : ``}${attribute.data.value}`
value: trait.value,
label: `${game.i18n.localize(abilities[traitValue].label)} ${trait.value >= 0 ? `+` : ``}${trait.value}`
}
: undefined,
title
});
}).then(({ roll, attribute, title }) => {
}).then(async ({ roll, trait, title }) => {
const cls = getDocumentClass('ChatMessage');
const systemData = new DHDualityRoll({
title: title,
origin: target?.id,
roll: roll,
modifiers: trait ? [trait] : [],
hope: { dice: rollCommand.hope ?? 'd12', value: roll.dice[0].total },
fear: { dice: rollCommand.fear ?? 'd12', value: roll.dice[1].total },
advantage: advantageState !== null ? { dice: 'd6', value: roll.dice[2].total } : undefined,
advantageState
});
const msgData = {
type: 'dualityRoll',
sound: CONFIG.sounds.dice,
system: {
title: title,
origin: target?.id,
roll: roll._formula,
modifiers: attribute ? [attribute] : [],
hope: { dice: rollCommand.hope ?? 'd12', value: roll.dice[0].total },
fear: { dice: rollCommand.fear ?? 'd12', value: roll.dice[1].total },
advantage:
rollCommand.advantage && !rollCommand.disadvantage
? { dice: 'd6', value: roll.dice[2].total }
: undefined,
disadvantage:
rollCommand.disadvantage && !rollCommand.advantage
? { dice: 'd6', value: roll.dice[2].total }
: undefined
},
system: systemData,
user: game.user.id,
content: 'systems/daggerheart/templates/chat/duality-roll.hbs',
rolls: [roll]
@ -295,13 +286,24 @@ const preloadHandlebarsTemplates = async function () {
'systems/daggerheart/templates/sheets/parts/heritage.hbs',
'systems/daggerheart/templates/sheets/parts/subclassFeature.hbs',
'systems/daggerheart/templates/sheets/parts/effects.hbs',
'systems/daggerheart/templates/sheets/pc/sections/inventory.hbs',
'systems/daggerheart/templates/sheets/pc/sections/loadout.hbs',
'systems/daggerheart/templates/sheets/pc/parts/heritageCard.hbs',
'systems/daggerheart/templates/sheets/pc/parts/advancementCard.hbs',
'systems/daggerheart/templates/sheets/character/sections/inventory.hbs',
'systems/daggerheart/templates/sheets/character/sections/loadout.hbs',
'systems/daggerheart/templates/sheets/character/parts/heritageCard.hbs',
'systems/daggerheart/templates/sheets/character/parts/advancementCard.hbs',
'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-features.hbs',
'systems/daggerheart/templates/sheets/items/subclass/parts/subclass-feature.hbs',
'systems/daggerheart/templates/components/card-preview.hbs',
'systems/daggerheart/templates/views/levelup/parts/selectable-card-preview.hbs',
'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs',
'systems/daggerheart/templates/ui/combat/combatTrackerSection.hbs'
'systems/daggerheart/templates/ui/combat/combatTrackerSection.hbs',
'systems/daggerheart/templates/views/actionTypes/damage.hbs',
'systems/daggerheart/templates/views/actionTypes/healing.hbs',
'systems/daggerheart/templates/views/actionTypes/resource.hbs',
'systems/daggerheart/templates/views/actionTypes/uuid.hbs',
'systems/daggerheart/templates/views/actionTypes/uses.hbs',
'systems/daggerheart/templates/views/actionTypes/roll.hbs',
'systems/daggerheart/templates/views/actionTypes/cost.hbs',
'systems/daggerheart/templates/views/actionTypes/range-target.hbs',
'systems/daggerheart/templates/views/actionTypes/effect.hbs'
]);
};