Attempt at making subclass aware of its class

This commit is contained in:
WBHarry 2025-08-23 12:12:46 +02:00
parent b83adbf09b
commit 6746190168
5 changed files with 272 additions and 235 deletions

View file

@ -2371,7 +2371,8 @@
"insufficientResources": "You have insufficient resources", "insufficientResources": "You have insufficient resources",
"multiclassAlreadyPresent": "You already have a class and multiclass", "multiclassAlreadyPresent": "You already have a class and multiclass",
"subclassesAlreadyPresent": "You already have a class and multiclass subclass", "subclassesAlreadyPresent": "You already have a class and multiclass subclass",
"noDiceSystem": "Your selected dice {system} does not have a {faces} dice" "noDiceSystem": "Your selected dice {system} does not have a {faces} dice",
"subclassAlreadyLinked": "{name} is already a subclass in the class {class}. Remove it from there if you want it to be a subclass to this class."
}, },
"Tooltip": { "Tooltip": {
"disableEffect": "Disable Effect", "disableEffect": "Disable Effect",

View file

@ -432,12 +432,16 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
} }
}; };
if (type == 'domains') if (type === 'domains')
presets.filter = { presets.filter = {
'level.max': { key: 'level.max', value: 1 }, 'level.max': { key: 'level.max', value: 1 },
'system.domain': { key: 'system.domain', value: this.setup.class?.system.domains ?? null } 'system.domain': { key: 'system.domain', value: this.setup.class?.system.domains ?? null }
}; };
if (type === 'subclasses')
presets.filter = {
'system.linkedClass': { key: 'system.linkedClass', value: this.setup.class?.uuid }
};
if (equipment.includes(type)) if (equipment.includes(type))
presets.filter = { presets.filter = {
'system.tier': { key: 'system.tier', value: 1 }, 'system.tier': { key: 'system.tier', value: 1 },

View file

@ -119,6 +119,15 @@ export default class ClassSheet extends DHBaseItemSheet {
const itemType = data.data ? data.type : item.type; const itemType = data.data ? data.type : item.type;
const target = event.target.closest('fieldset.drop-section'); const target = event.target.closest('fieldset.drop-section');
if (itemType === 'subclass') { if (itemType === 'subclass') {
if (item.system.linkedClass) {
return ui.notifications.warn(
game.i18n.format('DAGGERHEART.UI.Notifications.subclassAlreadyLinked', {
name: item.name,
class: this.document.name
})
);
}
await item.update({ 'system.linkedClass': this.document.uuid });
await this.document.update({ await this.document.update({
'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid] 'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid]
}); });
@ -181,6 +190,12 @@ export default class ClassSheet extends DHBaseItemSheet {
static async #removeItemFromCollection(_event, element) { static async #removeItemFromCollection(_event, element) {
const { uuid, target } = element.dataset; const { uuid, target } = element.dataset;
const prop = foundry.utils.getProperty(this.document.system, target); const prop = foundry.utils.getProperty(this.document.system, target);
if (target === 'subclasses') {
const subclass = await foundry.utils.fromUuid(uuid);
await subclass.update({ 'system.linkedClass': null });
}
await this.document.update({ [`system.${target}`]: prop.filter(i => i.uuid !== uuid).map(x => x.uuid) }); await this.document.update({ [`system.${target}`]: prop.filter(i => i.uuid !== uuid).map(x => x.uuid) });
} }

View file

@ -2,404 +2,419 @@ export const typeConfig = {
adversaries: { adversaries: {
columns: [ columns: [
{ {
key: "system.tier", key: 'system.tier',
label: "Tier" label: 'Tier'
}, },
{ {
key: "system.type", key: 'system.type',
label: "Type" label: 'Type'
} }
], ],
filters: [ filters: [
{ {
key: "system.tier", key: 'system.tier',
label: "Tier", label: 'Tier',
field: 'system.api.models.actors.DhAdversary.schema.fields.tier' field: 'system.api.models.actors.DhAdversary.schema.fields.tier'
}, },
{ {
key: "system.type", key: 'system.type',
label: "Type", label: 'Type',
field: 'system.api.models.actors.DhAdversary.schema.fields.type' field: 'system.api.models.actors.DhAdversary.schema.fields.type'
}, },
{ {
key: "system.difficulty", key: 'system.difficulty',
name: "difficulty.min", name: 'difficulty.min',
label: "Difficulty (Min)", label: 'Difficulty (Min)',
field: 'system.api.models.actors.DhAdversary.schema.fields.difficulty', field: 'system.api.models.actors.DhAdversary.schema.fields.difficulty',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.difficulty", key: 'system.difficulty',
name: "difficulty.max", name: 'difficulty.max',
label: "Difficulty (Max)", label: 'Difficulty (Max)',
field: 'system.api.models.actors.DhAdversary.schema.fields.difficulty', field: 'system.api.models.actors.DhAdversary.schema.fields.difficulty',
operator: "lte" operator: 'lte'
}, },
{ {
key: "system.resources.hitPoints.max", key: 'system.resources.hitPoints.max',
name: "hp.min", name: 'hp.min',
label: "Hit Points (Min)", label: 'Hit Points (Min)',
field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.hitPoints.fields.max', field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.hitPoints.fields.max',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.resources.hitPoints.max", key: 'system.resources.hitPoints.max',
name: "hp.max", name: 'hp.max',
label: "Hit Points (Max)", label: 'Hit Points (Max)',
field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.hitPoints.fields.max', field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.hitPoints.fields.max',
operator: "lte" operator: 'lte'
}, },
{ {
key: "system.resources.stress.max", key: 'system.resources.stress.max',
name: "stress.min", name: 'stress.min',
label: "Stress (Min)", label: 'Stress (Min)',
field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.stress.fields.max', field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.stress.fields.max',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.resources.stress.max", key: 'system.resources.stress.max',
name: "stress.max", name: 'stress.max',
label: "Stress (Max)", label: 'Stress (Max)',
field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.stress.fields.max', field: 'system.api.models.actors.DhAdversary.schema.fields.resources.fields.stress.fields.max',
operator: "lte" operator: 'lte'
}, }
] ]
}, },
items: { items: {
columns: [ columns: [
{ {
key: "type", key: 'type',
label: "Type" label: 'Type'
}, },
{ {
key: "system.secondary", key: 'system.secondary',
label: "Subtype", label: 'Subtype',
format: (isSecondary) => isSecondary ? "secondary" : (isSecondary === false ? "primary" : '-') format: isSecondary => (isSecondary ? 'secondary' : isSecondary === false ? 'primary' : '-')
}, },
{ {
key: "system.tier", key: 'system.tier',
label: "Tier" label: 'Tier'
} }
], ],
filters: [ filters: [
{ {
key: "type", key: 'type',
label: "Type", label: 'Type',
choices: () => CONFIG.Item.documentClass.TYPES.filter(t => ["armor", "weapon", "consumable", "loot"].includes(t)).map(t => ({ value: t, label: t })) choices: () =>
CONFIG.Item.documentClass.TYPES.filter(t =>
['armor', 'weapon', 'consumable', 'loot'].includes(t)
).map(t => ({ value: t, label: t }))
}, },
{ {
key: "system.secondary", key: 'system.secondary',
label: "Subtype", label: 'Subtype',
choices: [ choices: [
{ value: false, label: "Primary Weapon"}, { value: false, label: 'Primary Weapon' },
{ value: true, label: "Secondary Weapon"} { value: true, label: 'Secondary Weapon' }
] ]
}, },
{ {
key: "system.tier", key: 'system.tier',
label: "Tier", label: 'Tier',
choices: [{ value: "1", label: "1"}, { value: "2", label: "2"}, { value: "3", label: "3"}, { value: "4", label: "4"}] choices: [
{ value: '1', label: '1' },
{ value: '2', label: '2' },
{ value: '3', label: '3' },
{ value: '4', label: '4' }
]
}, },
{ {
key: "system.burden", key: 'system.burden',
label: "Burden", label: 'Burden',
field: 'system.api.models.items.DHWeapon.schema.fields.burden' field: 'system.api.models.items.DHWeapon.schema.fields.burden'
}, },
{ {
key: "system.attack.roll.trait", key: 'system.attack.roll.trait',
label: "Trait", label: 'Trait',
field: 'system.api.models.actions.actionsTypes.attack.schema.fields.roll.fields.trait' field: 'system.api.models.actions.actionsTypes.attack.schema.fields.roll.fields.trait'
}, },
{ {
key: "system.attack.range", key: 'system.attack.range',
label: "Range", label: 'Range',
field: 'system.api.models.actions.actionsTypes.attack.schema.fields.range' field: 'system.api.models.actions.actionsTypes.attack.schema.fields.range'
}, },
{ {
key: "system.baseScore", key: 'system.baseScore',
name: "armor.min", name: 'armor.min',
label: "Armor Score (Min)", label: 'Armor Score (Min)',
field: 'system.api.models.items.DHArmor.schema.fields.baseScore', field: 'system.api.models.items.DHArmor.schema.fields.baseScore',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.baseScore", key: 'system.baseScore',
name: "armor.max", name: 'armor.max',
label: "Armor Score (Max)", label: 'Armor Score (Max)',
field: 'system.api.models.items.DHArmor.schema.fields.baseScore', field: 'system.api.models.items.DHArmor.schema.fields.baseScore',
operator: "lte" operator: 'lte'
}, },
{ {
key: "system.itemFeatures", key: 'system.itemFeatures',
label: "Features", label: 'Features',
choices: () => [...Object.entries(CONFIG.DH.ITEM.weaponFeatures), ...Object.entries(CONFIG.DH.ITEM.armorFeatures)].map(([k,v]) => ({ value: k, label: v.label})), choices: () =>
operator: "contains3" [
...Object.entries(CONFIG.DH.ITEM.weaponFeatures),
...Object.entries(CONFIG.DH.ITEM.armorFeatures)
].map(([k, v]) => ({ value: k, label: v.label })),
operator: 'contains3'
} }
] ]
}, },
features: { features: {
columns: [ columns: [],
filters: []
],
filters: [
]
}, },
cards: { cards: {
columns: [ columns: [
{ {
key: "system.type", key: 'system.type',
label: "Type" label: 'Type'
}, },
{ {
key: "system.domain", key: 'system.domain',
label: "Domain" label: 'Domain'
}, },
{ {
key: "system.level", key: 'system.level',
label: "Level" label: 'Level'
} }
], ],
filters: [ filters: [
{ {
key: "system.type", key: 'system.type',
label: "Type", label: 'Type',
field: 'system.api.models.items.DHDomainCard.schema.fields.type' field: 'system.api.models.items.DHDomainCard.schema.fields.type'
}, },
{ {
key: "system.domain", key: 'system.domain',
label: "Domain", label: 'Domain',
field: 'system.api.models.items.DHDomainCard.schema.fields.domain', field: 'system.api.models.items.DHDomainCard.schema.fields.domain',
operator: "contains2" operator: 'contains2'
}, },
{ {
key: "system.level", key: 'system.level',
name: "level.min", name: 'level.min',
label: "Level (Min)", label: 'Level (Min)',
field: 'system.api.models.items.DHDomainCard.schema.fields.level', field: 'system.api.models.items.DHDomainCard.schema.fields.level',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.level", key: 'system.level',
name: "level.max", name: 'level.max',
label: "Level (Max)", label: 'Level (Max)',
field: 'system.api.models.items.DHDomainCard.schema.fields.level', field: 'system.api.models.items.DHDomainCard.schema.fields.level',
operator: "lte" operator: 'lte'
}, },
{ {
key: "system.recallCost", key: 'system.recallCost',
name: "recall.min", name: 'recall.min',
label: "Recall Cost (Min)", label: 'Recall Cost (Min)',
field: 'system.api.models.items.DHDomainCard.schema.fields.recallCost', field: 'system.api.models.items.DHDomainCard.schema.fields.recallCost',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.recallCost", key: 'system.recallCost',
name: "recall.max", name: 'recall.max',
label: "Recall Cost (Max)", label: 'Recall Cost (Max)',
field: 'system.api.models.items.DHDomainCard.schema.fields.recallCost', field: 'system.api.models.items.DHDomainCard.schema.fields.recallCost',
operator: "lte" operator: 'lte'
} }
] ]
}, },
classes: { classes: {
columns: [ columns: [
{ {
key: "system.evasion", key: 'system.evasion',
label: "Evasion" label: 'Evasion'
}, },
{ {
key: "system.hitPoints", key: 'system.hitPoints',
label: "Hit Points" label: 'Hit Points'
}, },
{ {
key: "system.domains", key: 'system.domains',
label: "Domains" label: 'Domains'
} }
], ],
filters: [ filters: [
{ {
key: "system.evasion", key: 'system.evasion',
name: "evasion.min", name: 'evasion.min',
label: "Evasion (Min)", label: 'Evasion (Min)',
field: 'system.api.models.items.DHClass.schema.fields.evasion', field: 'system.api.models.items.DHClass.schema.fields.evasion',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.evasion", key: 'system.evasion',
name: "evasion.max", name: 'evasion.max',
label: "Evasion (Max)", label: 'Evasion (Max)',
field: 'system.api.models.items.DHClass.schema.fields.evasion', field: 'system.api.models.items.DHClass.schema.fields.evasion',
operator: "lte" operator: 'lte'
}, },
{ {
key: "system.hitPoints", key: 'system.hitPoints',
name: "hp.min", name: 'hp.min',
label: "Hit Points (Min)", label: 'Hit Points (Min)',
field: 'system.api.models.items.DHClass.schema.fields.hitPoints', field: 'system.api.models.items.DHClass.schema.fields.hitPoints',
operator: "gte" operator: 'gte'
}, },
{ {
key: "system.hitPoints", key: 'system.hitPoints',
name: "hp.max", name: 'hp.max',
label: "Hit Points (Max)", label: 'Hit Points (Max)',
field: 'system.api.models.items.DHClass.schema.fields.hitPoints', field: 'system.api.models.items.DHClass.schema.fields.hitPoints',
operator: "lte" operator: 'lte'
}, },
{ {
key: "system.domains", key: 'system.domains',
label: "Domains", label: 'Domains',
choices: () => Object.values(CONFIG.DH.DOMAIN.domains).map(d => ({ value: d.id, label: d.label })), choices: () => Object.values(CONFIG.DH.DOMAIN.domains).map(d => ({ value: d.id, label: d.label })),
operator: "contains2" operator: 'contains2'
} }
] ]
}, },
subclasses: { subclasses: {
columns: [ columns: [
{ {
key: "id", key: 'id',
label: "Class", label: 'Class',
format: (id) => { format: id => {
return ""; console.log(id);
return '';
} }
}, },
{ {
key: "system.spellcastingTrait", key: 'system.spellcastingTrait',
label: "Spellcasting Trait" label: 'Spellcasting Trait'
}
],
filters: []
},
beastforms: {
columns: [
{
key: "system.tier",
label: "Tier"
},
{
key: "system.mainTrait",
label: "Main Trait"
} }
], ],
filters: [ filters: [
{ {
key: "system.tier", key: 'system.linkedClass',
label: "Tier", label: 'Class',
field: 'system.api.models.items.DHSubclass.schema.fields.linkedClass'
}
]
},
beastforms: {
columns: [
{
key: 'system.tier',
label: 'Tier'
},
{
key: 'system.mainTrait',
label: 'Main Trait'
}
],
filters: [
{
key: 'system.tier',
label: 'Tier',
field: 'system.api.models.items.DHBeastform.schema.fields.tier' field: 'system.api.models.items.DHBeastform.schema.fields.tier'
}, },
{ {
key: "system.mainTrait", key: 'system.mainTrait',
label: "Main Trait", label: 'Main Trait',
field: 'system.api.models.items.DHBeastform.schema.fields.mainTrait' field: 'system.api.models.items.DHBeastform.schema.fields.mainTrait'
} }
] ]
} }
} };
export const compendiumConfig = { export const compendiumConfig = {
"daggerheart": { daggerheart: {
id: "daggerheart", id: 'daggerheart',
label: "DAGGERHEART", label: 'DAGGERHEART',
folders: { folders: {
"adversaries": { adversaries: {
id: "adversaries", id: 'adversaries',
keys: ["adversaries"], keys: ['adversaries'],
label: "Adversaries", label: 'Adversaries',
type: ["adversary"], type: ['adversary'],
listType: "adversaries" listType: 'adversaries'
}, },
"ancestries": { ancestries: {
id: "ancestries", id: 'ancestries',
keys: ["ancestries"], keys: ['ancestries'],
label: "Ancestries", label: 'Ancestries',
type: ["ancestry"], type: ['ancestry'],
folders: { folders: {
"features": { features: {
id: "features", id: 'features',
keys: ["ancestries"], keys: ['ancestries'],
label: "Features", label: 'Features',
type: ["feature"] type: ['feature']
} }
} }
}, },
"equipments": { equipments: {
id: "equipments", id: 'equipments',
keys: ["armors", "weapons", "consumables", "loot"], keys: ['armors', 'weapons', 'consumables', 'loot'],
label: "Equipment", label: 'Equipment',
type: ["armor", "weapon", "consumable", "loot"], type: ['armor', 'weapon', 'consumable', 'loot'],
listType: "items" listType: 'items'
}, },
"classes": { classes: {
id: "classes", id: 'classes',
keys: ["classes"], keys: ['classes'],
label: "Classes", label: 'Classes',
type: ["class"], type: ['class'],
folders: { folders: {
"features": { features: {
id: "features", id: 'features',
keys: ["classes"], keys: ['classes'],
label: "Features", label: 'Features',
type: ["feature"] type: ['feature']
}, },
"items": { items: {
id: "items", id: 'items',
keys: ["classes"], keys: ['classes'],
label: "Items", label: 'Items',
type: ["armor", "weapon", "consumable", "loot"], type: ['armor', 'weapon', 'consumable', 'loot'],
listType: "items" listType: 'items'
} }
}, },
listType: "classes" listType: 'classes'
}, },
"subclasses": { subclasses: {
id: "subclasses", id: 'subclasses',
keys: ["subclasses"], keys: ['subclasses'],
label: "Subclasses", label: 'Subclasses',
type: ["subclass"], type: ['subclass'],
listType: "subclasses" listType: 'subclasses'
}, },
"domains": { domains: {
id: "domains", id: 'domains',
keys: ["domains"], keys: ['domains'],
label: "Domain Cards", label: 'Domain Cards',
type: ["domainCard"], type: ['domainCard'],
listType: "cards" listType: 'cards'
}, },
"communities": { communities: {
id: "communities", id: 'communities',
keys: ["communities"], keys: ['communities'],
label: "Communities", label: 'Communities',
type: ["community"], type: ['community'],
folders: { folders: {
"features": { features: {
id: "features", id: 'features',
keys: ["communities"], keys: ['communities'],
label: "Features", label: 'Features',
type: ["feature"] type: ['feature']
} }
} }
}, },
"environments": { environments: {
id: "environments", id: 'environments',
keys: ["environments"], keys: ['environments'],
label: "Environments", label: 'Environments',
type: ["environment"] type: ['environment']
}, },
"beastforms": { beastforms: {
id: "beastforms", id: 'beastforms',
keys: ["beastforms"], keys: ['beastforms'],
label: "Beastforms", label: 'Beastforms',
type: ["beastform"], type: ['beastform'],
listType: "beastforms", listType: 'beastforms',
folders: { folders: {
"features": { features: {
id: "features", id: 'features',
keys: ["beastforms"], keys: ['beastforms'],
label: "Features", label: 'Features',
type: ["feature"] type: ['feature']
}
} }
} }
} }
} }
} }
};

View file

@ -1,3 +1,4 @@
import ForeignDocumentUUIDField from '../fields/foreignDocumentUUIDField.mjs';
import ItemLinkFields from '../fields/itemLinkFields.mjs'; import ItemLinkFields from '../fields/itemLinkFields.mjs';
import BaseDataItem from './base.mjs'; import BaseDataItem from './base.mjs';
@ -25,7 +26,8 @@ export default class DHSubclass extends BaseDataItem {
}), }),
features: new ItemLinkFields(), features: new ItemLinkFields(),
featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }), featureState: new fields.NumberField({ required: true, initial: 1, min: 1 }),
isMulticlass: new fields.BooleanField({ initial: false }) isMulticlass: new fields.BooleanField({ initial: false }),
linkedClass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true, initial: null })
}; };
} }