diff --git a/lang/en.json b/lang/en.json index 6fc88758..a18527d0 100755 --- a/lang/en.json +++ b/lang/en.json @@ -693,6 +693,10 @@ "Name": "Greedy", "Description": "Spend a handful of gold to gain a +1 bonus to your Proficiency on a damage roll." }, + "Healing": { + "Name": "Healing", + "Description": "During downtime, automatically clear a Hit Point." + }, "Heavy": { "Name": "Heavy", "Description": "-1 to Evasion" @@ -717,6 +721,10 @@ "Name": "Locked On", "Description": "On a successful attack, your next attack against the same target with your primary weapon automatically succeeds." }, + "Lucky": { + "Name": "Lucky", + "Description": "On a failed attack, you can mark a Stress to reroll your attack." + }, "Long": { "Name": "Long", "Description": "This weapon's attack targets all adversaries in a line within range." diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index b0cbb9aa..a2a786b9 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -260,11 +260,40 @@ export const weaponFeatures = { }, charged: { label: 'DAGGERHEART.WeaponFeature.Charged.Name', - description: 'DAGGERHEART.WeaponFeature.Charged.Description' + description: 'DAGGERHEART.WeaponFeature.Charged.Description', + actions: [ + { + type: 'effect', + name: 'DAGGERHEART.WeaponFeature.Concussive.Name', + img: 'icons/skills/melee/shield-damaged-broken-brown.webp', + actionType: 'action', + cost: [ + { + type: 'stress', + value: 1 + } + ] + // Should add an effect with path system.proficiency.bonus +1 + } + ] }, concussive: { label: 'DAGGERHEART.WeaponFeature.Concussive.Name', - description: 'DAGGERHEART.WeaponFeature.Concussive.Description' + description: 'DAGGERHEART.WeaponFeature.Concussive.Description', + actions: [ + { + type: 'resource', + name: 'DAGGERHEART.WeaponFeature.Concussive.Name', + img: 'icons/skills/melee/shield-damaged-broken-brown.webp', + actionType: 'action', + cost: [ + { + type: 'hope', + value: 1 + } + ] + } + ] }, cumbersome: { label: 'DAGGERHEART.WeaponFeature.Cumbersome.Name', @@ -288,6 +317,16 @@ export const weaponFeatures = { deflecting: { label: 'DAGGERHEART.WeaponFeature.Deflecting.Name', description: 'DAGGERHEART.WeaponFeature.Deflecting.Description' + // actions: [{ + // type: 'effect', + // name: 'DAGGERHEART.WeaponFeature.Deflecting.Name', + // img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', + // actionType: 'reaction', + // cost: [{ + // type: 'armorSlot', // Needs armorSlot as type + // value: 1 + // }], + // }], }, destructive: { label: 'DAGGERHEART.WeaponFeature.Destructive.Name', @@ -306,7 +345,21 @@ export const weaponFeatures = { }, devastating: { label: 'DAGGERHEART.WeaponFeature.Devastating.Name', - description: 'DAGGERHEART.WeaponFeature.Devastating.Description' + description: 'DAGGERHEART.WeaponFeature.Devastating.Description', + actions: [ + { + type: 'resource', + name: 'DAGGERHEART.WeaponFeature.Devastating.Name', + img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', + actionType: 'action', + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, doubleduty: { label: 'DAGGERHEART.WeaponFeature.DoubleDuty.Name', @@ -337,12 +390,47 @@ export const weaponFeatures = { }, grappling: { label: 'DAGGERHEART.WeaponFeature.Grappling.Name', - description: 'DAGGERHEART.WeaponFeature.Grappling.Description' + description: 'DAGGERHEART.WeaponFeature.Grappling.Description', + actions: [ + { + type: 'resource', + name: 'DAGGERHEART.WeaponFeature.Grappling.Name', + img: 'icons/magic/control/debuff-chains-ropes-net-white.webp', + actionType: 'action', + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, greedy: { label: 'DAGGERHEART.WeaponFeature.Greedy.Name', description: 'DAGGERHEART.WeaponFeature.Greedy.Description' }, + healing: { + label: 'DAGGERHEART.WeaponFeature.Healing.Name', + description: 'DAGGERHEART.WeaponFeature.Healing.Description', + actions: [ + { + type: 'healing', + name: 'DAGGERHEART.WeaponFeature.Healing.Name', + img: 'icons/magic/life/cross-beam-green.webp', + actionType: 'action', + healing: { + type: 'health', + value: { + custom: { + enabled: true, + formula: '1' + } + } + } + } + ] + }, heavy: { label: 'DAGGERHEART.WeaponFeature.Heavy.Name', description: 'DAGGERHEART.WeaponFeature.Heavy.Description', @@ -382,6 +470,24 @@ export const weaponFeatures = { label: 'DAGGERHEART.WeaponFeature.Long.Name', description: 'DAGGERHEART.WeaponFeature.Long.Description' }, + lucky: { + label: 'DAGGERHEART.WeaponFeature.Lucky.Name', + description: 'DAGGERHEART.WeaponFeature.Lucky.Description', + actions: [ + { + type: 'resource', + name: 'DAGGERHEART.WeaponFeature.Lucky.Name', + img: 'icons/magic/control/buff-luck-fortune-green.webp', + actionType: 'action', + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] + }, massive: { label: 'DAGGERHEART.WeaponFeature.Massive.Name', description: 'DAGGERHEART.WeaponFeature.Massive.Description', @@ -399,7 +505,21 @@ export const weaponFeatures = { }, painful: { label: 'DAGGERHEART.WeaponFeature.Painful.Name', - description: 'DAGGERHEART.WeaponFeature.Painful.Description' + description: 'DAGGERHEART.WeaponFeature.Painful.Description', + actions: [ + { + type: 'resource', + name: 'DAGGERHEART.WeaponFeature.Painful.Name', + img: 'icons/skills/wounds/injury-face-impact-orange.webp', + actionType: 'action', + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, paired: { label: 'DAGGERHEART.WeaponFeature.Paired.Name', @@ -441,7 +561,21 @@ export const weaponFeatures = { }, quick: { label: 'DAGGERHEART.WeaponFeature.Quick.Name', - description: 'DAGGERHEART.WeaponFeature.Quick.Description' + description: 'DAGGERHEART.WeaponFeature.Quick.Description', + actions: [ + { + type: 'resource', + name: 'DAGGERHEART.WeaponFeature.Quick.Name', + img: 'icons/skills/movement/arrow-upward-yellow.webp', + actionType: 'action', + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, reliable: { label: 'DAGGERHEART.WeaponFeature.Reliable.Name', @@ -488,7 +622,21 @@ export const weaponFeatures = { }, startling: { label: 'DAGGERHEART.WeaponFeature.Startling.Name', - description: 'DAGGERHEART.WeaponFeature.Startling.Description' + description: 'DAGGERHEART.WeaponFeature.Startling.Description', + actions: [ + { + type: 'resource', + name: 'DAGGERHEART.WeaponFeature.Startling.Name', + img: 'icons/magic/control/fear-fright-mask-orange.webp', + actionType: 'action', + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, timebending: { label: 'DAGGERHEART.WeaponFeature.Timebending.Name', diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 7a17b8a7..b0fdf0ae 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -18,13 +18,14 @@ export default class DHArmor extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), - tier: new fields.NumberField({ required: true, integer: true, initial: 1 }), + tier: new fields.NumberField({ required: true, integer: true, initial: 1, min: 1 }), equipped: new fields.BooleanField({ initial: false }), baseScore: new fields.NumberField({ integer: true, initial: 0 }), features: new fields.ArrayField( new fields.SchemaField({ value: new fields.StringField({ required: true, choices: SYSTEM.ITEM.armorFeatures, blank: true }), - effectIds: new fields.ArrayField(new fields.StringField({ required: true })) + effectIds: new fields.ArrayField(new fields.StringField({ required: true })), + actionIds: new fields.ArrayField(new fields.StringField({ required: true })) }) ), marks: new fields.SchemaField({ @@ -55,6 +56,8 @@ export default class DHArmor extends BaseDataItem { for (var effectId of feature.effectIds) { await this.parent.effects.get(effectId).delete(); } + + changes.system.actions = this.actions.filter(x => !feature.actionIds.includes(x._id)); } for (var feature of added) { @@ -69,6 +72,17 @@ export default class DHArmor extends BaseDataItem { ]); feature.effectIds = embeddedItems.map(x => x.id); } + if (featureData.actions?.length > 0) { + const newActions = featureData.actions.map(action => { + const cls = actionsTypes[action.type]; + return new cls( + { ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) }, + { parent: this } + ); + }); + changes.system.actions = [...this.actions, ...newActions]; + feature.actionIds = newActions.map(x => x._id); + } } } } diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 71279b7a..3da7705e 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -2,6 +2,7 @@ import BaseDataItem from './base.mjs'; import FormulaField from '../fields/formulaField.mjs'; import ActionField from '../fields/actionField.mjs'; import { weaponFeatures } from '../../config/itemConfig.mjs'; +import { actionsTypes } from '../../data/_module.mjs'; export default class DHWeapon extends BaseDataItem { /** @inheritDoc */ @@ -22,7 +23,7 @@ export default class DHWeapon extends BaseDataItem { const fields = foundry.data.fields; return { ...super.defineSchema(), - tier: new fields.NumberField({ required: true, integer: true, initial: 1 }), + tier: new fields.NumberField({ required: true, integer: true, initial: 1, min: 1 }), equipped: new fields.BooleanField({ initial: false }), //SETTINGS @@ -42,7 +43,8 @@ export default class DHWeapon extends BaseDataItem { features: new fields.ArrayField( new fields.SchemaField({ value: new fields.StringField({ required: true, choices: SYSTEM.ITEM.weaponFeatures, blank: true }), - effectIds: new fields.ArrayField(new fields.StringField({ required: true })) + effectIds: new fields.ArrayField(new fields.StringField({ required: true })), + actionIds: new fields.ArrayField(new fields.StringField({ required: true })) }) ), actions: new fields.ArrayField(new ActionField()) @@ -61,6 +63,8 @@ export default class DHWeapon extends BaseDataItem { for (var effectId of feature.effectIds) { await this.parent.effects.get(effectId).delete(); } + + changes.system.actions = this.actions.filter(x => !feature.actionIds.includes(x._id)); } for (var feature of added) { @@ -75,6 +79,17 @@ export default class DHWeapon extends BaseDataItem { ]); feature.effectIds = embeddedItems.map(x => x.id); } + if (featureData.actions?.length > 0) { + const newActions = featureData.actions.map(action => { + const cls = actionsTypes[action.type]; + return new cls( + { ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) }, + { parent: this } + ); + }); + changes.system.actions = [...this.actions, ...newActions]; + feature.actionIds = newActions.map(x => x._id); + } } } }