mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-08 21:58:11 +02:00
Compare commits
No commits in common. "273f66678496fdde7478e988c54723a076710b12" and "b23095cb2f2a16ae2ac63c77166fdb150fc52a14" have entirely different histories.
273f666784
...
b23095cb2f
11 changed files with 38 additions and 116 deletions
|
|
@ -50,7 +50,7 @@ export default class CompendiumBrowserSettings extends HandlebarsApplicationMixi
|
||||||
const excludedSourceData = this.browserSettings.excludedSources;
|
const excludedSourceData = this.browserSettings.excludedSources;
|
||||||
const excludedPackData = this.browserSettings.excludedPacks;
|
const excludedPackData = this.browserSettings.excludedPacks;
|
||||||
context.typePackCollections = game.packs.reduce((acc, pack) => {
|
context.typePackCollections = game.packs.reduce((acc, pack) => {
|
||||||
const { type, label, packageType, packageName: basePackageName, name, id } = pack.metadata;
|
const { type, label, packageType, packageName: basePackageName, id } = pack.metadata;
|
||||||
if (!CompendiumBrowserSettings.#browserPackTypes.includes(type)) return acc;
|
if (!CompendiumBrowserSettings.#browserPackTypes.includes(type)) return acc;
|
||||||
|
|
||||||
const isWorldPack = packageType === 'world';
|
const isWorldPack = packageType === 'world';
|
||||||
|
|
@ -68,15 +68,13 @@ export default class CompendiumBrowserSettings extends HandlebarsApplicationMixi
|
||||||
if (!acc[type].sources[packageName])
|
if (!acc[type].sources[packageName])
|
||||||
acc[type].sources[packageName] = { label: sourceLabel, checked: sourceChecked, packs: [] };
|
acc[type].sources[packageName] = { label: sourceLabel, checked: sourceChecked, packs: [] };
|
||||||
|
|
||||||
const included =
|
const checked = !excludedPackData[id] || !excludedPackData[id].excludedDocumentTypes.includes(type);
|
||||||
!excludedPackData[packageName] ||
|
|
||||||
!excludedPackData[packageName][name]?.excludedDocumentTypes.includes(type);
|
|
||||||
|
|
||||||
acc[type].sources[packageName].packs.push({
|
acc[type].sources[packageName].packs.push({
|
||||||
name,
|
pack: id,
|
||||||
type,
|
type,
|
||||||
label: id === game.system.id ? game.system.title : game.i18n.localize(label),
|
label: id === game.system.id ? game.system.title : game.i18n.localize(label),
|
||||||
checked: included
|
checked: checked
|
||||||
});
|
});
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
|
|
@ -108,16 +106,16 @@ export default class CompendiumBrowserSettings extends HandlebarsApplicationMixi
|
||||||
toggleTypedPack(event) {
|
toggleTypedPack(event) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
const { type, source, packName } = event.target.dataset;
|
const { type, pack } = event.target.dataset;
|
||||||
const currentlyExcluded = this.browserSettings.excludedPacks[source]?.[packName]
|
const currentlyExcluded = this.browserSettings.excludedPacks[pack]
|
||||||
? this.browserSettings.excludedPacks[source][packName].excludedDocumentTypes.includes(type)
|
? this.browserSettings.excludedPacks[pack].excludedDocumentTypes.includes(type)
|
||||||
: false;
|
: false;
|
||||||
|
|
||||||
this.browserSettings.excludedPacks[source] ??= {};
|
if (!this.browserSettings.excludedPacks[pack])
|
||||||
this.browserSettings.excludedPacks[source][packName] ??= { excludedDocumentTypes: [] };
|
this.browserSettings.excludedPacks[pack] = { excludedDocumentTypes: [] };
|
||||||
this.browserSettings.excludedPacks[source][packName].excludedDocumentTypes = currentlyExcluded
|
this.browserSettings.excludedPacks[pack].excludedDocumentTypes = currentlyExcluded
|
||||||
? this.browserSettings.excludedPacks[source][packName].excludedDocumentTypes.filter(x => x !== type)
|
? this.browserSettings.excludedPacks[pack].excludedDocumentTypes.filter(x => x !== type)
|
||||||
: [...(this.browserSettings.excludedPacks[source][packName]?.excludedDocumentTypes ?? []), type];
|
: [...(this.browserSettings.excludedPacks[pack]?.excludedDocumentTypes ?? []), type];
|
||||||
|
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { DhHomebrew } from '../../data/settings/_module.mjs';
|
import { DhHomebrew } from '../../data/settings/_module.mjs';
|
||||||
import { Resource } from '../../data/settings/Homebrew.mjs';
|
import { Resource } from '../../data/settings/Homebrew.mjs';
|
||||||
|
import { slugify } from '../../helpers/utils.mjs';
|
||||||
|
|
||||||
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -402,12 +403,12 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
const domainName = button.form.elements.domainName.value;
|
const domainName = button.form.elements.domainName.value;
|
||||||
if (!domainName) return;
|
if (!domainName) return;
|
||||||
|
|
||||||
const newSlug = domainName.slugify();
|
const newSlug = slugify(domainName);
|
||||||
const existingDomains = [
|
const existingDomains = [
|
||||||
...Object.values(this.settings.domains),
|
...Object.values(this.settings.domains),
|
||||||
...Object.values(CONFIG.DH.DOMAIN.domains)
|
...Object.values(CONFIG.DH.DOMAIN.domains)
|
||||||
];
|
];
|
||||||
if (existingDomains.find(x => x.id === newSlug)) {
|
if (existingDomains.find(x => slugify(game.i18n.localize(x.label)) === newSlug)) {
|
||||||
ui.notifications.warn(game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.duplicateDomain'));
|
ui.notifications.warn(game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.domains.duplicateDomain'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -528,7 +529,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
||||||
const identifier = button.form.elements.identifier.value;
|
const identifier = button.form.elements.identifier.value;
|
||||||
if (!identifier) return;
|
if (!identifier) return;
|
||||||
|
|
||||||
const sluggedIdentifier = identifier.slugify();
|
const sluggedIdentifier = slugify(identifier);
|
||||||
|
|
||||||
await this.settings.updateSource({
|
await this.settings.updateSource({
|
||||||
[`resources.${actorType}.resources.${sluggedIdentifier}`]: Resource.getDefaultResourceData(identifier)
|
[`resources.${actorType}.resources.${sluggedIdentifier}`]: Resource.getDefaultResourceData(identifier)
|
||||||
|
|
|
||||||
|
|
@ -57,14 +57,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
contextMenus: [
|
contextMenus: [
|
||||||
{
|
|
||||||
handler: CharacterSheet.#getCreationMainContextOptions,
|
|
||||||
selector: '.character-details [data-action="editDoc"]',
|
|
||||||
options: {
|
|
||||||
parentClassHooks: false,
|
|
||||||
fixed: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
handler: CharacterSheet.#getDomainCardContextOptions,
|
handler: CharacterSheet.#getDomainCardContextOptions,
|
||||||
selector: '[data-item-uuid][data-type="domainCard"]',
|
selector: '[data-item-uuid][data-type="domainCard"]',
|
||||||
|
|
@ -327,56 +319,6 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
/* Context Menu */
|
/* Context Menu */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
static #getCreationMainContextOptions() {
|
|
||||||
/** Returns true if the item is managed by the level up wizard. Such items shouldn't allow things like manual removal */
|
|
||||||
function isItemWizardManaged(item) {
|
|
||||||
const actor = item?.actor;
|
|
||||||
if (!actor) return false;
|
|
||||||
|
|
||||||
// If levelup automation is off in general or for this character, all items are unmanaged
|
|
||||||
// This is disabled until we have proper granted feature removal, for now this feature is to correct errors
|
|
||||||
// const levelupAuto = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).levelupAuto;
|
|
||||||
// if (!levelupAuto) return false;
|
|
||||||
|
|
||||||
// Core items aren't part of levelup data. TODO: add some way to flag a specific character as no auto leveling
|
|
||||||
const classPair = actor.system.class;
|
|
||||||
const coreItems = [actor.system.ancestry, actor.system.community, classPair?.value, classPair?.subclass];
|
|
||||||
if (coreItems.includes(item)) return true;
|
|
||||||
|
|
||||||
const levelups = Object.values(actor.system.levelData?.levelups) ?? [];
|
|
||||||
const uuid = item.uuid;
|
|
||||||
const sourceUuid = item._stats.compendiumSource; // on older characters this may be missing
|
|
||||||
return levelups.some(data => {
|
|
||||||
if (item.type === 'subclass') {
|
|
||||||
const selectedSubclasses = data.selections.map(s => s.secondaryData?.subclass).filter(s => !!s);
|
|
||||||
return sourceUuid
|
|
||||||
? selectedSubclasses.includes(sourceUuid)
|
|
||||||
: selectedSubclasses.length && item.system.isMulticlass;
|
|
||||||
}
|
|
||||||
|
|
||||||
const matchesCard = data.achievements.domainCards.some(i => i.itemUuid === uuid);
|
|
||||||
const matchesSelection = data.selections.some(s => s.itemUuid === uuid);
|
|
||||||
return matchesCard || matchesSelection;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
label: 'CONTROLS.CommonDelete',
|
|
||||||
icon: 'fa-solid fa-trash',
|
|
||||||
visible: target => {
|
|
||||||
const doc = getDocFromElementSync(target);
|
|
||||||
return doc?.isOwner && !isItemWizardManaged(doc);
|
|
||||||
},
|
|
||||||
callback: async (target, event) => {
|
|
||||||
const doc = await getDocFromElement(target);
|
|
||||||
if (event.shiftKey) return doc.delete();
|
|
||||||
else return doc.deleteDialog();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the set of ContextMenu options for DomainCards.
|
* Get the set of ContextMenu options for DomainCards.
|
||||||
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
|
* @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance
|
||||||
|
|
|
||||||
|
|
@ -443,13 +443,11 @@ export const typeConfig = {
|
||||||
const list = [];
|
const list = [];
|
||||||
for (const item of items.filter(item => item.system.linkedClass)) {
|
for (const item of items.filter(item => item.system.linkedClass)) {
|
||||||
const linkedClass = await foundry.utils.fromUuid(item.system.linkedClass);
|
const linkedClass = await foundry.utils.fromUuid(item.system.linkedClass);
|
||||||
if (linkedClass) {
|
|
||||||
list.push({
|
list.push({
|
||||||
value: linkedClass.uuid,
|
value: linkedClass.uuid,
|
||||||
label: linkedClass.name
|
label: linkedClass.name
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return list.reduce((a, c) => {
|
return list.reduce((a, c) => {
|
||||||
if (!a.find(i => i.value === c.value)) a.push(c);
|
if (!a.find(i => i.value === c.value)) a.push(c);
|
||||||
|
|
|
||||||
|
|
@ -577,8 +577,6 @@ export default class DhCharacter extends DhCreature {
|
||||||
communityFeatures = [],
|
communityFeatures = [],
|
||||||
classFeatures = [],
|
classFeatures = [],
|
||||||
subclassFeatures = [],
|
subclassFeatures = [],
|
||||||
multiclassFeatures = [],
|
|
||||||
multiclassSubclassFeatures = [],
|
|
||||||
companionFeatures = [],
|
companionFeatures = [],
|
||||||
features = [];
|
features = [];
|
||||||
|
|
||||||
|
|
@ -588,9 +586,9 @@ export default class DhCharacter extends DhCreature {
|
||||||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.community.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.community.id) {
|
||||||
communityFeatures.push(item);
|
communityFeatures.push(item);
|
||||||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.class.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.class.id) {
|
||||||
(item.system.multiclassOrigin ? multiclassFeatures : classFeatures).push(item);
|
classFeatures.push(item);
|
||||||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.subclass.id) {
|
||||||
(item.system.multiclassOrigin ? multiclassSubclassFeatures : subclassFeatures).push(item);
|
subclassFeatures.push(item);
|
||||||
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) {
|
} else if (item.system.originItemType === CONFIG.DH.ITEM.featureTypes.companion.id) {
|
||||||
companionFeatures.push(item);
|
companionFeatures.push(item);
|
||||||
} else if (item.type === 'feature' && !item.system.type) {
|
} else if (item.type === 'feature' && !item.system.type) {
|
||||||
|
|
@ -619,24 +617,6 @@ export default class DhCharacter extends DhCreature {
|
||||||
type: 'subclass',
|
type: 'subclass',
|
||||||
values: subclassFeatures
|
values: subclassFeatures
|
||||||
},
|
},
|
||||||
...(multiclassFeatures.length
|
|
||||||
? {
|
|
||||||
multiclassFeatures: {
|
|
||||||
title: `${game.i18n.localize('DAGGERHEART.GENERAL.multiclass')} - ${this.multiclass.value?.name}`,
|
|
||||||
type: 'multiclass',
|
|
||||||
values: multiclassFeatures
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
...(multiclassSubclassFeatures.length
|
|
||||||
? {
|
|
||||||
multiclassSubclassFeatures: {
|
|
||||||
title: `${game.i18n.localize('DAGGERHEART.GENERAL.multiclass')} ${game.i18n.localize('TYPES.Item.subclass')} - ${this.multiclass.subclass?.name}`,
|
|
||||||
type: 'multiclassSubclass',
|
|
||||||
values: multiclassSubclassFeatures
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: {}),
|
|
||||||
companionFeatures: {
|
companionFeatures: {
|
||||||
title: game.i18n.localize('DAGGERHEART.ACTORS.Character.companionFeatures'),
|
title: game.i18n.localize('DAGGERHEART.ACTORS.Character.companionFeatures'),
|
||||||
type: 'companion',
|
type: 'companion',
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,12 @@ export default class CompendiumBrowserSettings extends foundry.abstract.DataMode
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
excludedPacks: new fields.TypedObjectField(
|
excludedPacks: new fields.TypedObjectField(
|
||||||
new fields.TypedObjectField(
|
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
excludedDocumentTypes: new fields.ArrayField(
|
excludedDocumentTypes: new fields.ArrayField(
|
||||||
new fields.StringField({ required: true, choices: CONST.SYSTEM_SPECIFIC_COMPENDIUM_TYPES })
|
new fields.StringField({ required: true, choices: CONST.SYSTEM_SPECIFIC_COMPENDIUM_TYPES })
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,7 +28,7 @@ export default class CompendiumBrowserSettings extends foundry.abstract.DataMode
|
||||||
const excludedSourceData = this.excludedSources[packageName];
|
const excludedSourceData = this.excludedSources[packageName];
|
||||||
if (excludedSourceData && excludedSourceData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
if (excludedSourceData && excludedSourceData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
||||||
|
|
||||||
const excludedPackData = this.excludedPacks[packageName]?.[pack.metadata.name];
|
const excludedPackData = this.excludedPacks[item.pack];
|
||||||
if (excludedPackData && excludedPackData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
if (excludedPackData && excludedPackData.excludedDocumentTypes.includes(pack.metadata.type)) return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -449,9 +449,14 @@ export async function createEmbeddedItemsWithEffects(actor, baseData) {
|
||||||
effects: data.effects?.map(effect => effect.toObject())
|
effects: data.effects?.map(effect => effect.toObject())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await actor.createEmbeddedDocuments('Item', effectData);
|
await actor.createEmbeddedDocuments('Item', effectData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const slugify = name => {
|
||||||
|
return name.toLowerCase().replaceAll(' ', '-').replaceAll('.', '');
|
||||||
|
};
|
||||||
|
|
||||||
export function shuffleArray(array) {
|
export function shuffleArray(array) {
|
||||||
let currentIndex = array.length;
|
let currentIndex = array.length;
|
||||||
while (currentIndex != 0) {
|
while (currentIndex != 0) {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "daggerheart",
|
"id": "daggerheart",
|
||||||
"title": "Daggerheart",
|
"title": "Daggerheart",
|
||||||
"description": "An unofficial implementation of the Daggerheart system",
|
"description": "An unofficial implementation of the Daggerheart system",
|
||||||
"version": "2.2.6",
|
"version": "2.2.5",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "14.361",
|
"minimum": "14.361",
|
||||||
"verified": "14.361",
|
"verified": "14.361",
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
},
|
},
|
||||||
"url": "https://github.com/Foundryborne/daggerheart",
|
"url": "https://github.com/Foundryborne/daggerheart",
|
||||||
"manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json",
|
"manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json",
|
||||||
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.6/system.zip",
|
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.2.5/system.zip",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "WBHarry"
|
"name": "WBHarry"
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
<div class="checks-container {{#unless source.checked}}collapsed{{/unless}}">
|
<div class="checks-container {{#unless source.checked}}collapsed{{/unless}}">
|
||||||
{{#each source.packs as |pack|}}
|
{{#each source.packs as |pack|}}
|
||||||
<div class="check-container">
|
<div class="check-container">
|
||||||
<input type="checkbox" class="pack-checkbox" data-type="{{pack.type}}" data-source="{{@../key}}" data-pack-name="{{pack.name}}" {{checked pack.checked}} />
|
<input type="checkbox" class="pack-checkbox" data-type="{{pack.type}}" data-pack="{{pack.pack}}" {{checked pack.checked}} />
|
||||||
<label>{{pack.label}}</label>
|
<label>{{pack.label}}</label>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if (or document.system.multiclass.value document.system.multiclass.subclass)}}
|
{{#if document.system.multiclass.value}}
|
||||||
<div class="multiclass">
|
<div class="multiclass">
|
||||||
{{#if document.system.multiclass.value}}
|
{{#if document.system.multiclass.value}}
|
||||||
<span data-action="editDoc"data-item-uuid="{{document.system.multiclass.value.uuid}}">{{document.system.multiclass.value.name}}</span>
|
<span data-action="editDoc"data-item-uuid="{{document.system.multiclass.value.uuid}}">{{document.system.multiclass.value.name}}</span>
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
{{#if roll.isCritical}}
|
{{#if roll.isCritical}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.criticalShort"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.criticalShort"}}</span>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if (and roll.dHope (not (eq roll.options.roll.type "reaction")))}}
|
{{#if (and roll.dHope (not (eq roll.type "reaction")))}}
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.withThing" thing=roll.totalLabel}}</span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue