Skip to content

Commit 1c0680c

Browse files
authored
Refactor the skill hooks and rolls into base skill data model (#832)
* Refactor the skill hooks and rolls into base skill data model * Clean up deprecation warnings * Refactor heroic skills
1 parent c7e284f commit 1c0680c

File tree

4 files changed

+215
-459
lines changed

4 files changed

+215
-459
lines changed
Lines changed: 24 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,36 @@
1-
import { ProgressDataModel } from '../common/progress-data-model.mjs';
2-
import { CheckHooks } from '../../../checks/check-hooks.mjs';
31
import { FU } from '../../../helpers/config.mjs';
4-
import { deprecationNotice } from '../../../helpers/deprecation-helper.mjs';
5-
import { CommonSections } from '../../../checks/common-sections.mjs';
6-
import { FUSubTypedItemDataModel } from '../item-data-model.mjs';
72
import { ItemPartialTemplates } from '../item-partial-templates.mjs';
8-
9-
/** @type RenderCheckHook */
10-
Hooks.on(CheckHooks.renderCheck, (data, check, actor, item) => {
11-
if (item?.system instanceof HeroicSkillDataModel) {
12-
CommonSections.tags(data.sections, [
13-
{
14-
tag: FU.heroicType[item.system.subtype.value],
15-
},
16-
{
17-
tag: 'FU.Class',
18-
separator: ':',
19-
value: item.system.class.value,
20-
show: item.system.class.value,
21-
},
22-
]);
23-
24-
if (item.system.requirement.value)
25-
data.sections.push({
26-
content: `
27-
<div class='chat-desc'>
28-
<p><strong>${game.i18n.localize('FU.Requirements')}: </strong>${item.system.requirement.value}</p>
29-
</div>`,
30-
});
31-
32-
if (item.system.hasResource.value) {
33-
CommonSections.resource(data.sections, item.system.rp);
34-
}
35-
36-
CommonSections.description(data.sections, item.system.description, item.system.summary.value);
37-
}
38-
});
3+
import { TraitUtils } from '../../../pipelines/traits.mjs';
4+
import { BaseSkillDataModel } from '../skill/base-skill-data-model.mjs';
395

406
/**
417
* @property {string} subtype.value
42-
* @property {string} summary.value
43-
* @property {string} description
44-
* @property {boolean} showTitleCard.value
458
* @property {string} class.value
469
* @property {string} requirement.value
47-
* @property {string} source.value
10+
* @property {string} description
11+
* @property {string} opportunity
12+
* @property {UseWeaponDataModelV2} useWeapon
13+
* @property {ItemAttributesDataModelV2} attributes
14+
* @property {number} accuracy
15+
* @property {Defense} defense
16+
* @property {DamageDataModelV2} damage
17+
* @property {EffectApplicationDataModel} effects
18+
* @property {ActionCostDataModel} cost
19+
* @property {TargetingDataModel} targeting
20+
* @property {Set<String>} traits
4821
*/
49-
export class HeroicSkillDataModel extends FUSubTypedItemDataModel {
50-
static {
51-
deprecationNotice(this, 'level.min');
52-
deprecationNotice(this, 'level.value');
53-
deprecationNotice(this, 'level.max');
54-
deprecationNotice(this, 'useWeapon.accuracy.value');
55-
deprecationNotice(this, 'useWeapon.damage.value');
56-
deprecationNotice(this, 'useWeapon.hrZero.value');
57-
deprecationNotice(this, 'attributes.primary.value');
58-
deprecationNotice(this, 'attributes.secondary.value');
59-
deprecationNotice(this, 'accuracy.value');
60-
deprecationNotice(this, 'damage.hasDamage.value');
61-
deprecationNotice(this, 'damage.value');
62-
deprecationNotice(this, 'damage.type.value');
63-
deprecationNotice(this, 'impdamage.hasImpDamage.value');
64-
deprecationNotice(this, 'impdamage.value');
65-
deprecationNotice(this, 'impdamage.impType.value');
66-
deprecationNotice(this, 'impdamage.type.value');
67-
deprecationNotice(this, 'benefits.resources.hp.value');
68-
deprecationNotice(this, 'benefits.resources.mp.value');
69-
deprecationNotice(this, 'benefits.resources.ip.value');
70-
}
71-
22+
export class HeroicSkillDataModel extends BaseSkillDataModel {
7223
static defineSchema() {
73-
const { SchemaField, StringField, BooleanField, EmbeddedDataField } = foundry.data.fields;
24+
const { SchemaField, StringField } = foundry.data.fields;
7425
return Object.assign(super.defineSchema(), {
26+
subtype: new SchemaField({ value: new StringField() }),
7527
class: new SchemaField({ value: new StringField() }),
76-
hasResource: new SchemaField({ value: new BooleanField() }),
77-
rp: new EmbeddedDataField(ProgressDataModel, {}),
7828
requirement: new SchemaField({ value: new StringField() }),
7929
});
8030
}
8131

8232
get attributePartials() {
83-
return [ItemPartialTemplates.standard, ItemPartialTemplates.classField, ItemPartialTemplates.heroicSkill, ItemPartialTemplates.resourcePoints];
33+
return [...this.commonPartials, ItemPartialTemplates.classField, ItemPartialTemplates.heroicSkill];
8434
}
8535

8636
/**
@@ -93,4 +43,11 @@ export class HeroicSkillDataModel extends FUSubTypedItemDataModel {
9343
'system.rp': this.rp.getProgressUpdate(event, target, { indirect: { dataAttribute: 'data-resource-action', attributeValueIncrement: 'increment', attributeValueDecrement: 'decrement' } }),
9444
});
9545
}
46+
47+
/**
48+
* @override
49+
*/
50+
getTags() {
51+
return [{ tag: 'FU.Class', separator: ':', value: this.class.value, show: this.class.value }, { tag: FU.heroicType[this.subtype.value] }, ...TraitUtils.toTags(this.traits)];
52+
}
9653
}

module/documents/items/misc/misc-ability-data-model.mjs

Lines changed: 2 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,86 +1,7 @@
11
import { ProgressDataModel } from '../common/progress-data-model.mjs';
22
import { MiscAbilityMigrations } from './misc-ability-migrations.mjs';
3-
import { CheckHooks } from '../../../checks/check-hooks.mjs';
4-
import { deprecationNotice } from '../../../helpers/deprecation-helper.mjs';
5-
import { Checks } from '../../../checks/checks.mjs';
6-
import { CheckConfiguration } from '../../../checks/check-configuration.mjs';
7-
import { ChooseWeaponDialog } from '../skill/choose-weapon-dialog.mjs';
8-
import { CHECK_DETAILS } from '../../../checks/default-section-order.mjs';
9-
import { CommonSections } from '../../../checks/common-sections.mjs';
103
import { ItemPartialTemplates } from '../item-partial-templates.mjs';
11-
import { TraitUtils } from '../../../pipelines/traits.mjs';
124
import { BaseSkillDataModel } from '../skill/base-skill-data-model.mjs';
13-
import { CommonEvents } from '../../../checks/common-events.mjs';
14-
15-
const skillForAttributeCheck = 'skillForAttributeCheck';
16-
17-
/**
18-
* @type RenderCheckHook
19-
*/
20-
let onRenderAccuracyCheck = async (data, check, actor, item, flags) => {
21-
if (check.type === 'accuracy' && item?.system instanceof MiscAbilityDataModel) {
22-
const inspector = CheckConfiguration.inspect(check);
23-
const weapon = await fromUuid(inspector.getWeaponReference());
24-
if (check.critical) {
25-
CommonSections.opportunity(data.sections, item.system.opportunity, CHECK_DETAILS);
26-
}
27-
CommonSections.description(data.sections, item.system.description, item.system.summary.value, CHECK_DETAILS);
28-
if (item.system.hasClock.value) {
29-
CommonSections.clock(data.sections, item.system.progress, CHECK_DETAILS);
30-
}
31-
32-
// Tag info
33-
let tags = [];
34-
tags.push(...TraitUtils.toTags(item.system.traits));
35-
if (weapon) {
36-
if (weapon.system.getTags instanceof Function) {
37-
tags.push(...weapon.system.getTags(item.system.useWeapon.traits));
38-
}
39-
}
40-
CommonSections.tags(data.sections, tags, CHECK_DETAILS);
41-
}
42-
};
43-
Hooks.on(CheckHooks.renderCheck, onRenderAccuracyCheck);
44-
45-
/**
46-
* @type RenderCheckHook
47-
*/
48-
let onRenderAttributeCheck = async (data, check, actor, item, flags) => {
49-
if (check.type === 'attribute' && item?.system instanceof MiscAbilityDataModel && check.additionalData[skillForAttributeCheck]) {
50-
const inspector = CheckConfiguration.inspect(check);
51-
const ability = await fromUuid(inspector.getWeaponReference());
52-
CommonSections.itemFlavor(data.sections, ability);
53-
if (check.critical) {
54-
CommonSections.opportunity(data.sections, ability.system.opportunity, CHECK_DETAILS);
55-
}
56-
CommonSections.description(data.sections, ability.system.description, ability.system.summary.value, CHECK_DETAILS, true);
57-
if (ability.system.hasClock.value) {
58-
CommonSections.clock(data.sections, item.system.progress, CHECK_DETAILS);
59-
}
60-
}
61-
};
62-
63-
Hooks.on(CheckHooks.renderCheck, onRenderAttributeCheck);
64-
65-
/**
66-
* @type RenderCheckHook
67-
*/
68-
const onRenderDisplay = (data, check, actor, item, flags) => {
69-
if (check.type === 'display' && item?.system instanceof MiscAbilityDataModel) {
70-
const skill = item.system;
71-
CommonSections.tags(data.sections, skill.getCommonTags(), CHECK_DETAILS);
72-
if (item.system.hasResource.value) {
73-
CommonSections.resource(data.sections, item.system.rp, CHECK_DETAILS);
74-
}
75-
CommonSections.description(data.sections, item.system.description, item.system.summary.value, CHECK_DETAILS);
76-
const inspector = CheckConfiguration.inspect(check);
77-
const targets = inspector.getTargetsOrDefault();
78-
CommonSections.actions(data, actor, item, targets, flags, inspector);
79-
CommonEvents.skill(actor, item);
80-
}
81-
};
82-
83-
Hooks.on(CheckHooks.renderCheck, onRenderDisplay);
845

856
/**
867
* @property {string} subtype.value
@@ -107,22 +28,6 @@ Hooks.on(CheckHooks.renderCheck, onRenderDisplay);
10728
* @property {Set<String>} traits
10829
*/
10930
export class MiscAbilityDataModel extends BaseSkillDataModel {
110-
static {
111-
deprecationNotice(this, 'rollInfo.useWeapon.accuracy.value', 'useWeapon.accuracy');
112-
deprecationNotice(this, 'rollInfo.useWeapon.damage.value', 'useWeapon.damage');
113-
deprecationNotice(this, 'rollInfo.useWeapon.hrZero.value', 'damage.hrZero');
114-
deprecationNotice(this, 'rollInfo.attributes.primary.value', 'attributes.primary');
115-
deprecationNotice(this, 'rollInfo.attributes.secondary.value', 'attributes.secondary');
116-
deprecationNotice(this, 'rollInfo.accuracy.value', 'accuracy');
117-
deprecationNotice(this, 'rollInfo.damage.hasDamage.value', 'damage.hasDamage');
118-
deprecationNotice(this, 'rollInfo.damage.value', 'damage.value');
119-
deprecationNotice(this, 'rollInfo.damage.type.value', 'damage.type');
120-
deprecationNotice(this, 'impdamage.hasImpDamage.value');
121-
deprecationNotice(this, 'impdamage.value');
122-
deprecationNotice(this, 'impdamage.impType.value');
123-
deprecationNotice(this, 'impdamage.type.value');
124-
}
125-
12631
static defineSchema() {
12732
const { SchemaField, StringField, BooleanField, NumberField, EmbeddedDataField } = foundry.data.fields;
12833
return Object.assign(super.defineSchema(), {
@@ -140,75 +45,8 @@ export class MiscAbilityDataModel extends BaseSkillDataModel {
14045
return source;
14146
}
14247

143-
/**
144-
* @param {KeyboardModifiers} modifiers
145-
* @return {Promise<void>}
146-
*/
147-
async roll(modifiers) {
148-
if (this.hasRoll.value) {
149-
if (this.useWeapon.accuracy) {
150-
return Checks.accuracyCheck(this.parent.actor, this.parent, this.#initializeAccuracyCheck(modifiers));
151-
} else {
152-
return Checks.attributeCheck(
153-
this.parent.actor,
154-
{
155-
primary: this.attributes.primary,
156-
secondary: this.attributes.secondary,
157-
},
158-
this.parent,
159-
this.#initializeAttributeCheck(modifiers),
160-
);
161-
}
162-
}
163-
return Checks.display(this.parent.actor, this.parent, this.#initializeSkillDisplay(modifiers));
164-
}
165-
166-
/**
167-
* @param {KeyboardModifiers} modifiers
168-
* @return {CheckCallback}
169-
* @remarks Expects a weapon
170-
*/
171-
#initializeSkillDisplay(modifiers) {
172-
return async (check, actor, item) => {
173-
const config = CheckConfiguration.configure(check);
174-
await this.configureDisplayCheck(config, actor, item);
175-
};
176-
}
177-
178-
/**
179-
* @return {CheckCallback}
180-
*/
181-
#initializeAttributeCheck(modifiers) {
182-
return async (check, actor, item) => {
183-
await this.configureAttributeCheck(modifiers, check, actor, item);
184-
};
185-
}
186-
187-
/**
188-
* @param modifiers
189-
* @return {CheckCallback}
190-
*/
191-
#initializeAccuracyCheck(modifiers) {
192-
return async (check, actor, item) => {
193-
const weapon = await ChooseWeaponDialog.prompt(actor, true);
194-
if (weapon === false) {
195-
let message = game.i18n.localize('FU.AbilityNoWeaponEquipped');
196-
ui.notifications.error(message);
197-
throw new Error(message);
198-
}
199-
if (weapon == null) {
200-
throw new Error('no selection');
201-
}
202-
const { check: weaponCheck, error } = await Checks.prepareCheckDryRun('accuracy', actor, weapon);
203-
if (error) {
204-
throw error;
205-
}
206-
207-
check.primary = weaponCheck.primary;
208-
check.secondary = weaponCheck.secondary;
209-
210-
return this.configureAccuracyCheck(modifiers, check, actor, item, weapon);
211-
};
48+
getTags() {
49+
return super.getTags();
21250
}
21351

21452
get attributePartials() {

0 commit comments

Comments
 (0)