diff --git a/daggerheart.mjs b/daggerheart.mjs index 2eb5109f..0518a4cf 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -43,7 +43,6 @@ CONFIG.Item.dataModels = models.items.config; CONFIG.ActiveEffect.documentClass = documents.DhActiveEffect; CONFIG.ActiveEffect.dataModels = models.activeEffects.config; -CONFIG.ActiveEffect.changeTypes = { ...CONFIG.ActiveEffect.changeTypes, ...models.activeEffects.changeEffects }; CONFIG.Combat.documentClass = documents.DhpCombat; CONFIG.Combat.dataModels = { base: models.DhCombat }; @@ -212,7 +211,6 @@ Hooks.once('init', () => { SYSTEM.id, applications.sheetConfigs.ActiveEffectConfig, { - types: ['base', 'beastform', 'horde'], makeDefault: true, label: sheetLabel('DOCUMENT.ActiveEffect') } @@ -270,6 +268,7 @@ Hooks.on('setup', () => { ...damageThresholds, 'proficiency', 'evasion', + 'armorScore', 'scars', 'levelData.level.current' ] diff --git a/lang/en.json b/lang/en.json index aa379c6f..e2773836 100755 --- a/lang/en.json +++ b/lang/en.json @@ -454,7 +454,7 @@ "text": "Are you sure you want to delete {name}?" }, "DamageReduction": { - "maxUseableArmor": "Useable Armor Slots", + "armorMarks": "Armor Marks", "armorWithStress": "Spend 1 stress to use an extra mark", "thresholdImmunities": "Threshold Immunities", "stress": "Stress", @@ -800,11 +800,6 @@ "bruiser": "for each Bruiser adversary.", "solo": "for each Solo adversary." }, - "ArmorInteraction": { - "none": { "label": "Ignores Armor" }, - "active": { "label": "Active w/ Armor" }, - "inactive": { "label": "Inactive w/ Armor" } - }, "ArmorFeature": { "burning": { "name": "Burning", @@ -1900,17 +1895,6 @@ "name": "Healing Roll" } }, - "ChangeTypes": { - "armor": { - "newArmorEffect": "Armor Effect", - "FIELDS": { - "interaction": { - "label": "Armor Interaction", - "hint": "Does the character wearing armor suppress this effect?" - } - } - } - }, "Duration": { "passive": "Passive", "temporary": "Temporary" @@ -2326,7 +2310,6 @@ "duality": "Duality", "dualityDice": "Duality Dice", "dualityRoll": "Duality Roll", - "effect": "Effect", "enabled": "Enabled", "evasion": "Evasion", "equipment": "Equipment", @@ -3134,9 +3117,6 @@ "knowTheTide": "Know The Tide gained a token", "lackingItemTransferPermission": "User {user} lacks owner permission needed to transfer items to {target}" }, - "Progress": { - "migrationLabel": "Performing system migration. Please wait and do not close Foundry." - }, "Sidebar": { "actorDirectory": { "tier": "Tier {tier} {type}", diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 930ca1a1..cd0a5cf7 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -1,4 +1,4 @@ -import { damageKeyToNumber, getArmorSources, getDamageLabel } from '../../helpers/utils.mjs'; +import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs'; const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; @@ -10,7 +10,6 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.reject = reject; this.actor = actor; this.damage = damage; - this.damageType = damageType; this.rulesDefault = game.settings.get( CONFIG.DH.id, @@ -21,20 +20,14 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.rulesDefault ); - const orderedArmorSources = getArmorSources(actor).filter(s => !s.disabled); - const armor = orderedArmorSources.reduce((acc, { document }) => { - const { current, max } = document.type === 'armor' ? document.system.armor : document.system.armorData; - acc.push({ - effect: document, - marks: [...Array(max).keys()].reduce((acc, _, index) => { - const spent = index < current; - acc[foundry.utils.randomID()] = { selected: false, disabled: spent, spent }; - return acc; - }, {}) - }); + const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true); + const availableArmor = actor.system.armorScore - actor.system.armor.system.marks.value; + const maxArmorMarks = canApplyArmor ? availableArmor : 0; + const armor = [...Array(maxArmorMarks).keys()].reduce((acc, _) => { + acc[foundry.utils.randomID()] = { selected: false }; return acc; - }, []); + }, {}); const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce( (acc, _) => { acc[foundry.utils.randomID()] = { selected: false }; @@ -128,11 +121,13 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap context.thresholdImmunities = Object.keys(this.thresholdImmunities).length > 0 ? this.thresholdImmunities : null; - const { selectedStressMarks, stressReductions, currentMarks, currentDamage, maxArmorUsed, availableArmor } = + const { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage } = this.getDamageInfo(); - context.armorScore = this.actor.system.armorScore.max; + context.armorScore = this.actor.system.armorScore; context.armorMarks = currentMarks; + context.basicMarksUsed = + selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.value; const stressReductionStress = this.availableStressReductions ? stressReductions.reduce((acc, red) => acc + red.cost, 0) @@ -146,30 +141,16 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap } : null; - context.maxArmorUsed = maxArmorUsed; - context.availableArmor = availableArmor; - context.basicMarksUsed = availableArmor === 0 || selectedStressMarks.length; - - const armorSources = []; - for (const source of this.marks.armor) { - const parent = source.effect.origin - ? await foundry.utils.fromUuid(source.effect.origin) - : source.effect.parent; - - const useEffectName = parent.type === 'armor' || parent instanceof Actor; - const label = useEffectName ? source.effect.name : parent.name; - armorSources.push({ - label: label, - uuid: source.effect.uuid, - marks: source.marks - }); - } + const maxArmor = this.actor.system.rules.damageReduction.maxArmorMarked.value; context.marks = { - armor: armorSources, + armor: Object.keys(this.marks.armor).reduce((acc, key, index) => { + const mark = this.marks.armor[key]; + if (!this.rulesOn || index + 1 <= maxArmor) acc[key] = mark; + + return acc; + }, {}), stress: this.marks.stress }; - - context.usesStressArmor = Object.keys(context.marks.stress).length; context.availableStressReductions = this.availableStressReductions; context.damage = getDamageLabel(this.damage); @@ -186,31 +167,27 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap } getDamageInfo = () => { - const selectedArmorMarks = this.marks.armor.flatMap(x => Object.values(x.marks).filter(x => x.selected)); + const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected); const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected); const stressReductions = this.availableStressReductions ? Object.values(this.availableStressReductions).filter(red => red.selected) : []; - const currentMarks = this.actor.system.armorScore.value + selectedArmorMarks.length; - - const maxArmorUsed = this.actor.system.rules.damageReduction.maxArmorMarked.value + selectedStressMarks.length; - const availableArmor = - maxArmorUsed - - this.marks.armor.reduce((acc, source) => { - acc += Object.values(source.marks).filter(x => x.selected).length; - return acc; - }, 0); + const currentMarks = + this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length; const armorMarkReduction = selectedArmorMarks.length * this.actor.system.rules.damageReduction.increasePerArmorMark; - let currentDamage = Math.max(this.damage - armorMarkReduction - stressReductions.length, 0); + let currentDamage = Math.max( + this.damage - armorMarkReduction - selectedStressMarks.length - stressReductions.length, + 0 + ); if (this.reduceSeverity) { currentDamage = Math.max(currentDamage - this.reduceSeverity, 0); } if (this.thresholdImmunities[currentDamage]) currentDamage = 0; - return { selectedStressMarks, stressReductions, currentMarks, currentDamage, maxArmorUsed, availableArmor }; + return { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage }; }; static toggleRules() { @@ -218,10 +195,13 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap const maxArmor = this.actor.system.rules.damageReduction.maxArmorMarked.value; this.marks = { - armor: this.marks.armor.map((mark, index) => { + armor: Object.keys(this.marks.armor).reduce((acc, key, index) => { + const mark = this.marks.armor[key]; const keepSelectValue = !this.rulesOn || index + 1 <= maxArmor; - return { ...mark, selected: keepSelectValue ? mark.selected : false }; - }), + acc[key] = { ...mark, selected: keepSelectValue ? mark.selected : false }; + + return acc; + }, {}), stress: this.marks.stress }; @@ -229,8 +209,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap } static setMarks(_, target) { - const currentMark = foundry.utils.getProperty(this.marks, target.dataset.path); - const { selectedStressMarks, stressReductions, currentDamage, availableArmor } = this.getDamageInfo(); + const currentMark = this.marks[target.dataset.type][target.dataset.key]; + const { selectedStressMarks, stressReductions, currentMarks, currentDamage } = this.getDamageInfo(); if (!currentMark.selected && currentDamage === 0) { ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.damageAlreadyNone')); @@ -238,18 +218,12 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap } if (this.rulesOn) { - if (target.dataset.type === 'armor' && !currentMark.selected && !availableArmor) { + if (!currentMark.selected && currentMarks === this.actor.system.armorScore) { ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noAvailableArmorMarks')); return; } } - const stressUsed = selectedStressMarks.length; - if (target.dataset.type === 'armor' && stressUsed) { - const updateResult = this.updateStressArmor(target.dataset.id, !currentMark.selected); - if (updateResult === false) return; - } - if (currentMark.selected) { const currentDamageLabel = getDamageLabel(currentDamage); for (let reduction of stressReductions) { @@ -258,16 +232,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap } } - if (target.dataset.type === 'stress' && currentMark.armorMarkId) { - for (const source of this.marks.armor) { - const match = Object.keys(source.marks).find(key => key === currentMark.armorMarkId); - if (match) { - source.marks[match].selected = false; - break; - } - } - - currentMark.armorMarkId = null; + if (target.dataset.type === 'armor' && selectedStressMarks.length > 0) { + selectedStressMarks.forEach(mark => (mark.selected = false)); } } @@ -275,25 +241,6 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.render(); } - updateStressArmor(armorMarkId, select) { - let stressMarkKey = null; - if (select) { - stressMarkKey = Object.keys(this.marks.stress).find( - key => this.marks.stress[key].selected && !this.marks.stress[key].armorMarkId - ); - } else { - stressMarkKey = Object.keys(this.marks.stress).find( - key => this.marks.stress[key].armorMarkId === armorMarkId - ); - if (!stressMarkKey) - stressMarkKey = Object.keys(this.marks.stress).find(key => this.marks.stress[key].selected); - } - - if (!stressMarkKey) return false; - - this.marks.stress[stressMarkKey].armorMarkId = select ? armorMarkId : null; - } - static useStressReduction(_, target) { const damageValue = Number(target.dataset.reduction); const stressReduction = this.availableStressReductions[damageValue]; @@ -332,18 +279,11 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap } static async takeDamage() { - const { selectedStressMarks, stressReductions, currentDamage } = this.getDamageInfo(); - const armorChanges = this.marks.armor.reduce((acc, source) => { - const amount = Object.values(source.marks).filter(x => x.selected).length; - if (amount) acc.push({ uuid: source.effect.uuid, amount }); + const { selectedArmorMarks, selectedStressMarks, stressReductions, currentDamage } = this.getDamageInfo(); + const armorSpent = selectedArmorMarks.length + selectedStressMarks.length; + const stressSpent = selectedStressMarks.length + stressReductions.reduce((acc, red) => acc + red.cost, 0); - return acc; - }, []); - const stressSpent = - selectedStressMarks.filter(x => x.armorMarkId).length + - stressReductions.reduce((acc, red) => acc + red.cost, 0); - - this.resolve({ modifiedDamage: currentDamage, armorChanges, stressSpent }); + this.resolve({ modifiedDamage: currentDamage, armorSpent, stressSpent }); await this.close(true); } diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 3475dee7..52cced3e 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -203,7 +203,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV const msg = { user: game.user.id, system: { - moves: moves.map(move => ({ ...move, actions: Array.from(move.actions) })), + moves: moves, actor: this.actor.uuid }, speaker: cls.getSpeaker(), diff --git a/module/applications/sheets-configs/_module.mjs b/module/applications/sheets-configs/_module.mjs index 4b83a042..d3fb3c39 100644 --- a/module/applications/sheets-configs/_module.mjs +++ b/module/applications/sheets-configs/_module.mjs @@ -3,6 +3,7 @@ export { default as ActionSettingsConfig } from './action-settings-config.mjs'; export { default as CharacterSettings } from './character-settings.mjs'; export { default as AdversarySettings } from './adversary-settings.mjs'; export { default as CompanionSettings } from './companion-settings.mjs'; +export { default as SettingActiveEffectConfig } from './setting-active-effect-config.mjs'; export { default as SettingFeatureConfig } from './setting-feature-config.mjs'; export { default as EnvironmentSettings } from './environment-settings.mjs'; export { default as ActiveEffectConfig } from './activeEffectConfig.mjs'; diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index e75e16ab..0dbc377a 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -24,12 +24,9 @@ export default class DHActionConfig extends DHActionBaseConfig { const effectData = this._addEffectData.bind(this)(); const data = this.action.toObject(); - const created = await game.system.api.documents.DhActiveEffect.createDialog(effectData, { - parent: this.action.item, + const [created] = await this.action.item.createEmbeddedDocuments('ActiveEffect', [effectData], { render: false }); - if (!created) return; - data.effects.push({ _id: created._id }); this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) }); this.action.item.effects.get(created._id).sheet.render(true); diff --git a/module/applications/sheets-configs/action-settings-config.mjs b/module/applications/sheets-configs/action-settings-config.mjs index 9cb866bc..91b85802 100644 --- a/module/applications/sheets-configs/action-settings-config.mjs +++ b/module/applications/sheets-configs/action-settings-config.mjs @@ -55,7 +55,7 @@ export default class DHActionSettingsConfig extends DHActionBaseConfig { static async editEffect(event) { const id = event.target.closest('[data-effect-id]')?.dataset?.effectId; - const updatedEffect = await game.system.api.applications.sheetConfigs.ActiveEffectConfig.configureSetting( + const updatedEffect = await game.system.api.applications.sheetConfigs.SettingActiveEffectConfig.configure( this.getEffectDetails(id) ); if (!updatedEffect) return; diff --git a/module/applications/sheets-configs/activeEffectConfig.mjs b/module/applications/sheets-configs/activeEffectConfig.mjs index 3a993da0..d1ba85e0 100644 --- a/module/applications/sheets-configs/activeEffectConfig.mjs +++ b/module/applications/sheets-configs/activeEffectConfig.mjs @@ -4,8 +4,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac constructor(options) { super(options); - this.changeChoices = this.#getChangeChoices(); - this.conditionalChoices = this.#getChangeChoices({ resourceValuePaths: true }); + this.changeChoices = DhActiveEffectConfig.getChangeChoices(); } static DEFAULT_OPTIONS = { @@ -51,7 +50,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac * Get ChangeChoices for the changes autocomplete. Static for use in this class aswell as in settings-active-effect-config.mjs * @returns {ChangeChoice { value: string, label: string, hint: string, group: string }[]} */ - #getChangeChoices(options = { resourceValuePaths: false }) { + static getChangeChoices() { const ignoredActorKeys = ['config', 'DhEnvironment', 'DhParty']; const getAllLeaves = (root, group, parentPath = '') => { @@ -71,8 +70,6 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac return leaves; }; - - const resourcePathEnding = options.resourceValuePaths ? 'value' : 'max'; return Object.keys(game.system.api.models.actors).reduce((acc, key) => { if (ignoredActorKeys.includes(key)) return acc; @@ -81,17 +78,11 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac const attributes = CONFIG.Token.documentClass.getTrackedAttributes(model.metadata.type); const getTranslations = path => { - if (path === 'resources.hope.max') { + if (path === 'resources.hope.max') return { label: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.FIELDS.maxHope.label'), hint: '' }; - } else if (path === 'resources.hope.value') { - return { - label: game.i18n.localize('DAGGERHEART.GENERAL.hope'), - hint: '' - }; - } const field = model.schema.getField(path); return { @@ -101,7 +92,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac }; const bars = attributes.bar.flatMap(x => { - const joined = `${x.join('.')}.${resourcePathEnding}`; + const joined = `${x.join('.')}.max`; return { value: joined, ...getTranslations(joined), group }; }); const values = attributes.value.flatMap(x => { @@ -121,18 +112,16 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); const changeChoices = this.changeChoices; - const conditionalChoices = this.conditionalChoices; htmlElement.querySelectorAll('.effect-change-input').forEach(element => { - const choices = element.classList.contains('conditional-key-input') ? conditionalChoices : changeChoices; autocomplete({ input: element, fetch: function (text, update) { if (!text) { - update(choices); + update(changeChoices); } else { text = text.toLowerCase(); - var suggestions = choices.filter(n => n.label.toLowerCase().includes(text)); + var suggestions = changeChoices.filter(n => n.label.toLowerCase().includes(text)); update(suggestions); } }, @@ -171,14 +160,6 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac minLength: 0 }); }); - - htmlElement - .querySelector('.armor-change-checkbox') - ?.addEventListener('change', this.armorChangeToggle.bind(this)); - - htmlElement - .querySelector('.armor-damage-thresholds-checkbox') - ?.addEventListener('change', this.armorDamageThresholdToggle.bind(this)); } async _prepareContext(options) { @@ -229,66 +210,21 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac })); break; case 'changes': - const singleTypes = ['armor']; - const typedChanges = context.source.changes.reduce((acc, change, index) => { - if (singleTypes.includes(change.type)) { - acc[change.type] = { ...change, index }; - } - return acc; - }, {}); - partContext.changes = partContext.changes.filter(c => !!c); - partContext.typedChanges = typedChanges; + const fields = this.document.system.schema.fields.changes.element.fields; + partContext.changes = await Promise.all( + foundry.utils + .deepClone(context.source.changes) + .map((c, i) => this._prepareChangeContext(c, i, fields)) + ); break; } return partContext; } - armorChangeToggle(event) { - if (event.target.checked) { - this.addArmorChange(); - } else { - this.removeTypedChange(event.target.dataset.index); - } - } - - /* Could be generalised if needed later */ - addArmorChange() { - const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form)); - const changes = Object.values(submitData.system?.changes ?? {}); - changes.push(game.system.api.data.activeEffects.changeTypes.armor.getInitialValue()); - return this.submit({ updateData: { system: { changes } } }); - } - - removeTypedChange(indexString) { - const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form)); - const changes = Object.values(submitData.system.changes); - const index = Number(indexString); - changes.splice(index, 1); - return this.submit({ updateData: { system: { changes } } }); - } - - armorDamageThresholdToggle(event) { - const submitData = this._processFormData(null, this.form, new FormDataExtended(this.form)); - const changes = Object.values(submitData.system?.changes ?? {}); - const index = Number(event.target.dataset.index); - if (event.target.checked) { - changes[index].value.damageThresholds = { major: 0, severe: 0 }; - } else { - changes[index].value.damageThresholds = null; - } - - return this.submit({ updateData: { system: { changes } } }); - } - - /** @inheritdoc */ - _renderChange(context) { - const { change, index, defaultPriority } = context; - if (!(change.type in CONFIG.DH.GENERAL.baseActiveEffectModes)) return null; - - const changeTypesSchema = this.document.system.schema.fields.changes.element.types; - const fields = context.fields ?? (changeTypesSchema[change.type] ?? changeTypesSchema.add).fields; + _prepareChangeContext(change, index, fields) { if (typeof change.value !== 'string') change.value = JSON.stringify(change.value); + const defaultPriority = game.system.api.documents.DhActiveEffect.CHANGE_TYPES[change.type]?.defaultPriority; Object.assign( change, ['key', 'type', 'value', 'priority'].reduce((paths, fieldName) => { @@ -308,11 +244,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac change, index, defaultPriority, - fields, - types: Object.keys(CONFIG.DH.GENERAL.baseActiveEffectModes).reduce((r, key) => { - r[key] = CONFIG.DH.GENERAL.baseActiveEffectModes[key].label; - return r; - }, {}) + fields } ) ); @@ -391,34 +323,4 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac return submitData; } - - /** @inheritDoc */ - _processSubmitData(event, form, submitData, options) { - if (this.options.isSetting) { - // Settings should update source instead - this.document.updateSource(submitData); - this.render(); - } else { - return super._processSubmitData(event, form, submitData, options); - } - } - - /** Creates an active effect config for a setting */ - static async configureSetting(effect, options = {}) { - const document = new CONFIG.ActiveEffect.documentClass({ ...foundry.utils.duplicate(effect), _id: effect.id }); - return new Promise(resolve => { - const app = new this({ document, ...options, isSetting: true }); - app.addEventListener( - 'close', - () => { - const newEffect = app.document.toObject(true); - newEffect.id = newEffect._id; - delete newEffect._id; - resolve(newEffect); - }, - { once: true } - ); - app.render({ force: true }); - }); - } } diff --git a/module/applications/sheets-configs/setting-feature-config.mjs b/module/applications/sheets-configs/setting-feature-config.mjs index f90bb52f..fb790f7f 100644 --- a/module/applications/sheets-configs/setting-feature-config.mjs +++ b/module/applications/sheets-configs/setting-feature-config.mjs @@ -147,7 +147,7 @@ export default class SettingFeatureConfig extends HandlebarsApplicationMixin(App const effectIndex = this.move.effects.findIndex(x => x.id === id); const effect = this.move.effects[effectIndex]; const updatedEffect = - await game.system.api.applications.sheetConfigs.ActiveEffectConfig.configureSetting(effect); + await game.system.api.applications.sheetConfigs.SettingActiveEffectConfig.configure(effect); if (!updatedEffect) return; await this.updateMove({ diff --git a/module/applications/sheets-configs/token-config-mixin.mjs b/module/applications/sheets-configs/token-config-mixin.mjs index bed7f628..5242d797 100644 --- a/module/applications/sheets-configs/token-config-mixin.mjs +++ b/module/applications/sheets-configs/token-config-mixin.mjs @@ -67,9 +67,9 @@ export default function DHTokenConfigMixin(Base) { changes.height = tokenSize; } - // const deletions = { actorId: _del }; - // const mergeOptions = { inplace: false, performDeletions: true, actorLink: false }; - this._preview.updateSource(changes); + const deletions = { actorId: _del, actorLink: _del }; + const mergeOptions = { inplace: false, performDeletions: true }; + this._preview.updateSource(foundry.utils.mergeObject(changes, deletions, mergeOptions)); if (this._preview?.object?.destroyed === false) { this._preview.object.initializeSources(); diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index f2686fdd..db236197 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -3,7 +3,7 @@ import DhDeathMove from '../../dialogs/deathMove.mjs'; import { CharacterLevelup, LevelupViewMode } from '../../levelup/_module.mjs'; import DhCharacterCreation from '../../characterCreation/characterCreation.mjs'; import FilterMenu from '../../ux/filter-menu.mjs'; -import { getArmorSources, getDocFromElement, getDocFromElementSync } from '../../../helpers/utils.mjs'; +import { getDocFromElement, getDocFromElementSync } from '../../../helpers/utils.mjs'; /**@typedef {import('@client/applications/_types.mjs').ApplicationClickAction} ApplicationClickAction */ @@ -34,8 +34,7 @@ export default class CharacterSheet extends DHBaseActorSheet { cancelBeastform: CharacterSheet.#cancelBeastform, toggleResourceManagement: CharacterSheet.#toggleResourceManagement, useDowntime: this.useDowntime, - viewParty: CharacterSheet.#viewParty, - toggleArmorMangement: CharacterSheet.#toggleArmorManagement + viewParty: CharacterSheet.#viewParty }, window: { resizable: true, @@ -639,12 +638,12 @@ export default class CharacterSheet extends DHBaseActorSheet { } async updateArmorMarks(event) { - const inputValue = Number(event.currentTarget.value); - const { value, max } = this.document.system.armorScore; - const changeValue = Math.min(inputValue - value, max - value); + const armor = this.document.system.armor; + if (!armor) return; - event.currentTarget.value = inputValue < 0 ? 0 : value + changeValue; - this.document.system.updateArmorValue({ value: changeValue }); + const maxMarks = this.document.system.armorScore; + const value = Math.min(Math.max(Number(event.currentTarget.value), 0), maxMarks); + await armor.update({ 'system.marks.value': value }); } /* -------------------------------------------- */ @@ -804,13 +803,10 @@ export default class CharacterSheet extends DHBaseActorSheet { * Toggles ArmorScore resource value. * @type {ApplicationClickAction} */ - static async #toggleArmor(_, button, _element) { - const { value, max } = this.document.system.armorScore; - const inputValue = Number.parseInt(button.dataset.value); - const newValue = value >= inputValue ? inputValue - 1 : inputValue; - const changeValue = Math.min(newValue - value, max - value); - - this.document.system.updateArmorValue({ value: changeValue }); + static async #toggleArmor(_, button, element) { + const ArmorValue = Number.parseInt(button.dataset.value); + const newValue = this.document.system.armor.system.marks.value >= ArmorValue ? ArmorValue - 1 : ArmorValue; + await this.document.system.armor.update({ 'system.marks.value': newValue }); } /** @@ -936,99 +932,6 @@ export default class CharacterSheet extends DHBaseActorSheet { }); } - static async #toggleArmorManagement(_event, target) { - const existingTooltip = document.body.querySelector('.locked-tooltip .armor-management-container'); - if (existingTooltip) { - game.tooltip.dismissLockedTooltips(); - return; - } - - const armorSources = getArmorSources(this.document) - .filter(s => !s.disabled) - .toReversed() - .map(({ name, document, data }) => ({ - ...data, - uuid: document.uuid, - name - })); - if (!armorSources.length) return; - - const useResourcePips = game.settings.get( - CONFIG.DH.id, - CONFIG.DH.SETTINGS.gameSettings.appearance - ).useResourcePips; - const html = document.createElement('div'); - html.innerHTML = await foundry.applications.handlebars.renderTemplate( - `systems/daggerheart/templates/ui/tooltip/armorManagement.hbs`, - { - sources: armorSources, - useResourcePips - } - ); - - game.tooltip.dismissLockedTooltips(); - game.tooltip.activate(target, { - html, - locked: true, - cssClass: 'bordered-tooltip', - direction: 'DOWN' - }); - - html.querySelectorAll('.armor-slot').forEach(element => { - element.addEventListener('click', CharacterSheet.armorSourcePipUpdate); - }); - } - - static async armorSourceInput(event) { - const effect = await foundry.utils.fromUuid(event.target.dataset.uuid); - const value = Math.max(Math.min(Number.parseInt(event.target.value), effect.system.armorData.max), 0); - event.target.value = value; - const progressBar = event.target.closest('.status-bar.armor-slots').querySelector('progress'); - progressBar.value = value; - } - - /** Update specific armor source */ - static async armorSourcePipUpdate(event) { - const target = event.target.closest('.armor-slot'); - const { uuid, value } = target.dataset; - const document = await foundry.utils.fromUuid(uuid); - - let inputValue = Number.parseInt(value); - let decreasing = false; - let newCurrent = 0; - - if (document.type === 'armor') { - decreasing = document.system.armor.current >= inputValue; - newCurrent = decreasing ? inputValue - 1 : inputValue; - await document.update({ 'system.armor.current': newCurrent }); - } else if (document.system.armorData) { - const { current } = document.system.armorData; - decreasing = current >= inputValue; - newCurrent = decreasing ? inputValue - 1 : inputValue; - - const newChanges = document.system.changes.map(change => ({ - ...change, - value: change.type === 'armor' ? { ...change.value, current: newCurrent } : change.value - })); - - await document.update({ 'system.changes': newChanges }); - } else { - return; - } - - const container = target.closest('.slot-bar'); - for (const armorSlot of container.querySelectorAll('.armor-slot i')) { - const index = Number.parseInt(armorSlot.dataset.index); - if (decreasing && index >= newCurrent) { - armorSlot.classList.remove('fa-shield'); - armorSlot.classList.add('fa-shield-halved'); - } else if (!decreasing && index < newCurrent) { - armorSlot.classList.add('fa-shield'); - armorSlot.classList.remove('fa-shield-halved'); - } - } - } - static async #toggleResourceManagement(event, button) { event.stopPropagation(); const existingTooltip = document.body.querySelector('.locked-tooltip .resource-management-container'); @@ -1062,6 +965,7 @@ export default class CharacterSheet extends DHBaseActorSheet { ); const target = button.closest('.resource-section'); + game.tooltip.dismissLockedTooltips(); game.tooltip.activate(target, { html, diff --git a/module/applications/sheets/actors/party.mjs b/module/applications/sheets/actors/party.mjs index c5e77112..45bdb679 100644 --- a/module/applications/sheets/actors/party.mjs +++ b/module/applications/sheets/actors/party.mjs @@ -189,14 +189,11 @@ export default class Party extends DHBaseActorSheet { * Toggles a armor slot resource value. * @type {ApplicationClickAction} */ - static async #toggleArmorSlot(_, target) { - const actor = game.actors.get(target.dataset.actorId); - const { value, max } = actor.system.armorScore; - const inputValue = Number.parseInt(target.dataset.value); - const newValue = value >= inputValue ? inputValue - 1 : inputValue; - const changeValue = Math.min(newValue - value, max - value); - - await actor.system.updateArmorValue({ value: changeValue }); + static async #toggleArmorSlot(_, target, element) { + const armorItem = await foundry.utils.fromUuid(target.dataset.itemUuid); + const armorValue = Number.parseInt(target.dataset.value); + const newValue = armorItem.system.marks.value >= armorValue ? armorValue - 1 : armorValue; + await armorItem.update({ 'system.marks.value': newValue }); this.render(); } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 83313454..89941399 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -749,13 +749,11 @@ export default function DHApplicationMixin(Base) { const cls = type === 'action' ? game.system.api.models.actions.actionsTypes.base : getDocumentClass(documentClass); - const data = { name: cls.defaultName({ type, parent }), type, system: systemData }; - if (inVault) data['system.inVault'] = true; if (disabled) data.disabled = true; if (type === 'domainCard' && parent?.system.domains?.length) { diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index 4b0fd7d9..6f994faf 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -160,7 +160,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { inactives: [] }; - for (const effect of this.actor.allApplicableEffects({ noTransferArmor: true })) { + for (const effect of this.actor.allApplicableEffects()) { const list = effect.active ? context.effects.actives : context.effects.inactives; list.push(effect); } diff --git a/module/applications/sheets/items/armor.mjs b/module/applications/sheets/items/armor.mjs index 54685fee..2550b415 100644 --- a/module/applications/sheets/items/armor.mjs +++ b/module/applications/sheets/items/armor.mjs @@ -47,15 +47,6 @@ export default class ArmorSheet extends ItemAttachmentSheet(DHBaseItemSheet) { return context; } - async updateArmorEffect(event) { - const value = Number.parseInt(event.target.value); - const armorEffect = this.document.system.armorEffect; - if (Number.isNaN(value) || !armorEffect) return; - - await armorEffect.system.armorChange.updateArmorMax(value); - this.render(); - } - /** * Callback function used by `tagifyElement`. * @param {Array} selectedOptions - The currently selected tag objects. diff --git a/module/applications/ui/_module.mjs b/module/applications/ui/_module.mjs index 80d3ebe4..8c5c020e 100644 --- a/module/applications/ui/_module.mjs +++ b/module/applications/ui/_module.mjs @@ -7,4 +7,3 @@ export { default as DhFearTracker } from './fearTracker.mjs'; export { default as DhHotbar } from './hotbar.mjs'; export { default as DhSceneNavigation } from './sceneNavigation.mjs'; export { ItemBrowser } from './itemBrowser.mjs'; -export { default as DhProgress } from './progress.mjs'; diff --git a/module/applications/ui/progress.mjs b/module/applications/ui/progress.mjs deleted file mode 100644 index 2fb1b445..00000000 --- a/module/applications/ui/progress.mjs +++ /dev/null @@ -1,27 +0,0 @@ -export default class DhProgress { - #notification; - - constructor({ max, label = '' }) { - this.max = max; - this.label = label; - this.#notification = ui.notifications.info(this.label, { progress: true }); - } - - updateMax(newMax) { - this.max = newMax; - } - - advance({ by = 1, label = this.label } = {}) { - if (this.value === this.max) return; - this.value = (this.value ?? 0) + Math.abs(by); - this.#notification.update({ message: label, pct: this.value / this.max }); - } - - close({ label = '' } = {}) { - this.#notification.update({ message: label, pct: 1 }); - } - - static createMigrationProgress(max = 0) { - return new DhProgress({ max, label: game.i18n.localize('DAGGERHEART.UI.Progress.migrationLabel') }); - } -} diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 7c7c2668..d8403b50 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -974,7 +974,7 @@ export const tagTeamRollTypes = { } }; -export const baseActiveEffectModes = { +export const activeEffectModes = { custom: { id: 'custom', priority: 0, @@ -1012,21 +1012,6 @@ export const baseActiveEffectModes = { } }; -export const activeEffectModes = { - armor: { - id: 'armor', - priority: 20, - label: 'TYPES.ActiveEffect.armor' - }, - ...baseActiveEffectModes -}; - -export const activeEffectArmorInteraction = { - none: { id: 'none', label: 'DAGGERHEART.CONFIG.ArmorInteraction.none.label' }, - active: { id: 'active', label: 'DAGGERHEART.CONFIG.ArmorInteraction.active.label' }, - inactive: { id: 'inactive', label: 'DAGGERHEART.CONFIG.ArmorInteraction.inactive.label' } -}; - export const activeEffectDurations = { temporary: { id: 'temporary', diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index a3e785c3..b424c707 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -489,18 +489,15 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.barrier.effects.barrier.description', img: 'icons/skills/melee/shield-block-bash-blue.webp', changes: [ + { + key: 'system.armorScore', + mode: 2, + value: 'ITEM.@system.tier + 1' + }, { key: 'system.evasion', mode: 2, value: '-1' - }, - { - key: 'Armor', - type: 'armor', - typeData: { - type: 'armor', - max: 'ITEM.@system.tier + 1' - } } ] } @@ -792,6 +789,11 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.effects.doubleDuty.description', img: 'icons/skills/melee/sword-shield-stylized-white.webp', changes: [ + { + key: 'system.armorScore', + mode: 2, + value: '1' + }, { key: 'system.bonuses.damage.primaryWeapon.bonus', mode: 2, @@ -806,22 +808,6 @@ export const weaponFeatures = { type: 'withinRange' } } - }, - { - name: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.effects.doubleDuty.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.effects.doubleDuty.description', - img: 'icons/skills/melee/sword-shield-stylized-white.webp', - changes: [ - { - key: 'Armor', - type: 'armor', - value: 0, - typeData: { - type: 'armor', - max: 1 - } - } - ] } ] }, @@ -1205,13 +1191,9 @@ export const weaponFeatures = { img: 'icons/skills/melee/shield-block-gray-orange.webp', changes: [ { - key: 'Armor', - type: 'armor', - value: 0, - typeData: { - type: 'armor', - max: 'ITEM.@system.tier' - } + key: 'system.armorScore', + mode: 2, + value: 'ITEM.@system.tier' } ] } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 01139b30..1fa1e7c0 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -298,19 +298,17 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel static async getEffects(actor, effectParent) { if (!actor) return []; - return Array.from(await actor.allApplicableEffects({ noTransferArmor: true, noSelfArmor: true })).filter( - effect => { - /* Effects on weapons only ever apply for the weapon itself */ - if (effect.parent.type === 'weapon') { - /* Unless they're secondary - then they apply only to other primary weapons */ - if (effect.parent.system.secondary) { - if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) return false; - } else if (effectParent?.id !== effect.parent.id) return false; - } - - return !effect.isSuppressed; + return Array.from(await actor.allApplicableEffects()).filter(effect => { + /* Effects on weapons only ever apply for the weapon itself */ + if (effect.parent.type === 'weapon') { + /* Unless they're secondary - then they apply only to other primary weapons */ + if (effect.parent.system.secondary) { + if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) return false; + } else if (effectParent?.id !== effect.parent.id) return false; } - ); + + return !effect.isSuppressed; + }); } /** diff --git a/module/data/activeEffect/_module.mjs b/module/data/activeEffect/_module.mjs index a5d859a9..9b4e3263 100644 --- a/module/data/activeEffect/_module.mjs +++ b/module/data/activeEffect/_module.mjs @@ -2,7 +2,6 @@ import BaseEffect from './baseEffect.mjs'; import BeastformEffect from './beastformEffect.mjs'; import HordeEffect from './hordeEffect.mjs'; import { EffectConditionals, EffectConditional } from './effectConditional.mjs'; -export { changeTypes, changeEffects } from './changeTypes/_module.mjs'; export { BaseEffect, BeastformEffect, HordeEffect, EffectConditionals, EffectConditional }; diff --git a/module/data/activeEffect/baseEffect.mjs b/module/data/activeEffect/baseEffect.mjs index 82e96776..14633ded 100644 --- a/module/data/activeEffect/baseEffect.mjs +++ b/module/data/activeEffect/baseEffect.mjs @@ -14,41 +14,26 @@ import { EffectConditionals } from './effectConditional.mjs'; * "Anything that uses another data model value as its value": +1 - Effects that increase traits have to be calculated first at Base priority. (EX: Raise evasion by half your agility) */ -import { getScrollTextData } from '../../helpers/utils.mjs'; -import { changeTypes } from './_module.mjs'; - export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel { static defineSchema() { const fields = foundry.data.fields; - const baseChanges = Object.keys(CONFIG.DH.GENERAL.baseActiveEffectModes).reduce((r, type) => { - r[type] = new fields.SchemaField({ - key: new fields.StringField({ required: true }), - type: new fields.StringField({ - required: true, - choices: [type], - initial: type, - validate: BaseEffect.#validateType - }), - value: new fields.AnyField({ - required: true, - nullable: true, - serializable: true, - initial: '' - }), - phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }), - priority: new fields.NumberField() - }); - return r; - }, {}); - return { ...super.defineSchema(), changes: new fields.ArrayField( - new fields.TypedSchemaField( - { ...changeTypes, ...baseChanges }, - { initial: baseChanges.add.getInitialValue() } - ) + new fields.SchemaField({ + key: new fields.StringField({ required: true }), + type: new fields.StringField({ + required: true, + blank: false, + choices: CONFIG.DH.GENERAL.activeEffectModes, + initial: CONFIG.DH.GENERAL.activeEffectModes.add.id, + validate: BaseEffect.#validateType + }), + value: new fields.AnyField({ required: true, nullable: true, serializable: true, initial: '' }), + phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }), + priority: new fields.NumberField() + }) ), conditionals: new EffectConditionals(), duration: new fields.SchemaField({ @@ -104,23 +89,6 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel { return true; } - get isSuppressed() { - for (const change of this.changes) { - if (change.isSuppressed) return true; - } - } - - get armorChange() { - return this.changes.find(x => x.type === CONFIG.DH.GENERAL.activeEffectModes.armor.id); - } - - get armorData() { - const armorChange = this.armorChange; - if (!armorChange) return null; - - return armorChange.getArmorData(); - } - static getDefaultObject() { return { name: 'New Effect', @@ -142,31 +110,4 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel { } }; } - - async _preUpdate(changed, options, userId) { - const allowed = await super._preUpdate(changed, options, userId); - if (allowed === false) return false; - - const autoSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); - if ( - autoSettings.resourceScrollTexts && - this.parent.actor?.type === 'character' && - this.parent.actor.system.resources.armor - ) { - const newArmorTotal = (changed.system?.changes ?? []).reduce((acc, change) => { - if (change.type === 'armor') acc += change.value.current; - return acc; - }, this.parent.actor.system.armor?.system?.armor?.current ?? 0); - - const armorData = getScrollTextData(this.parent.actor, { value: newArmorTotal }, 'armor'); - options.scrollingTextData = [armorData]; - } - } - - _onUpdate(changed, options, userId) { - super._onUpdate(changed, options, userId); - - if (this.parent.actor && options.scrollingTextData) - this.parent.actor.queueScrollText(options.scrollingTextData); - } } diff --git a/module/data/activeEffect/changeTypes/_module.mjs b/module/data/activeEffect/changeTypes/_module.mjs deleted file mode 100644 index cf872304..00000000 --- a/module/data/activeEffect/changeTypes/_module.mjs +++ /dev/null @@ -1,9 +0,0 @@ -import Armor from './armor.mjs'; - -export const changeEffects = { - armor: Armor.changeEffect -}; - -export const changeTypes = { - armor: Armor -}; diff --git a/module/data/activeEffect/changeTypes/armor.mjs b/module/data/activeEffect/changeTypes/armor.mjs deleted file mode 100644 index f400d41b..00000000 --- a/module/data/activeEffect/changeTypes/armor.mjs +++ /dev/null @@ -1,206 +0,0 @@ -import { itemAbleRollParse } from '../../../helpers/utils.mjs'; - -const fields = foundry.data.fields; - -export default class ArmorChange extends foundry.abstract.DataModel { - static defineSchema() { - return { - type: new fields.StringField({ required: true, choices: ['armor'], initial: 'armor' }), - priority: new fields.NumberField(), - phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }), - value: new fields.SchemaField({ - current: new fields.NumberField({ integer: true, min: 0, initial: 0 }), - max: new fields.StringField({ - required: true, - nullable: false, - initial: '1', - label: 'DAGGERHEART.GENERAL.max' - }), - damageThresholds: new fields.SchemaField( - { - major: new fields.StringField({ - initial: '0', - label: 'DAGGERHEART.GENERAL.DamageThresholds.majorThreshold' - }), - severe: new fields.StringField({ - initial: '0', - label: 'DAGGERHEART.GENERAL.DamageThresholds.severeThreshold' - }) - }, - { nullable: true, initial: null } - ), - interaction: new fields.StringField({ - required: true, - choices: CONFIG.DH.GENERAL.activeEffectArmorInteraction, - initial: CONFIG.DH.GENERAL.activeEffectArmorInteraction.none.id, - label: 'DAGGERHEART.EFFECTS.ChangeTypes.armor.FIELDS.interaction.label', - hint: 'DAGGERHEART.EFFECTS.ChangeTypes.armor.FIELDS.interaction.hint' - }) - }) - }; - } - - static changeEffect = { - label: 'Armor', - defaultPriority: 20, - handler: (actor, change, _options, _field, replacementData) => { - const parsedMax = itemAbleRollParse(change.value.max, actor, change.effect.parent); - game.system.api.documents.DhActiveEffect.applyChange( - actor, - { - ...change, - key: 'system.armorScore.value', - type: CONFIG.DH.GENERAL.activeEffectModes.add.id, - value: change.value.current - }, - replacementData - ); - game.system.api.documents.DhActiveEffect.applyChange( - actor, - { - ...change, - key: 'system.armorScore.max', - type: CONFIG.DH.GENERAL.activeEffectModes.add.id, - value: parsedMax - }, - replacementData - ); - - if (change.value.damageThresholds) { - const getThresholdValue = value => { - const parsed = itemAbleRollParse(value, actor, change.effect.parent); - const roll = new Roll(parsed).evaluateSync(); - return roll ? (roll.isDeterministic ? roll.total : null) : null; - }; - const major = getThresholdValue(change.value.damageThresholds.major); - const severe = getThresholdValue(change.value.damageThresholds.severe); - - if (major) { - game.system.api.documents.DhActiveEffect.applyChange( - actor, - { - ...change, - key: 'system.damageThresholds.major', - type: CONFIG.DH.GENERAL.activeEffectModes.override.id, - priority: 50, - value: major - }, - replacementData - ); - } - - if (severe) { - game.system.api.documents.DhActiveEffect.applyChange( - actor, - { - ...change, - key: 'system.damageThresholds.severe', - type: CONFIG.DH.GENERAL.activeEffectModes.override.id, - priority: 50, - value: severe - }, - replacementData - ); - } - } - - return {}; - }, - render: null - }; - - get isSuppressed() { - switch (this.value.interaction) { - case CONFIG.DH.GENERAL.activeEffectArmorInteraction.active.id: - return !this.parent.parent?.actor.system.armor; - case CONFIG.DH.GENERAL.activeEffectArmorInteraction.inactive.id: - return Boolean(this.parent.parent?.actor.system.armor); - default: - return false; - } - } - - static getInitialValue() { - return { - type: CONFIG.DH.GENERAL.activeEffectModes.armor.id, - value: { - current: 0, - max: 0 - }, - phase: 'initial', - priority: 20 - }; - } - - static getDefaultArmorEffect() { - return { - name: game.i18n.localize('DAGGERHEART.EFFECTS.ChangeTypes.armor.newArmorEffect'), - img: 'icons/equipment/chest/breastplate-helmet-metal.webp', - system: { - changes: [ArmorChange.getInitialValue()] - } - }; - } - - /* Helpers */ - - getArmorData() { - const actor = this.parent.parent?.actor?.type === 'character' ? this.parent.parent.actor : null; - const maxParse = actor ? itemAbleRollParse(this.value.max, actor, this.parent.parent.parent) : null; - const maxRoll = maxParse ? new Roll(maxParse).evaluateSync() : null; - const maxEvaluated = maxRoll ? (maxRoll.isDeterministic ? maxRoll.total : null) : null; - - return { - current: this.value.current, - max: maxEvaluated ?? this.value.max - }; - } - - async updateArmorMax(newMax) { - const newChanges = [ - ...this.parent.changes.map(change => ({ - ...change, - value: - change.type === 'armor' - ? { - ...change.value, - current: Math.min(change.value.current, newMax), - max: newMax - } - : change.value - })) - ]; - await this.parent.parent.update({ 'system.changes': newChanges }); - } - - static orderEffectsForAutoChange(armorEffects, increasing) { - const getEffectWeight = effect => { - switch (effect.parent.type) { - case 'class': - case 'subclass': - case 'ancestry': - case 'community': - case 'feature': - case 'domainCard': - return 2; - case 'armor': - return 3; - case 'loot': - case 'consumable': - return 4; - case 'weapon': - return 5; - case 'character': - return 6; - default: - return 1; - } - }; - - return armorEffects - .filter(x => !x.disabled && !x.isSuppressed) - .sort((a, b) => - increasing ? getEffectWeight(b) - getEffectWeight(a) : getEffectWeight(a) - getEffectWeight(b) - ); - } -} diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 55c1c7d8..d5481cc5 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -6,7 +6,6 @@ import DhCreature from './creature.mjs'; import { attributeField, stressDamageReductionRule, bonusField } from '../fields/actorField.mjs'; import { ActionField } from '../fields/actionField.mjs'; import DHCharacterSettings from '../../applications/sheets-configs/character-settings.mjs'; -import { getArmorSources } from '../../helpers/utils.mjs'; export default class DhCharacter extends DhCreature { /**@override */ @@ -42,16 +41,17 @@ export default class DhCharacter extends DhCreature { label: 'DAGGERHEART.GENERAL.proficiency' }), evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }), + armorScore: new fields.NumberField({ integer: true, initial: 0, label: 'DAGGERHEART.GENERAL.armorScore' }), damageThresholds: new fields.SchemaField({ - major: new fields.NumberField({ - integer: true, - initial: 0, - label: 'DAGGERHEART.GENERAL.DamageThresholds.majorThreshold' - }), severe: new fields.NumberField({ integer: true, initial: 0, label: 'DAGGERHEART.GENERAL.DamageThresholds.severeThreshold' + }), + major: new fields.NumberField({ + integer: true, + initial: 0, + label: 'DAGGERHEART.GENERAL.DamageThresholds.majorThreshold' }) }), experiences: new fields.TypedObjectField( @@ -465,101 +465,6 @@ export default class DhCharacter extends DhCreature { } } - async updateArmorValue({ value: armorChange = 0, clear = false }) { - if (armorChange === 0 && !clear) return; - - const increasing = armorChange >= 0; - let remainingChange = Math.abs(armorChange); - const orderedSources = getArmorSources(this.parent).filter(s => !s.disabled); - - const handleArmorData = (embeddedUpdates, doc, armorData) => { - let usedArmorChange = 0; - if (clear) { - usedArmorChange -= armorData.current; - } else { - if (increasing) { - const remainingArmor = armorData.max - armorData.current; - usedArmorChange = Math.min(remainingChange, remainingArmor); - remainingChange -= usedArmorChange; - } else { - const changeChange = Math.min(armorData.current, remainingChange); - usedArmorChange -= changeChange; - remainingChange -= changeChange; - } - } - - if (!usedArmorChange) return usedArmorChange; - else { - if (!embeddedUpdates[doc.id]) embeddedUpdates[doc.id] = { doc: doc, updates: [] }; - - return usedArmorChange; - } - }; - - const armorUpdates = []; - const effectUpdates = []; - for (const { document: armorSource } of orderedSources) { - const usedArmorChange = handleArmorData( - armorSource.type === 'armor' ? armorUpdates : effectUpdates, - armorSource.parent, - armorSource.type === 'armor' ? armorSource.system.armor : armorSource.system.armorData - ); - if (!usedArmorChange) continue; - - if (armorSource.type === 'armor') { - armorUpdates[armorSource.parent.id].updates.push({ - '_id': armorSource.id, - 'system.armor.current': armorSource.system.armor.current + usedArmorChange - }); - } else { - effectUpdates[armorSource.parent.id].updates.push({ - '_id': armorSource.id, - 'system.changes': armorSource.system.changes.map(change => ({ - ...change, - value: - change.type === 'armor' - ? { - ...change.value, - current: armorSource.system.armorChange.value.current + usedArmorChange - } - : change.value - })) - }); - } - - if (remainingChange === 0 && !clear) break; - } - - const armorUpdateValues = Object.values(armorUpdates); - for (const [index, { doc, updates }] of armorUpdateValues.entries()) - await doc.updateEmbeddedDocuments('Item', updates, { render: index === armorUpdateValues.length - 1 }); - - const effectUpdateValues = Object.values(effectUpdates); - for (const [index, { doc, updates }] of effectUpdateValues.entries()) - await doc.updateEmbeddedDocuments('ActiveEffect', updates, { - render: index === effectUpdateValues.length - 1 - }); - } - - async updateArmorEffectValue({ uuid, value }) { - const source = await foundry.utils.fromUuid(uuid); - if (source.type === 'armor') { - await source.update({ - 'system.armor.current': source.system.armor.current + value - }); - } else { - const effectValue = source.system.armorChange.value; - await source.update({ - 'system.changes': [ - { - ...source.system.armorChange, - value: { ...effectValue, current: effectValue.current + value } - } - ] - }); - } - } - get sheetLists() { const ancestryFeatures = [], communityFeatures = [], @@ -683,10 +588,6 @@ export default class DhCharacter extends DhCreature { prepareBaseData() { super.prepareBaseData(); - this.armorScore = { - max: this.armor?.system.armor.max ?? 0, - value: this.armor?.system.armor.current ?? 0 - }; this.evasion += this.class.value?.system?.evasion ?? 0; const currentLevel = this.levelData.level.current; @@ -736,12 +637,14 @@ export default class DhCharacter extends DhCreature { } } + const armor = this.armor; + this.armorScore = armor ? armor.system.baseScore : 0; this.damageThresholds = { - major: this.armor - ? this.armor.system.baseThresholds.major + this.levelData.level.current + major: armor + ? armor.system.baseThresholds.major + this.levelData.level.current : this.levelData.level.current, - severe: this.armor - ? this.armor.system.baseThresholds.severe + this.levelData.level.current + severe: armor + ? armor.system.baseThresholds.severe + this.levelData.level.current : this.levelData.level.current * 2 }; @@ -776,8 +679,9 @@ export default class DhCharacter extends DhCreature { this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait; this.resources.armor = { - ...this.armorScore, label: 'DAGGERHEART.GENERAL.armor', + value: this.armor?.system?.marks?.value ?? 0, + max: this.armorScore, isReversed: true }; diff --git a/module/data/fields/actorField.mjs b/module/data/fields/actorField.mjs index e4dcb8e9..25e04317 100644 --- a/module/data/fields/actorField.mjs +++ b/module/data/fields/actorField.mjs @@ -89,17 +89,13 @@ class ResourcesField extends fields.TypedObjectField { */ _getField(path) { if (path.length === 0) return this; - const first = path.pop(); + const first = path.shift(); + if (first === this.element.name) return this.element_getField(path); const resources = CONFIG.DH.RESOURCE[this.actorType].all; if (first in resources) { - const field = this.element._getField(path); - const resourceName = game.i18n.localize(resources[first].label); - field.label = - field.name === 'max' - ? game.i18n.format('DAGGERHEART.GENERAL.maxWithThing', { thing: resourceName }) - : resources[first].label; - return field; + this.element.label = resources[first].label; + return this.element._getField(path); } return undefined; diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index b0e4847f..264d7f93 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -19,14 +19,7 @@ export default class DHArmor extends AttachableItem { ...super.defineSchema(), tier: new fields.NumberField({ required: true, integer: true, initial: 1, min: 1 }), equipped: new fields.BooleanField({ initial: false }), - armor: new fields.SchemaField({ - current: new fields.NumberField({ integer: true, min: 0, initial: 0 }), - max: new fields.NumberField({ required: true, integer: true, initial: 0 }) - }), - baseThresholds: new fields.SchemaField({ - major: new fields.NumberField({ integer: true, initial: 0 }), - severe: new fields.NumberField({ integer: true, initial: 0 }) - }), + baseScore: new fields.NumberField({ integer: true, initial: 0 }), armorFeatures: new fields.ArrayField( new fields.SchemaField({ value: new fields.StringField({ @@ -35,7 +28,14 @@ export default class DHArmor extends AttachableItem { effectIds: new fields.ArrayField(new fields.StringField({ required: true })), actionIds: new fields.ArrayField(new fields.StringField({ required: true })) }) - ) + ), + marks: new fields.SchemaField({ + value: new fields.NumberField({ initial: 0, integer: true }) + }), + baseThresholds: new fields.SchemaField({ + major: new fields.NumberField({ integer: true, initial: 0 }), + severe: new fields.NumberField({ integer: true, initial: 0 }) + }) }; } @@ -151,20 +151,13 @@ export default class DHArmor extends AttachableItem { } } - /** @inheritDoc */ - static migrateDocumentData(source) { - if (!source.system.armor) { - source.system.armor = { current: source.system.marks?.value ?? 0, max: source.system.baseScore ?? 0 }; - } - } - /** * Generates a list of localized tags based on this item's type-specific properties. * @returns {string[]} An array of localized tag strings. */ _getTags() { const tags = [ - `${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.armor.max}`, + `${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`, `${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseThresholds.base')}: ${this.baseThresholds.major} / ${this.baseThresholds.severe}` ]; @@ -176,7 +169,9 @@ export default class DHArmor extends AttachableItem { * @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects. */ _getLabels() { - const labels = [`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.armor.max}`]; + const labels = []; + if (this.baseScore) + labels.push(`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`); return labels; } diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 21a11149..5a16927a 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -222,14 +222,9 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { const autoSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); const armorChanged = - changed.system?.armor?.current !== undefined && changed.system.armor.current !== this.armor.current; + changed.system?.marks?.value !== undefined && changed.system.marks.value !== this.marks.value; if (armorChanged && autoSettings.resourceScrollTexts && this.parent.parent?.type === 'character') { - const armorChangeValue = changed.system.armor.current - this.armor.current; - const armorData = getScrollTextData( - this.parent.parent, - { value: armorChangeValue + this.parent.parent.system.armorScore.value }, - 'armor' - ); + const armorData = getScrollTextData(this.parent.parent, changed.system.marks, 'armor'); options.scrollingTextData = [armorData]; } diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 355dcf32..ad664f15 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -1,5 +1,5 @@ import { itemAbleRollParse } from '../helpers/utils.mjs'; -import { RefreshType } from '../systemRegistration/socket.mjs'; +import { RefreshType, socketEvent } from '../systemRegistration/socket.mjs'; export default class DhActiveEffect extends foundry.documents.ActiveEffect { /* -------------------------------------------- */ @@ -11,8 +11,6 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { const conditionalSuspended = game.system.api.data.activeEffects.EffectConditionals.isConditionalSuspended(this); if (conditionalSuspended) return true; - if (this.system.isSuppressed === true) return true; - // If this is a copied effect from an attachment, never suppress it // (These effects have attachmentSource metadata) if (this.flags?.daggerheart?.attachmentSource) { @@ -20,7 +18,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { } // Then apply the standard suppression rules - if (['weapon', 'armor'].includes(this.parent?.type) && this.transfer) { + if (['weapon', 'armor'].includes(this.parent?.type)) { return !this.parent.system.equipped; } @@ -81,7 +79,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { throw new Error('The array of sub-types to restrict to must not be empty.'); } - const creatableEffects = types || ['base']; + const creatableEffects = ['base']; const documentTypes = this.TYPES.filter(type => creatableEffects.includes(type)).map(type => { const labelKey = `TYPES.ActiveEffect.${type}`; const label = game.i18n.has(labelKey) ? game.i18n.localize(labelKey) : type; @@ -166,9 +164,9 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { super.applyChangeField(model, change, field); } - static _applyChangeUnguided(actor, change, changes, options) { + _applyLegacy(actor, change, changes) { change.value = DhActiveEffect.getChangeValue(actor, change, change.effect); - super._applyChangeUnguided(actor, change, changes, options); + super._applyLegacy(actor, change, changes); } static getChangeValue(model, change, effect) { diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 023beaa0..6c434007 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -598,7 +598,8 @@ export default class DhpActor extends Actor { const availableStress = this.system.resources.stress.max - this.system.resources.stress.value; const canUseArmor = - this.system.armorScore.value < this.system.armorScore.max && + this.system.armor && + this.system.armor.system.marks.value < this.system.armorScore && type.every(t => this.system.armorApplicableDamageTypes[t] === true); const canUseStress = Object.keys(stressDamageReduction).reduce((acc, x) => { const rule = stressDamageReduction[x]; @@ -638,7 +639,12 @@ export default class DhpActor extends Actor { const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); if (hpDamage?.value) { hpDamage.value = this.convertDamageToThreshold(hpDamage.value); - if (this.type === 'character' && !isDirect && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) { + if ( + this.type === 'character' && + !isDirect && + this.system.armor && + this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes) + ) { const armorSlotResult = await this.owner.query( 'armorSlot', { @@ -651,10 +657,12 @@ export default class DhpActor extends Actor { } ); if (armorSlotResult) { - const { modifiedDamage, armorChanges, stressSpent } = armorSlotResult; + const { modifiedDamage, armorSpent, stressSpent } = armorSlotResult; updates.find(u => u.key === 'hitPoints').value = modifiedDamage; - for (const armorChange of armorChanges) { - updates.push({ value: armorChange.amount, key: 'armor', uuid: armorChange.uuid }); + if (armorSpent) { + const armorUpdate = updates.find(u => u.key === 'armor'); + if (armorUpdate) armorUpdate.value += armorSpent; + else updates.push({ value: armorSpent, key: 'armor' }); } if (stressSpent) { const stressUpdate = updates.find(u => u.key === 'stress'); @@ -801,8 +809,12 @@ export default class DhpActor extends Actor { ); break; case 'armor': - if (!r.uuid) this.system.updateArmorValue(r); - else this.system.updateArmorEffectValue(r); + if (this.system.armor?.system?.marks) { + updates.armor.resources['system.marks.value'] = Math.max( + Math.min(valueFunc(this.system.armor.system.marks, r), this.system.armorScore), + 0 + ); + } break; default: if (this.system.resources?.[r.key]) { @@ -1018,20 +1030,4 @@ export default class DhpActor extends Actor { return allTokens; } - - /**@inheritdoc */ - *allApplicableEffects({ noSelfArmor, noTransferArmor } = {}) { - for (const effect of this.effects) { - if (!noSelfArmor || effect.type !== 'armor') yield effect; - } - for (const item of this.items) { - for (const effect of item.effects) { - if (effect.transfer && (!noTransferArmor || effect.type !== 'armor')) yield effect; - } - } - } - - applyActiveEffects(phase) { - super.applyActiveEffects(phase); - } } diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 56048a81..67f7d253 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -230,14 +230,4 @@ export default class DHItem extends foundry.documents.Item { async _preDelete() { this.deleteTriggers(); } - - /** @inheritDoc */ - static migrateData(source) { - const documentClass = game.system.api.data.items[`DH${source.type?.capitalize()}`]; - if (documentClass?.migrateDocumentData) { - documentClass.migrateDocumentData(source); - } - - return super.migrateData(source); - } } diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 8b9be60c..137d5419 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -762,67 +762,3 @@ export function getUnusedDamageTypes(parts) { return acc; }, []); } - -/** Returns resolved armor sources ordered by application order */ -export function getArmorSources(actor) { - const rawArmorSources = Array.from(actor.allApplicableEffects()).filter(x => x.system.armorData); - if (actor.system.armor) rawArmorSources.push(actor.system.armor); - - const data = rawArmorSources.map(doc => { - // Get the origin item. Since the actor is already loaded, it should already be cached - // Consider the relative function versions if this causes an issue - const isItem = doc instanceof Item; - const origin = isItem ? doc : doc.origin ? foundry.utils.fromUuidSync(doc.origin) : doc.parent; - return { - origin, - name: origin.name, - document: doc, - data: doc.system.armor ?? doc.system.armorData, - disabled: !!doc.disabled || !!doc.isSuppressed - }; - }); - - return sortBy(data, ({ origin }) => { - switch (origin?.type) { - case 'class': - case 'subclass': - case 'ancestry': - case 'community': - case 'feature': - case 'domainCard': - return 2; - case 'loot': - case 'consumable': - return 3; - case 'character': - return 4; - case 'weapon': - return 5; - case 'armor': - return 6; - default: - return 1; - } - }); -} - -/** - * Returns an array sorted by a function that returns a thing to compare, or an array to compare in order - * Similar to lodash's sortBy function. - */ -export function sortBy(arr, fn) { - const directCompare = (a, b) => (a < b ? -1 : a > b ? 1 : 0); - const cmp = (a, b) => { - const resultA = fn(a); - const resultB = fn(b); - if (Array.isArray(resultA) && Array.isArray(resultB)) { - for (let idx = 0; idx < Math.min(resultA.length, resultB.length); idx++) { - const result = directCompare(resultA[idx], resultB[idx]); - if (result !== 0) return result; - } - return 0; - } - return directCompare(resultA, resultB); - }; - return arr.sort(cmp); -} diff --git a/module/systemRegistration/handlebars.mjs b/module/systemRegistration/handlebars.mjs index 36df8b54..4ad98b06 100644 --- a/module/systemRegistration/handlebars.mjs +++ b/module/systemRegistration/handlebars.mjs @@ -48,7 +48,6 @@ export const preloadHandlebarsTemplates = async function () { 'systems/daggerheart/templates/ui/chat/parts/button-part.hbs', 'systems/daggerheart/templates/ui/itemBrowser/itemContainer.hbs', 'systems/daggerheart/templates/scene/dh-config.hbs', - 'systems/daggerheart/templates/settings/appearance-settings/diceSoNiceTab.hbs', - 'systems/daggerheart/templates/sheets/activeEffect/typeChanges/armorChange.hbs' + 'systems/daggerheart/templates/settings/appearance-settings/diceSoNiceTab.hbs' ]); }; diff --git a/module/systemRegistration/migrations.mjs b/module/systemRegistration/migrations.mjs index 458ee6ef..f8795386 100644 --- a/module/systemRegistration/migrations.mjs +++ b/module/systemRegistration/migrations.mjs @@ -246,101 +246,6 @@ export async function runMigrations() { lastMigrationVersion = '1.6.0'; } - - if (foundry.utils.isNewerVersion('2.0.0', lastMigrationVersion)) { - const progress = game.system.api.applications.ui.DhProgress.createMigrationProgress(0); - const progressBuffer = 50; - - //#region Data Setup - const lockedPacks = []; - const itemPacks = game.packs.filter(x => x.metadata.type === 'Item'); - const actorPacks = game.packs.filter(x => x.metadata.type === 'Actor'); - - const getIndexes = async (packs, type) => { - const indexes = []; - for (const pack of packs) { - const indexValues = pack.index.values().reduce((acc, index) => { - if (!type || index.type === type) acc.push(index.uuid); - return acc; - }, []); - - if (indexValues.length && pack.locked) { - lockedPacks.push(pack.collection); - await pack.configure({ locked: false }); - } - - indexes.push(...indexValues); - } - - return indexes; - }; - - const itemEntries = await getIndexes(itemPacks); - const characterEntries = await getIndexes(actorPacks, 'character'); - - const worldItems = game.items; - const worldCharacters = game.actors.filter(x => x.type === 'character'); - - /* The async fetches are the mainstay of time. Leaving 1 progress for the sync logic */ - const newMax = itemEntries.length + characterEntries.length + progressBuffer; - progress.updateMax(newMax); - - const compendiumItems = []; - for (const entry of itemEntries) { - const item = await foundry.utils.fromUuid(entry); - compendiumItems.push(item); - progress.advance(); - } - - const compendiumCharacters = []; - for (const entry of characterEntries) { - const character = await foundry.utils.fromUuid(entry); - compendiumCharacters.push(character); - progress.advance(); - } - //#endregion - - /* Migrate existing effects modifying armor, creating new Armor Effects instead */ - const migrateEffects = async entity => { - for (const effect of entity.effects) { - if (effect.system.changes.every(x => x.key !== 'system.armorScore')) continue; - - effect.update({ - 'system.changes': effect.system.changes.map(change => ({ - ...change, - type: change.key === 'system.armorScore' ? 'armor' : change.type, - value: change.key === 'system.armorScore' ? { current: 0, max: change.value } : change.value - })) - }); - } - }; - - /* Migrate existing armors effects */ - const migrateItems = async items => { - for (const item of items) { - await migrateEffects(item); - } - }; - - await migrateItems([...compendiumItems, ...worldItems]); - progress.advance({ by: progressBuffer / 2 }); - - for (const actor of [...compendiumCharacters, ...worldCharacters]) { - await migrateEffects(actor); - await migrateItems(actor.items); - } - - progress.advance({ by: progressBuffer / 2 }); - - for (let packId of lockedPacks) { - const pack = game.packs.get(packId); - await pack.configure({ locked: true }); - } - - progress.close(); - - lastMigrationVersion = '2.0.0'; - } //#endregion await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion); diff --git a/src/packs/domains/domainCard_Armorer_cy8GjBPGc9w9RaGO.json b/src/packs/domains/domainCard_Armorer_cy8GjBPGc9w9RaGO.json index cad6012e..059fb24c 100644 --- a/src/packs/domains/domainCard_Armorer_cy8GjBPGc9w9RaGO.json +++ b/src/packs/domains/domainCard_Armorer_cy8GjBPGc9w9RaGO.json @@ -92,28 +92,34 @@ "name": "Armorer", "type": "base", "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "1", - "interaction": "active" - } - } - ] + "rangeDependence": { + "enabled": false, + "type": "withinRange", + "target": "hostile", + "range": "melee" + } }, - "_id": "tJw2JIPcT9hEMRXg", + "_id": "cED730OjuMW5haJR", "img": "icons/tools/hand/hammer-and-nail.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "1", + "priority": null + } + ], "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null }, - "description": "

While you’re wearing armor, gain a +1 bonus to your Armor Score.

", + "description": "

While you’re wearing armor, gain a +1 bonus to your Armor Score.

", "origin": null, "tint": "#ffffff", "transfer": true, @@ -123,10 +129,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!cy8GjBPGc9w9RaGO.tJw2JIPcT9hEMRXg" + "_key": "!items.effects!cy8GjBPGc9w9RaGO.cED730OjuMW5haJR" } ], "ownership": { diff --git a/src/packs/domains/domainCard_Bare_Bones_l5D9kq901JDESaXw.json b/src/packs/domains/domainCard_Bare_Bones_l5D9kq901JDESaXw.json index 098f5f4c..3b1ea76a 100644 --- a/src/packs/domains/domainCard_Bare_Bones_l5D9kq901JDESaXw.json +++ b/src/packs/domains/domainCard_Bare_Bones_l5D9kq901JDESaXw.json @@ -19,52 +19,7 @@ } }, "flags": {}, - "effects": [ - { - "name": "Bare Bones", - "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "3 + @system.traits.strength.value", - "interaction": "inactive", - "damageThresholds": { - "major": "9 + (@tier - 1) * 5 + max(0, (@tier -2) * 2 )", - "severe": "19 + (@tier - 1) * 5 + max(0, (@tier -2) * 2 )" - } - } - } - ] - }, - "_id": "FCsgz7Tdsw6QUzBs", - "img": "icons/magic/control/buff-strength-muscle-damage-orange.webp", - "disabled": false, - "start": null, - "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false - }, - "description": "

You have a base Armor Score of 3 + your Strength.

", - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "showIcon": 1, - "folder": null, - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "_key": "!items.effects!l5D9kq901JDESaXw.FCsgz7Tdsw6QUzBs" - } - ], + "effects": [], "ownership": { "default": 0, "MQSznptE5yLT7kj8": 3 diff --git a/src/packs/domains/domainCard_Book_of_Ava_YtZzYBtR0yLPPA93.json b/src/packs/domains/domainCard_Book_of_Ava_YtZzYBtR0yLPPA93.json index fa247c89..7977e56a 100644 --- a/src/packs/domains/domainCard_Book_of_Ava_YtZzYBtR0yLPPA93.json +++ b/src/packs/domains/domainCard_Book_of_Ava_YtZzYBtR0yLPPA93.json @@ -105,7 +105,7 @@ }, "effects": [ { - "_id": "ptYT10JZ2WJHvFMd", + "_id": "LdcT1nrkd5ORCU4n", "onSave": false } ], @@ -252,7 +252,7 @@ "img": "icons/magic/defensive/shield-barrier-glowing-triangle-blue.webp", "origin": "Compendium.daggerheart.domains.Item.YtZzYBtR0yLPPA93", "transfer": false, - "_id": "ptYT10JZ2WJHvFMd", + "_id": "LdcT1nrkd5ORCU4n", "type": "base", "system": { "rangeDependence": { @@ -263,12 +263,10 @@ }, "changes": [ { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "1" - } + "key": "system.armorScore", + "value": 1, + "priority": null, + "type": "add" } ], "duration": { @@ -300,7 +298,7 @@ }, "showIcon": 1, "folder": null, - "_key": "!items.effects!YtZzYBtR0yLPPA93.ptYT10JZ2WJHvFMd" + "_key": "!items.effects!YtZzYBtR0yLPPA93.LdcT1nrkd5ORCU4n" } ], "ownership": { diff --git a/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json b/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json index 61c7ace8..84ef1025 100644 --- a/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json +++ b/src/packs/domains/domainCard_Valor_Touched_k1AtYd3lSchIymBr.json @@ -93,25 +93,32 @@ "name": "Valor-Touched", "type": "base", "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "1" - } - } - ] + "rangeDependence": { + "enabled": false, + "type": "withinRange", + "target": "hostile", + "range": "melee" + } }, - "_id": "Ma8Zp005QYKPWIEN", + "_id": "H9lgIqqp1imSNOv9", "img": "icons/magic/control/control-influence-rally-purple.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "1", + "priority": null + } + ], "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null }, "description": "", "origin": null, @@ -123,10 +130,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!k1AtYd3lSchIymBr.Ma8Zp005QYKPWIEN" + "_key": "!items.effects!k1AtYd3lSchIymBr.H9lgIqqp1imSNOv9" } ], "ownership": { diff --git a/src/packs/items/armors/armor_Advanced_Chainmail_Armor_LzLOJ9EVaHWAjoq9.json b/src/packs/items/armors/armor_Advanced_Chainmail_Armor_LzLOJ9EVaHWAjoq9.json index 4566396a..174f20c8 100644 --- a/src/packs/items/armors/armor_Advanced_Chainmail_Armor_LzLOJ9EVaHWAjoq9.json +++ b/src/packs/items/armors/armor_Advanced_Chainmail_Armor_LzLOJ9EVaHWAjoq9.json @@ -5,10 +5,6 @@ "_id": "LzLOJ9EVaHWAjoq9", "img": "icons/equipment/chest/breastplate-banded-steel-gold.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Advanced_Full_Plate_Armor_crIbCb9NZ4K0VpoU.json b/src/packs/items/armors/armor_Advanced_Full_Plate_Armor_crIbCb9NZ4K0VpoU.json index 52adc7aa..dbc9d29f 100644 --- a/src/packs/items/armors/armor_Advanced_Full_Plate_Armor_crIbCb9NZ4K0VpoU.json +++ b/src/packs/items/armors/armor_Advanced_Full_Plate_Armor_crIbCb9NZ4K0VpoU.json @@ -5,10 +5,6 @@ "_id": "crIbCb9NZ4K0VpoU", "img": "icons/equipment/chest/breastplate-layered-steel-grey.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Advanced_Gambeson_Armor_epkAmlZVk7HOfUUT.json b/src/packs/items/armors/armor_Advanced_Gambeson_Armor_epkAmlZVk7HOfUUT.json index 36edec39..c9ffc8a3 100644 --- a/src/packs/items/armors/armor_Advanced_Gambeson_Armor_epkAmlZVk7HOfUUT.json +++ b/src/packs/items/armors/armor_Advanced_Gambeson_Armor_epkAmlZVk7HOfUUT.json @@ -5,10 +5,6 @@ "_id": "epkAmlZVk7HOfUUT", "img": "icons/equipment/chest/breastplate-purple.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Advanced_Leather_Armor_itSOp2GCyem0f7oM.json b/src/packs/items/armors/armor_Advanced_Leather_Armor_itSOp2GCyem0f7oM.json index 3e5dbd3b..4e1927e3 100644 --- a/src/packs/items/armors/armor_Advanced_Leather_Armor_itSOp2GCyem0f7oM.json +++ b/src/packs/items/armors/armor_Advanced_Leather_Armor_itSOp2GCyem0f7oM.json @@ -5,10 +5,6 @@ "_id": "itSOp2GCyem0f7oM", "img": "icons/equipment/chest/breastplate-layered-leather-blue.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Bare_Bones_ITAjcigTcUw5pMCN.json b/src/packs/items/armors/armor_Bare_Bones_ITAjcigTcUw5pMCN.json new file mode 100644 index 00000000..5158b100 --- /dev/null +++ b/src/packs/items/armors/armor_Bare_Bones_ITAjcigTcUw5pMCN.json @@ -0,0 +1,75 @@ +{ + "folder": "tI3bfr6Sgi16Z7zm", + "name": "Bare Bones", + "type": "armor", + "_id": "ITAjcigTcUw5pMCN", + "img": "icons/magic/control/buff-strength-muscle-damage.webp", + "system": { + "description": "

When you choose not to equip armor, you have a base Armor Score of 3 + your Strength and use the following as your base damage thresholds:

", + "actions": {}, + "attached": [], + "tier": 1, + "equipped": false, + "baseScore": 3, + "armorFeatures": [], + "marks": { + "value": 0 + }, + "baseThresholds": { + "major": 9, + "severe": 19 + } + }, + "effects": [ + { + "name": "Bare Bones", + "type": "base", + "system": { + "rangeDependence": { + "enabled": false, + "type": "withinRange", + "target": "hostile", + "range": "melee" + } + }, + "_id": "8ze88zUwdkQSKKJq", + "img": "icons/magic/control/buff-strength-muscle-damage.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "@system.traits.strength.value", + "priority": 21 + } + ], + "disabled": false, + "duration": { + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null + }, + "description": "

When you choose not to equip armor, you have a base Armor Score of 3 + your Strength and use the following as your base damage thresholds:

", + "origin": null, + "tint": "#ffffff", + "transfer": true, + "statuses": [], + "sort": 0, + "flags": {}, + "_stats": { + "compendiumSource": null + }, + "_key": "!items.effects!ITAjcigTcUw5pMCN.8ze88zUwdkQSKKJq" + } + ], + "sort": 0, + "ownership": { + "default": 0, + "MQSznptE5yLT7kj8": 3 + }, + "flags": {}, + "_key": "!items!ITAjcigTcUw5pMCN" +} diff --git a/src/packs/items/armors/armor_Bellamoi_Fine_Armor_WuoVwZA53XRAIt6d.json b/src/packs/items/armors/armor_Bellamoi_Fine_Armor_WuoVwZA53XRAIt6d.json index c470de87..ce4e35fd 100644 --- a/src/packs/items/armors/armor_Bellamoi_Fine_Armor_WuoVwZA53XRAIt6d.json +++ b/src/packs/items/armors/armor_Bellamoi_Fine_Armor_WuoVwZA53XRAIt6d.json @@ -5,10 +5,6 @@ "_id": "WuoVwZA53XRAIt6d", "img": "icons/equipment/chest/breastplate-layered-gold.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Bladefare_Armor_mNN6pvcsS10ChrWF.json b/src/packs/items/armors/armor_Bladefare_Armor_mNN6pvcsS10ChrWF.json index 4ee73939..8b276d5f 100644 --- a/src/packs/items/armors/armor_Bladefare_Armor_mNN6pvcsS10ChrWF.json +++ b/src/packs/items/armors/armor_Bladefare_Armor_mNN6pvcsS10ChrWF.json @@ -5,10 +5,6 @@ "_id": "mNN6pvcsS10ChrWF", "img": "icons/equipment/chest/breastplate-collared-steel-grey.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Chainmail_Armor_haULhuEg37zUUvhb.json b/src/packs/items/armors/armor_Chainmail_Armor_haULhuEg37zUUvhb.json index 4f0719a7..f7526e96 100644 --- a/src/packs/items/armors/armor_Chainmail_Armor_haULhuEg37zUUvhb.json +++ b/src/packs/items/armors/armor_Chainmail_Armor_haULhuEg37zUUvhb.json @@ -5,10 +5,6 @@ "_id": "haULhuEg37zUUvhb", "img": "icons/equipment/chest/breastplate-scale-grey.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Channeling_Armor_vMJxEWz1srfwMsoj.json b/src/packs/items/armors/armor_Channeling_Armor_vMJxEWz1srfwMsoj.json index e805d5d1..a4bd0fea 100644 --- a/src/packs/items/armors/armor_Channeling_Armor_vMJxEWz1srfwMsoj.json +++ b/src/packs/items/armors/armor_Channeling_Armor_vMJxEWz1srfwMsoj.json @@ -5,10 +5,6 @@ "_id": "vMJxEWz1srfwMsoj", "img": "icons/equipment/chest/robe-collared-blue.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Dragonscale_Armor_mdQ69eFHyAQUDmE7.json b/src/packs/items/armors/armor_Dragonscale_Armor_mdQ69eFHyAQUDmE7.json index 4b270234..5b39e41d 100644 --- a/src/packs/items/armors/armor_Dragonscale_Armor_mdQ69eFHyAQUDmE7.json +++ b/src/packs/items/armors/armor_Dragonscale_Armor_mdQ69eFHyAQUDmE7.json @@ -5,10 +5,6 @@ "_id": "mdQ69eFHyAQUDmE7", "img": "icons/equipment/chest/breastplate-rivited-red.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": { "J1MCpcfXByKaSSgx": { diff --git a/src/packs/items/armors/armor_Dunamis_Silkchain_hAY6UgdGT7dj22Pr.json b/src/packs/items/armors/armor_Dunamis_Silkchain_hAY6UgdGT7dj22Pr.json index 6d223ada..588d9cf9 100644 --- a/src/packs/items/armors/armor_Dunamis_Silkchain_hAY6UgdGT7dj22Pr.json +++ b/src/packs/items/armors/armor_Dunamis_Silkchain_hAY6UgdGT7dj22Pr.json @@ -5,10 +5,6 @@ "_id": "hAY6UgdGT7dj22Pr", "img": "icons/equipment/chest/robe-layered-red.webp", "system": { - "armor": { - "current": 0, - "max": 7 - }, "description": "", "actions": { "8PD5JQuS05IA6HJT": { diff --git a/src/packs/items/armors/armor_Elundrian_Chain_Armor_Q6LxmtFetDDkoZVZ.json b/src/packs/items/armors/armor_Elundrian_Chain_Armor_Q6LxmtFetDDkoZVZ.json index 1cf74e2e..d63ce4df 100644 --- a/src/packs/items/armors/armor_Elundrian_Chain_Armor_Q6LxmtFetDDkoZVZ.json +++ b/src/packs/items/armors/armor_Elundrian_Chain_Armor_Q6LxmtFetDDkoZVZ.json @@ -5,10 +5,6 @@ "_id": "Q6LxmtFetDDkoZVZ", "img": "icons/equipment/chest/breastplate-sculpted-green.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Emberwoven_Armor_bcQUh4QG3qFX0Vx6.json b/src/packs/items/armors/armor_Emberwoven_Armor_bcQUh4QG3qFX0Vx6.json index 616bbadf..15b07474 100644 --- a/src/packs/items/armors/armor_Emberwoven_Armor_bcQUh4QG3qFX0Vx6.json +++ b/src/packs/items/armors/armor_Emberwoven_Armor_bcQUh4QG3qFX0Vx6.json @@ -5,10 +5,6 @@ "_id": "bcQUh4QG3qFX0Vx6", "img": "icons/equipment/chest/breastplate-layered-gilded-orange.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": { "L8mHf4A8SylyxsMH": { diff --git a/src/packs/items/armors/armor_Full_Fortified_Armor_7emTSt6nhZuTlvt5.json b/src/packs/items/armors/armor_Full_Fortified_Armor_7emTSt6nhZuTlvt5.json index 9f2d7ece..8eb964cc 100644 --- a/src/packs/items/armors/armor_Full_Fortified_Armor_7emTSt6nhZuTlvt5.json +++ b/src/packs/items/armors/armor_Full_Fortified_Armor_7emTSt6nhZuTlvt5.json @@ -5,10 +5,6 @@ "_id": "7emTSt6nhZuTlvt5", "img": "icons/equipment/chest/breastplate-layered-steel.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Full_Plate_Armor_UdUJNa31WxFW2noa.json b/src/packs/items/armors/armor_Full_Plate_Armor_UdUJNa31WxFW2noa.json index 7701d063..1ea120ed 100644 --- a/src/packs/items/armors/armor_Full_Plate_Armor_UdUJNa31WxFW2noa.json +++ b/src/packs/items/armors/armor_Full_Plate_Armor_UdUJNa31WxFW2noa.json @@ -5,10 +5,6 @@ "_id": "UdUJNa31WxFW2noa", "img": "icons/equipment/chest/breastplate-collared-steel.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Gambeson_Armor_yJFp1bfpecDcStVK.json b/src/packs/items/armors/armor_Gambeson_Armor_yJFp1bfpecDcStVK.json index 0ede5b60..1c775402 100644 --- a/src/packs/items/armors/armor_Gambeson_Armor_yJFp1bfpecDcStVK.json +++ b/src/packs/items/armors/armor_Gambeson_Armor_yJFp1bfpecDcStVK.json @@ -5,10 +5,6 @@ "_id": "yJFp1bfpecDcStVK", "img": "icons/equipment/chest/vest-leather-tattered-white.webp", "system": { - "armor": { - "current": 0, - "max": 3 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Harrowbone_Armor_dvyQeUVRLc9y6rnt.json b/src/packs/items/armors/armor_Harrowbone_Armor_dvyQeUVRLc9y6rnt.json index 85ad1d6a..82b4f791 100644 --- a/src/packs/items/armors/armor_Harrowbone_Armor_dvyQeUVRLc9y6rnt.json +++ b/src/packs/items/armors/armor_Harrowbone_Armor_dvyQeUVRLc9y6rnt.json @@ -5,10 +5,6 @@ "_id": "dvyQeUVRLc9y6rnt", "img": "icons/equipment/chest/breastplate-gorget-steel.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": { "IzM88FIxQ35P5VB2": { diff --git a/src/packs/items/armors/armor_Improved_Chainmail_Armor_K5WkjS0NGqHYmhU3.json b/src/packs/items/armors/armor_Improved_Chainmail_Armor_K5WkjS0NGqHYmhU3.json index ef93ecdd..96e320d1 100644 --- a/src/packs/items/armors/armor_Improved_Chainmail_Armor_K5WkjS0NGqHYmhU3.json +++ b/src/packs/items/armors/armor_Improved_Chainmail_Armor_K5WkjS0NGqHYmhU3.json @@ -5,10 +5,6 @@ "_id": "K5WkjS0NGqHYmhU3", "img": "icons/equipment/chest/breastplate-metal-scaled-grey.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Improved_Full_Plate_Armor_9f7RozpPTqrzJS1m.json b/src/packs/items/armors/armor_Improved_Full_Plate_Armor_9f7RozpPTqrzJS1m.json index 1723c53a..ee63a774 100644 --- a/src/packs/items/armors/armor_Improved_Full_Plate_Armor_9f7RozpPTqrzJS1m.json +++ b/src/packs/items/armors/armor_Improved_Full_Plate_Armor_9f7RozpPTqrzJS1m.json @@ -5,10 +5,6 @@ "_id": "9f7RozpPTqrzJS1m", "img": "icons/equipment/chest/breastplate-cuirass-steel-grey.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Improved_Gambeson_Armor_jphnMZjnS2FkOH3s.json b/src/packs/items/armors/armor_Improved_Gambeson_Armor_jphnMZjnS2FkOH3s.json index a2ff6554..6f4ea1c3 100644 --- a/src/packs/items/armors/armor_Improved_Gambeson_Armor_jphnMZjnS2FkOH3s.json +++ b/src/packs/items/armors/armor_Improved_Gambeson_Armor_jphnMZjnS2FkOH3s.json @@ -5,10 +5,6 @@ "_id": "jphnMZjnS2FkOH3s", "img": "icons/equipment/chest/breastplate-quilted-brown.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Improved_Leather_Armor_t91M61pSCMKStTNt.json b/src/packs/items/armors/armor_Improved_Leather_Armor_t91M61pSCMKStTNt.json index efa3643d..a4f38cc6 100644 --- a/src/packs/items/armors/armor_Improved_Leather_Armor_t91M61pSCMKStTNt.json +++ b/src/packs/items/armors/armor_Improved_Leather_Armor_t91M61pSCMKStTNt.json @@ -5,10 +5,6 @@ "_id": "t91M61pSCMKStTNt", "img": "icons/equipment/chest/breastplate-banded-simple-leather-brown.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Irontree_Breastplate_Armor_tzZntboNtHL5C6VM.json b/src/packs/items/armors/armor_Irontree_Breastplate_Armor_tzZntboNtHL5C6VM.json index a664ad9c..a9e9eaca 100644 --- a/src/packs/items/armors/armor_Irontree_Breastplate_Armor_tzZntboNtHL5C6VM.json +++ b/src/packs/items/armors/armor_Irontree_Breastplate_Armor_tzZntboNtHL5C6VM.json @@ -5,10 +5,6 @@ "_id": "tzZntboNtHL5C6VM", "img": "icons/equipment/chest/breastplate-layered-leather-brown-silver.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Leather_Armor_nibfdNtp2PtxvbVz.json b/src/packs/items/armors/armor_Leather_Armor_nibfdNtp2PtxvbVz.json index 93d8f0cc..37a13f2b 100644 --- a/src/packs/items/armors/armor_Leather_Armor_nibfdNtp2PtxvbVz.json +++ b/src/packs/items/armors/armor_Leather_Armor_nibfdNtp2PtxvbVz.json @@ -5,10 +5,6 @@ "_id": "nibfdNtp2PtxvbVz", "img": "icons/equipment/chest/breastplate-layered-leather-brown.webp", "system": { - "armor": { - "current": 0, - "max": 3 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Legendary_Chainmail_Armor_EsIN5OLKe9ZYFNXZ.json b/src/packs/items/armors/armor_Legendary_Chainmail_Armor_EsIN5OLKe9ZYFNXZ.json index 6c93cbe4..4bee5e4f 100644 --- a/src/packs/items/armors/armor_Legendary_Chainmail_Armor_EsIN5OLKe9ZYFNXZ.json +++ b/src/packs/items/armors/armor_Legendary_Chainmail_Armor_EsIN5OLKe9ZYFNXZ.json @@ -5,10 +5,6 @@ "_id": "EsIN5OLKe9ZYFNXZ", "img": "icons/equipment/chest/breastplate-banded-blue.webp", "system": { - "armor": { - "current": 0, - "max": 7 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Legendary_Full_Plate_Armor_SXWjUR2aUR6bYvdl.json b/src/packs/items/armors/armor_Legendary_Full_Plate_Armor_SXWjUR2aUR6bYvdl.json index f66e4c38..baf544c2 100644 --- a/src/packs/items/armors/armor_Legendary_Full_Plate_Armor_SXWjUR2aUR6bYvdl.json +++ b/src/packs/items/armors/armor_Legendary_Full_Plate_Armor_SXWjUR2aUR6bYvdl.json @@ -5,10 +5,6 @@ "_id": "SXWjUR2aUR6bYvdl", "img": "icons/equipment/chest/breastplate-layered-steel-blue-gold.webp", "system": { - "armor": { - "current": 0, - "max": 7 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Legendary_Gambeson_Armor_c6tMXz4rPf9ioQrf.json b/src/packs/items/armors/armor_Legendary_Gambeson_Armor_c6tMXz4rPf9ioQrf.json index 4cf1c856..338c85e8 100644 --- a/src/packs/items/armors/armor_Legendary_Gambeson_Armor_c6tMXz4rPf9ioQrf.json +++ b/src/packs/items/armors/armor_Legendary_Gambeson_Armor_c6tMXz4rPf9ioQrf.json @@ -5,10 +5,6 @@ "_id": "c6tMXz4rPf9ioQrf", "img": "icons/equipment/chest/breastplate-layered-leather-blue-gold.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Legendary_Leather_Armor_Tptgl5WOj76TyFn7.json b/src/packs/items/armors/armor_Legendary_Leather_Armor_Tptgl5WOj76TyFn7.json index 3ddc5ed7..42334dc4 100644 --- a/src/packs/items/armors/armor_Legendary_Leather_Armor_Tptgl5WOj76TyFn7.json +++ b/src/packs/items/armors/armor_Legendary_Leather_Armor_Tptgl5WOj76TyFn7.json @@ -5,10 +5,6 @@ "_id": "Tptgl5WOj76TyFn7", "img": "icons/equipment/chest/breastplate-layered-gilded-black.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Monett_s_Cloak_AQzU2RsqS5V5bd1v.json b/src/packs/items/armors/armor_Monett_s_Cloak_AQzU2RsqS5V5bd1v.json index 6bb479a4..9a8e1f22 100644 --- a/src/packs/items/armors/armor_Monett_s_Cloak_AQzU2RsqS5V5bd1v.json +++ b/src/packs/items/armors/armor_Monett_s_Cloak_AQzU2RsqS5V5bd1v.json @@ -5,10 +5,6 @@ "_id": "AQzU2RsqS5V5bd1v", "img": "icons/equipment/chest/coat-collared-red.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Rosewild_Armor_tN8kAeBvNKM3EBFo.json b/src/packs/items/armors/armor_Rosewild_Armor_tN8kAeBvNKM3EBFo.json index e3cde9fb..0f0f6430 100644 --- a/src/packs/items/armors/armor_Rosewild_Armor_tN8kAeBvNKM3EBFo.json +++ b/src/packs/items/armors/armor_Rosewild_Armor_tN8kAeBvNKM3EBFo.json @@ -5,10 +5,6 @@ "_id": "tN8kAeBvNKM3EBFo", "img": "icons/equipment/chest/breastplate-banded-leather-purple.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": { "QRTnCYxJfuJHdnyV": { diff --git a/src/packs/items/armors/armor_Runes_of_Fortification_P4qAEDJUoNLgVRsA.json b/src/packs/items/armors/armor_Runes_of_Fortification_P4qAEDJUoNLgVRsA.json index 2ccc80da..240a4f3e 100644 --- a/src/packs/items/armors/armor_Runes_of_Fortification_P4qAEDJUoNLgVRsA.json +++ b/src/packs/items/armors/armor_Runes_of_Fortification_P4qAEDJUoNLgVRsA.json @@ -5,10 +5,6 @@ "_id": "P4qAEDJUoNLgVRsA", "img": "icons/magic/symbols/rune-sigil-red-orange.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": { "37KLF2bim9nRdPTU": { diff --git a/src/packs/items/armors/armor_Runetan_Floating_Armor_tHlBUDQC24YMZqd6.json b/src/packs/items/armors/armor_Runetan_Floating_Armor_tHlBUDQC24YMZqd6.json index 593bc8e0..8d4af425 100644 --- a/src/packs/items/armors/armor_Runetan_Floating_Armor_tHlBUDQC24YMZqd6.json +++ b/src/packs/items/armors/armor_Runetan_Floating_Armor_tHlBUDQC24YMZqd6.json @@ -5,10 +5,6 @@ "_id": "tHlBUDQC24YMZqd6", "img": "icons/equipment/chest/breastplate-layered-leather-black.webp", "system": { - "armor": { - "current": 0, - "max": 4 - }, "description": "", "actions": { "Nn33zCIcWe6LQMDH": { diff --git a/src/packs/items/armors/armor_Savior_Chainmail_8X16lJQ3xltTwynm.json b/src/packs/items/armors/armor_Savior_Chainmail_8X16lJQ3xltTwynm.json index 6826254a..714e8592 100644 --- a/src/packs/items/armors/armor_Savior_Chainmail_8X16lJQ3xltTwynm.json +++ b/src/packs/items/armors/armor_Savior_Chainmail_8X16lJQ3xltTwynm.json @@ -5,10 +5,6 @@ "_id": "8X16lJQ3xltTwynm", "img": "icons/equipment/chest/breastplate-layered-leather-green.webp", "system": { - "armor": { - "current": 0, - "max": 8 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Spiked_Plate_Armor_QjwsIhXKqnlvRBMv.json b/src/packs/items/armors/armor_Spiked_Plate_Armor_QjwsIhXKqnlvRBMv.json index ac9115a2..cb5fc720 100644 --- a/src/packs/items/armors/armor_Spiked_Plate_Armor_QjwsIhXKqnlvRBMv.json +++ b/src/packs/items/armors/armor_Spiked_Plate_Armor_QjwsIhXKqnlvRBMv.json @@ -5,10 +5,6 @@ "_id": "QjwsIhXKqnlvRBMv", "img": "icons/equipment/chest/breastplate-banded-steel-studded.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": {}, "attached": [], diff --git a/src/packs/items/armors/armor_Tyris_Soft_Armor_PSW3BxCGmtLeWOxM.json b/src/packs/items/armors/armor_Tyris_Soft_Armor_PSW3BxCGmtLeWOxM.json index c6766018..da640830 100644 --- a/src/packs/items/armors/armor_Tyris_Soft_Armor_PSW3BxCGmtLeWOxM.json +++ b/src/packs/items/armors/armor_Tyris_Soft_Armor_PSW3BxCGmtLeWOxM.json @@ -5,10 +5,6 @@ "_id": "PSW3BxCGmtLeWOxM", "img": "icons/equipment/chest/robe-layered-purple.webp", "system": { - "armor": { - "current": 0, - "max": 5 - }, "description": "", "actions": { "Ch6IhuPewBeseGez": { diff --git a/src/packs/items/armors/armor_Veritas_Opal_Armor_OvzgUTYy2RCN85vV.json b/src/packs/items/armors/armor_Veritas_Opal_Armor_OvzgUTYy2RCN85vV.json index 403b79e8..08a1b573 100644 --- a/src/packs/items/armors/armor_Veritas_Opal_Armor_OvzgUTYy2RCN85vV.json +++ b/src/packs/items/armors/armor_Veritas_Opal_Armor_OvzgUTYy2RCN85vV.json @@ -5,10 +5,6 @@ "_id": "OvzgUTYy2RCN85vV", "img": "icons/equipment/chest/breastplate-collared-steel-green.webp", "system": { - "armor": { - "current": 0, - "max": 6 - }, "description": "", "actions": { "sY3W5JYspN5Du5ag": { diff --git a/src/packs/items/armors/folders_Special_tI3bfr6Sgi16Z7zm.json b/src/packs/items/armors/folders_Special_tI3bfr6Sgi16Z7zm.json new file mode 100644 index 00000000..65c4eca8 --- /dev/null +++ b/src/packs/items/armors/folders_Special_tI3bfr6Sgi16Z7zm.json @@ -0,0 +1,12 @@ +{ + "type": "Item", + "folder": null, + "name": "Special", + "color": null, + "sorting": "a", + "_id": "tI3bfr6Sgi16Z7zm", + "description": "", + "sort": 0, + "flags": {}, + "_key": "!folders!tI3bfr6Sgi16Z7zm" +} diff --git a/src/packs/items/weapons/weapon_Advanced_Round_Shield_hiEOGF2reabGLUoi.json b/src/packs/items/weapons/weapon_Advanced_Round_Shield_hiEOGF2reabGLUoi.json index 54800642..da5d5bf8 100644 --- a/src/packs/items/weapons/weapon_Advanced_Round_Shield_hiEOGF2reabGLUoi.json +++ b/src/packs/items/weapons/weapon_Advanced_Round_Shield_hiEOGF2reabGLUoi.json @@ -113,26 +113,26 @@ "name": "Protective", "description": "

Add the item's Tier to your Armor Score

", "img": "icons/skills/melee/shield-block-gray-orange.webp", - "_id": "7285CRGdZfHCEtT2", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier", + "priority": null + } + ], + "_id": "i5HfkF5aKQuUCTEG", "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier" - } - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null }, "origin": null, "tint": "#ffffff", @@ -143,10 +143,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!hiEOGF2reabGLUoi.7285CRGdZfHCEtT2" + "_key": "!items.effects!hiEOGF2reabGLUoi.i5HfkF5aKQuUCTEG" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Advanced_Tower_Shield_OfOzQbs4hg6QbfTG.json b/src/packs/items/weapons/weapon_Advanced_Tower_Shield_OfOzQbs4hg6QbfTG.json index a88749a8..9fe47fc0 100644 --- a/src/packs/items/weapons/weapon_Advanced_Tower_Shield_OfOzQbs4hg6QbfTG.json +++ b/src/packs/items/weapons/weapon_Advanced_Tower_Shield_OfOzQbs4hg6QbfTG.json @@ -113,25 +113,25 @@ "name": "Barrier", "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", "img": "icons/skills/melee/shield-block-bash-blue.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier + 1" + }, + { + "key": "system.evasion", + "mode": 2, + "value": "-1" + } + ], "_id": "87gedjJZGdFY81Mt", "type": "base", - "system": { - "changes": [ - { - "key": "system.evasion", - "type": "add", - "value": -1, - "phase": "initial", - "priority": 0 - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null }, "origin": null, "tint": "#ffffff", @@ -142,49 +142,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, "_key": "!items.effects!OfOzQbs4hg6QbfTG.87gedjJZGdFY81Mt" - }, - { - "name": "Barrier", - "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", - "img": "icons/skills/melee/shield-block-bash-blue.webp", - "_id": "J0f7zqqOr61ADpdy", - "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier + 1" - } - } - ] - }, - "disabled": false, - "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false - }, - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!OfOzQbs4hg6QbfTG.J0f7zqqOr61ADpdy" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Improved_Round_Shield_DlinEBGZfIlvreO3.json b/src/packs/items/weapons/weapon_Improved_Round_Shield_DlinEBGZfIlvreO3.json index 65868950..091355c2 100644 --- a/src/packs/items/weapons/weapon_Improved_Round_Shield_DlinEBGZfIlvreO3.json +++ b/src/packs/items/weapons/weapon_Improved_Round_Shield_DlinEBGZfIlvreO3.json @@ -113,26 +113,26 @@ "name": "Protective", "description": "

Add the item's Tier to your Armor Score

", "img": "icons/skills/melee/shield-block-gray-orange.webp", - "_id": "pZCrWd7zLTarvEQK", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier", + "priority": null + } + ], + "_id": "cXWSV50apzaNQkdA", "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier" - } - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null }, "origin": null, "tint": "#ffffff", @@ -143,10 +143,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!DlinEBGZfIlvreO3.pZCrWd7zLTarvEQK" + "_key": "!items.effects!DlinEBGZfIlvreO3.cXWSV50apzaNQkdA" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Improved_Tower_Shield_bxt3NsbMqTSdI5ab.json b/src/packs/items/weapons/weapon_Improved_Tower_Shield_bxt3NsbMqTSdI5ab.json index 64555dfa..6f55fe3d 100644 --- a/src/packs/items/weapons/weapon_Improved_Tower_Shield_bxt3NsbMqTSdI5ab.json +++ b/src/packs/items/weapons/weapon_Improved_Tower_Shield_bxt3NsbMqTSdI5ab.json @@ -113,25 +113,25 @@ "name": "Barrier", "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", "img": "icons/skills/melee/shield-block-bash-blue.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier + 1" + }, + { + "key": "system.evasion", + "mode": 2, + "value": "-1" + } + ], "_id": "tkNEA1PO3jEFhKCa", "type": "base", - "system": { - "changes": [ - { - "key": "system.evasion", - "type": "add", - "value": -1, - "phase": "initial", - "priority": 0 - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null }, "origin": null, "tint": "#ffffff", @@ -142,49 +142,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, "_key": "!items.effects!bxt3NsbMqTSdI5ab.tkNEA1PO3jEFhKCa" - }, - { - "name": "Barrier", - "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", - "img": "icons/skills/melee/shield-block-bash-blue.webp", - "_id": "XugJeHJdnC6IymSa", - "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier + 1" - } - } - ] - }, - "disabled": false, - "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false - }, - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!bxt3NsbMqTSdI5ab.XugJeHJdnC6IymSa" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Labrys_Axe_ijWppQzSOqVCb3rE.json b/src/packs/items/weapons/weapon_Labrys_Axe_ijWppQzSOqVCb3rE.json index 11994d3e..0dd7d23a 100644 --- a/src/packs/items/weapons/weapon_Labrys_Axe_ijWppQzSOqVCb3rE.json +++ b/src/packs/items/weapons/weapon_Labrys_Axe_ijWppQzSOqVCb3rE.json @@ -113,26 +113,20 @@ "name": "Protective", "description": "Add your character's Tier to your Armor Score", "img": "icons/skills/melee/shield-block-gray-orange.webp", - "_id": "vnR4Zhnb0rOqwrFw", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier" + } + ], + "_id": "qTxADRsQnKiYfOiQ", "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier" - } - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null }, "origin": null, "tint": "#ffffff", @@ -143,10 +137,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!ijWppQzSOqVCb3rE.vnR4Zhnb0rOqwrFw" + "_key": "!items.effects!ijWppQzSOqVCb3rE.qTxADRsQnKiYfOiQ" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Legendary_Round_Shield_A28WL9E2lJ3iLZHW.json b/src/packs/items/weapons/weapon_Legendary_Round_Shield_A28WL9E2lJ3iLZHW.json index 85134d21..5eedb6c2 100644 --- a/src/packs/items/weapons/weapon_Legendary_Round_Shield_A28WL9E2lJ3iLZHW.json +++ b/src/packs/items/weapons/weapon_Legendary_Round_Shield_A28WL9E2lJ3iLZHW.json @@ -113,26 +113,26 @@ "name": "Protective", "description": "

Add the item's Tier to your Armor Score

", "img": "icons/skills/melee/shield-block-gray-orange.webp", - "_id": "EixxJrRHyc6kj3Wg", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier", + "priority": null + } + ], + "_id": "Z2p00q5h6x6seXys", "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier" - } - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null }, "origin": null, "tint": "#ffffff", @@ -143,10 +143,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!A28WL9E2lJ3iLZHW.EixxJrRHyc6kj3Wg" + "_key": "!items.effects!A28WL9E2lJ3iLZHW.Z2p00q5h6x6seXys" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Legendary_Tower_Shield_MaJIROht7A9LxIZx.json b/src/packs/items/weapons/weapon_Legendary_Tower_Shield_MaJIROht7A9LxIZx.json index 772e9ca9..49ca454a 100644 --- a/src/packs/items/weapons/weapon_Legendary_Tower_Shield_MaJIROht7A9LxIZx.json +++ b/src/packs/items/weapons/weapon_Legendary_Tower_Shield_MaJIROht7A9LxIZx.json @@ -113,25 +113,25 @@ "name": "Barrier", "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", "img": "icons/skills/melee/shield-block-bash-blue.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier + 1" + }, + { + "key": "system.evasion", + "mode": 2, + "value": "-1" + } + ], "_id": "lBJMzxdGO2nJdTQS", "type": "base", - "system": { - "changes": [ - { - "key": "system.evasion", - "type": "add", - "value": -1, - "phase": "initial", - "priority": 0 - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null }, "origin": null, "tint": "#ffffff", @@ -142,49 +142,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, "_key": "!items.effects!MaJIROht7A9LxIZx.lBJMzxdGO2nJdTQS" - }, - { - "name": "Barrier", - "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", - "img": "icons/skills/melee/shield-block-bash-blue.webp", - "_id": "1fgUIaXl6VQrhP7j", - "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier + 1" - } - } - ] - }, - "disabled": false, - "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false - }, - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!MaJIROht7A9LxIZx.1fgUIaXl6VQrhP7j" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Round_Shield_mxwWKDujgsRcZWPT.json b/src/packs/items/weapons/weapon_Round_Shield_mxwWKDujgsRcZWPT.json index 55e92f01..ccba4b0e 100644 --- a/src/packs/items/weapons/weapon_Round_Shield_mxwWKDujgsRcZWPT.json +++ b/src/packs/items/weapons/weapon_Round_Shield_mxwWKDujgsRcZWPT.json @@ -113,26 +113,26 @@ "name": "Protective", "description": "

Add the item's Tier to your Armor Score

", "img": "icons/skills/melee/shield-block-gray-orange.webp", - "_id": "eV4lFIpQMiKERj4U", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier", + "priority": null + } + ], + "_id": "M70a81e0Mg66jHRL", "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier" - } - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null, + "seconds": null, + "rounds": null, + "turns": null, + "startRound": null, + "startTurn": null }, "origin": null, "tint": "#ffffff", @@ -143,10 +143,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!mxwWKDujgsRcZWPT.eV4lFIpQMiKERj4U" + "_key": "!items.effects!mxwWKDujgsRcZWPT.M70a81e0Mg66jHRL" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Spiked_Shield_vzyzFwLUniWZV1rt.json b/src/packs/items/weapons/weapon_Spiked_Shield_vzyzFwLUniWZV1rt.json index 39c18b08..2dd08026 100644 --- a/src/packs/items/weapons/weapon_Spiked_Shield_vzyzFwLUniWZV1rt.json +++ b/src/packs/items/weapons/weapon_Spiked_Shield_vzyzFwLUniWZV1rt.json @@ -113,31 +113,32 @@ "name": "Double Duty", "description": "+1 to Armor Score; +1 to primary weapon damage within Melee range", "img": "icons/skills/melee/sword-shield-stylized-white.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "1" + }, + { + "key": "system.bonuses.damage.primaryWeapon.bonus", + "mode": 2, + "value": "1" + } + ], "system": { "rangeDependence": { "enabled": true, "range": "melee", "target": "hostile", "type": "withinRange" - }, - "changes": [ - { - "key": "system.bonuses.damage.primaryWeapon.bonus", - "type": "add", - "value": 1, - "phase": "initial", - "priority": 0 - } - ] + } }, "_id": "d3TJtlpoHBCztbom", "type": "base", "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null }, "origin": null, "tint": "#ffffff", @@ -148,49 +149,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, "_key": "!items.effects!vzyzFwLUniWZV1rt.d3TJtlpoHBCztbom" - }, - { - "name": "Double Duty", - "description": "+1 to Armor Score; +1 to primary weapon damage within Melee range", - "img": "icons/skills/melee/sword-shield-stylized-white.webp", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "1" - } - } - ] - }, - "_id": "mvUY9LGfwICak7cE", - "type": "base", - "disabled": false, - "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false - }, - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!vzyzFwLUniWZV1rt.mvUY9LGfwICak7cE" } ], "sort": 0, diff --git a/src/packs/items/weapons/weapon_Tower_Shield_C9aWpK1shVMWP4m5.json b/src/packs/items/weapons/weapon_Tower_Shield_C9aWpK1shVMWP4m5.json index e584b63c..47043c54 100644 --- a/src/packs/items/weapons/weapon_Tower_Shield_C9aWpK1shVMWP4m5.json +++ b/src/packs/items/weapons/weapon_Tower_Shield_C9aWpK1shVMWP4m5.json @@ -113,25 +113,25 @@ "name": "Barrier", "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", "img": "icons/skills/melee/shield-block-bash-blue.webp", + "changes": [ + { + "key": "system.armorScore", + "mode": 2, + "value": "ITEM.@system.tier + 1" + }, + { + "key": "system.evasion", + "mode": 2, + "value": "-1" + } + ], "_id": "8r0TcKWXboFV0eqS", "type": "base", - "system": { - "changes": [ - { - "key": "system.evasion", - "type": "add", - "value": -1, - "phase": "initial", - "priority": 0 - } - ] - }, + "system": {}, "disabled": false, "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false + "startTime": null, + "combat": null }, "origin": null, "tint": "#ffffff", @@ -142,49 +142,7 @@ "_stats": { "compendiumSource": null }, - "start": null, - "showIcon": 1, - "folder": null, "_key": "!items.effects!C9aWpK1shVMWP4m5.8r0TcKWXboFV0eqS" - }, - { - "name": "Barrier", - "description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion", - "img": "icons/skills/melee/shield-block-bash-blue.webp", - "_id": "tLRc4UAnGuIq7er3", - "type": "base", - "system": { - "changes": [ - { - "type": "armor", - "phase": "initial", - "priority": 20, - "value": { - "max": "ITEM.@system.tier + 1" - } - } - ] - }, - "disabled": false, - "duration": { - "value": null, - "units": "seconds", - "expiry": null, - "expired": false - }, - "origin": null, - "tint": "#ffffff", - "transfer": true, - "statuses": [], - "sort": 0, - "flags": {}, - "_stats": { - "compendiumSource": null - }, - "start": null, - "showIcon": 1, - "folder": null, - "_key": "!items.effects!C9aWpK1shVMWP4m5.tLRc4UAnGuIq7er3" } ], "sort": 0, diff --git a/styles/less/dialog/damage-reduction/damage-reduction-container.less b/styles/less/dialog/damage-reduction/damage-reduction-container.less index e8242bdd..2f343fb3 100644 --- a/styles/less/dialog/damage-reduction/damage-reduction-container.less +++ b/styles/less/dialog/damage-reduction/damage-reduction-container.less @@ -35,10 +35,7 @@ display: flex; flex-direction: column; align-items: center; - - &.full-width { - width: 100%; - } + width: 100%; } .padded { @@ -48,7 +45,6 @@ .armor-title { margin: 0; white-space: nowrap; - width: 100%; } .resources-container { @@ -66,17 +62,12 @@ .mark-selection { display: flex; - flex-direction: column; + align-items: center; width: 100%; margin: 0; - h4 { - margin: 0; - } - .mark-selection-inner { display: flex; - justify-content: center; gap: 8px; .mark-container { @@ -100,19 +91,6 @@ opacity: 0.2; } - &.spent { - ::after { - position: absolute; - content: '/'; - color: red; - font-weight: 700; - font-size: 1.8em; - left: -1px; - top: -7px; - rotate: 13deg; - } - } - .fa-shield { position: relative; right: 0.5px; diff --git a/styles/less/sheets/activeEffects/activeEffects.less b/styles/less/sheets/activeEffects/activeEffects.less index b6fa98db..c6e00245 100644 --- a/styles/less/sheets/activeEffects/activeEffects.less +++ b/styles/less/sheets/activeEffects/activeEffects.less @@ -44,71 +44,6 @@ text-align: center; } } - - .armor-change-container { - padding-top: 0; - padding-bottom: 4px; - row-gap: 0; - - legend { - display: flex; - align-items: center; - padding-left: 3px; - } - - header { - padding: 0; - left: -0.25rem; // TODO: Find why this header is offset 0.25rem to the right so this can be removed. - } - - header, - ol { - grid-template-columns: 5rem 7rem 12rem 4rem; - } - - .damage-thresholds-container { - width: 100%; - display: flex; - flex-direction: column; - gap: 4px; - - .damage-threshold-title { - display: flex; - align-items: center; - justify-content: center; - gap: 8px; - - &::before, - &::after { - content: ''; - flex: 1; - height: 2px; - } - - &::before { - background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, light-dark(@dark-blue, @golden) 100%); - } - - &::after { - background: linear-gradient(90deg, light-dark(@dark-blue, @golden) 0%, rgba(0, 0, 0, 0) 100%); - } - - span { - font-size: var(--font-size-18); - } - } - - .form-group { - flex-direction: column; - gap: 0; - - label { - color: inherit; - line-height: 16px; - } - } - } - } } .form-group { diff --git a/styles/less/sheets/actors/character/sidebar.less b/styles/less/sheets/actors/character/sidebar.less index 8bbede76..04baf2b9 100644 --- a/styles/less/sheets/actors/character/sidebar.less +++ b/styles/less/sheets/actors/character/sidebar.less @@ -276,23 +276,6 @@ } } - .slot-label { - .slot-value-container { - position: relative; - display: flex; - align-items: center; - justify-content: center; - width: 100%; - - i { - position: absolute; - right: 0; - font-size: 12px; - color: light-dark(@beige, @dark-blue); - } - } - } - .status-value { padding: 0 5px; } @@ -315,12 +298,6 @@ border-radius: 3px; background: light-dark(@dark-blue, @golden); clip-path: none; - cursor: pointer; - display: flex; - align-items: center; - gap: 4px; - border: 1px solid transparent; - transition: all 0.3s ease; h4 { font-weight: bold; @@ -329,21 +306,6 @@ color: light-dark(@beige, @dark-blue); font-size: var(--font-size-12); } - - i { - font-size: 12px; - color: light-dark(@beige, @dark-blue); - } - - &:hover { - background: light-dark(@light-black, @dark-blue); - border: 1px solid light-dark(@dark-blue, @golden); - - h4, - i { - color: light-dark(@dark-blue, @golden); - } - } } .slot-value { position: absolute; @@ -393,19 +355,6 @@ font-size: var(--font-size-12); flex-wrap: wrap; justify-content: center; - border: 1px solid transparent; - transition: all 0.3s ease; - - &:hover { - background: light-dark(@light-black, @dark-blue); - border: 1px solid light-dark(@dark-blue, @golden); - - .label, - .value, - i { - color: light-dark(@dark-blue, @golden); - } - } .label { padding-right: 1px; diff --git a/styles/less/ux/index.less b/styles/less/ux/index.less index 6fad3ab1..c6c40f78 100644 --- a/styles/less/ux/index.less +++ b/styles/less/ux/index.less @@ -1,5 +1,4 @@ @import './tooltip/tooltip.less'; -@import './tooltip/armorManagement.less'; @import './tooltip/battlepoints.less'; @import './tooltip/bordered-tooltip.less'; @import './tooltip/domain-cards.less'; diff --git a/styles/less/ux/tooltip/armorManagement.less b/styles/less/ux/tooltip/armorManagement.less index e1ac6bb9..bc716fa0 100644 --- a/styles/less/ux/tooltip/armorManagement.less +++ b/styles/less/ux/tooltip/armorManagement.less @@ -1,19 +1,7 @@ -@import '../../utils/fonts.less'; -@import '../../utils/colors.less'; - .bordered-tooltip.locked-tooltip .daggerheart.armor-management-container { display: flex; flex-direction: column; - gap: 10px; - padding-bottom: 10px; - - h3 { - font-family: @font-subtitle; - margin: 0; - border: none; - font-weight: normal; - font-size: var(--font-size-20); - } + gap: 16px; .armor-source-container { display: flex; @@ -22,16 +10,16 @@ gap: 4px; .armor-source-label { - font-family: @font-body; - margin: 0; + font-size: var(--font-size-24); + font-weight: bold; } .status-bar { display: flex; justify-content: center; position: relative; - width: 100%; - height: 30px; + width: 80px; + height: 20px; .status-value { position: absolute; @@ -39,8 +27,8 @@ padding: 0 5px; font-size: 1rem; align-items: center; - width: 100%; - height: 30px; + width: 80px; + height: 20px; justify-content: center; text-align: center; z-index: 2; @@ -48,13 +36,13 @@ input[type='number'] { background: transparent; - font-size: 1.2rem; + font-size: 1rem; width: 30px; + height: 15px; text-align: center; border: none; outline: 2px solid transparent; color: @beige; - font-family: @font-body; &.bar-input { padding: 0; @@ -62,7 +50,6 @@ backdrop-filter: none; background: transparent; transition: all 0.3s ease; - height: 25px; &:hover, &:focus { @@ -73,16 +60,14 @@ } .bar-label { - font-family: @font-body; width: 40px; - font-size: 1.2rem; } } .progress-bar { position: absolute; appearance: none; - width: 100%; - height: 30px; + width: 80px; + height: 20px; border: 1px solid light-dark(@dark-blue, @golden); border-radius: 6px; z-index: 1; @@ -112,30 +97,4 @@ } } } - - .slot-bar { - display: flex; - flex-wrap: wrap; - gap: 4px; - padding: 5px; - border: 1px solid light-dark(@dark-blue, @golden); - border-radius: 6px; - z-index: 1; - background: @dark-blue; - align-items: center; - justify-content: center; - color: light-dark(@dark-blue, @golden); - min-height: 30px; - width: 100%; - - .armor-slot { - cursor: pointer; - transition: all 0.3s ease; - font-size: var(--font-size-12); - - .fa-shield-halved { - color: light-dark(@dark-blue-40, @golden-40); - } - } - } } diff --git a/system.json b/system.json index 9a78bf50..41e46edb 100644 --- a/system.json +++ b/system.json @@ -5,7 +5,7 @@ "version": "2.0.0", "compatibility": { "minimum": "14.355", - "verified": "14.357", + "verified": "14.356", "maximum": "14" }, "authors": [ diff --git a/templates/dialogs/damageReduction.hbs b/templates/dialogs/damageReduction.hbs index 50fe3422..57d7ee61 100644 --- a/templates/dialogs/damageReduction.hbs +++ b/templates/dialogs/damageReduction.hbs @@ -7,57 +7,53 @@
-

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.maxUseableArmor"}}

-
{{availableArmor}}
+

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.armorMarks"}}

+
{{armorMarks}}/{{armorScore}}
+ {{#if this.stress}} +
+

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.stress"}}

+
{{this.stress.value}}/{{this.stress.max}}
+
+ {{/if}}
-
- {{#each marks.armor as |source|}} -
-

{{source.label}}

-
- {{#each source.marks}} - - - - {{/each}} -
-
- {{/each}} - {{#if usesStressArmor}} -
-

{{localize "Stress"}}

-
+
+

+
+ {{#each marks.armor}} +
+ +
+ {{/each}} {{#each marks.stress}}
{{/each}} -

- {{/if}} + +
{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.usedMarks"}}
{{#if availableStressReductions}}
-

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.stressReduction"}}

+

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.stressReduction"}}

{{/if}} {{#each availableStressReductions}}
-

+

{{#if this.any}} {{localize "DAGGERHEART.GENERAL.any"}} @@ -78,7 +74,7 @@ {{#if reduceSeverity}}
-

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.reduceSeverity" nr=reduceSeverity}}

+

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.reduceSeverity" nr=reduceSeverity}}

{{/if}} @@ -86,7 +82,7 @@ {{#if thresholdImmunities}}
-

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.thresholdImmunities"}}

+

{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.thresholdImmunities"}}

{{/if}} diff --git a/templates/sheets/activeEffect/change.hbs b/templates/sheets/activeEffect/change.hbs index d7d396e4..30f643b8 100644 --- a/templates/sheets/activeEffect/change.hbs +++ b/templates/sheets/activeEffect/change.hbs @@ -3,9 +3,7 @@
- + {{formInput fields.type name=change.typePath value=change.type localize=true}}
{{formInput fields.value name=change.valuePath value=change.value elementType="input"}} diff --git a/templates/sheets/activeEffect/changes.hbs b/templates/sheets/activeEffect/changes.hbs index 47a48382..026ffd90 100644 --- a/templates/sheets/activeEffect/changes.hbs +++ b/templates/sheets/activeEffect/changes.hbs @@ -13,11 +13,4 @@ {{{change}}} {{/each}} - -
- {{localize "DAGGERHEART.GENERAL.armor"}} - {{#if typedChanges.armor}} - {{> "systems/daggerheart/templates/sheets/activeEffect/typeChanges/armorChange.hbs" typedChanges.armor fields=@root.systemFields.changes.element.types.armor.fields}} - {{/if}} -
diff --git a/templates/sheets/activeEffect/conditionals.hbs b/templates/sheets/activeEffect/conditionals.hbs index f8230d94..637ac33c 100644 --- a/templates/sheets/activeEffect/conditionals.hbs +++ b/templates/sheets/activeEffect/conditionals.hbs @@ -32,7 +32,7 @@
- +
diff --git a/templates/sheets/activeEffect/typeChanges/armorChange.hbs b/templates/sheets/activeEffect/typeChanges/armorChange.hbs deleted file mode 100644 index 662a1294..00000000 --- a/templates/sheets/activeEffect/typeChanges/armorChange.hbs +++ /dev/null @@ -1,28 +0,0 @@ -
-
{{localize "EFFECT.FIELDS.changes.element.value.label"}}
-
{{localize "DAGGERHEART.GENERAL.max"}}
-
{{localize "DAGGERHEART.EFFECTS.ChangeTypes.armor.FIELDS.interaction.label"}}
-
{{localize "EFFECT.FIELDS.changes.element.priority.label"}}
-
-
    -
  1. - - - {{formInput fields.value.fields.current name=(concat "system.changes." index ".value.current") value=value.current data-dtype="Number"}} - {{formInput fields.value.fields.max name=(concat "system.changes." index ".value.max") value=value.max data-dtype="Number"}} - {{formInput fields.value.fields.interaction name=(concat "system.changes." index ".value.interaction") value=value.interaction localize=true}} - {{formInput fields.priority name=(concat "system.changes." index ".priority") value=priority}} -
  2. -
-
-
- {{localize "DAGGERHEART.GENERAL.DamageThresholds.title"}} - -
- {{#if value.damageThresholds}} -
- {{formGroup fields.value.fields.damageThresholds.fields.major name=(concat "system.changes." index ".value.damageThresholds.major") value=value.damageThresholds.major localize=true }} - {{formGroup fields.value.fields.damageThresholds.fields.severe name=(concat "system.changes." index ".value.damageThresholds.severe") value=value.damageThresholds.severe localize=true }} -
- {{/if}} -
\ No newline at end of file diff --git a/templates/sheets/actors/character/effects.hbs b/templates/sheets/actors/character/effects.hbs index 3355d575..30fb31f4 100644 --- a/templates/sheets/actors/character/effects.hbs +++ b/templates/sheets/actors/character/effects.hbs @@ -18,7 +18,6 @@ collection=effects.inactives canCreate=true hideResources=true - disabled=true }}

\ No newline at end of file diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs index d3be4983..b2757b55 100644 --- a/templates/sheets/actors/character/sidebar.hbs +++ b/templates/sheets/actors/character/sidebar.hbs @@ -30,14 +30,14 @@
- {{#if document.system.armorScore.max}} + {{#if document.system.armor.system.marks}}
{{#if useResourcePips}} {{else}}
- + / - {{document.system.armorScore.max}} + {{document.system.armorScore}}
- + {{/if}}
{{else}} diff --git a/templates/sheets/actors/party/resources.hbs b/templates/sheets/actors/party/resources.hbs index bfbfb578..74f94806 100644 --- a/templates/sheets/actors/party/resources.hbs +++ b/templates/sheets/actors/party/resources.hbs @@ -52,12 +52,13 @@ - {{#if actor.system.armorScore.max}} + {{#if actor.system.armor.system.marks}}
{{localize "DAGGERHEART.GENERAL.armorSlots"}} - {{actor.system.armorScore.value}} / {{actor.system.armorScore.max}} + {{actor.system.armor.system.marks.value}} / {{actor.system.armorScore}}
{{/if}} diff --git a/templates/sheets/items/armor/header.hbs b/templates/sheets/items/armor/header.hbs index d8044332..d4306131 100644 --- a/templates/sheets/items/armor/header.hbs +++ b/templates/sheets/items/armor/header.hbs @@ -9,7 +9,7 @@

{{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: - {{source.system.armor.max}} + {{source.system.baseScore}} - {{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.base"}}: {{source.system.baseThresholds.major}} diff --git a/templates/sheets/items/armor/settings.hbs b/templates/sheets/items/armor/settings.hbs index 51bf1746..e7bde6fe 100644 --- a/templates/sheets/items/armor/settings.hbs +++ b/templates/sheets/items/armor/settings.hbs @@ -6,9 +6,9 @@
{{localize tabs.settings.label}} {{localize "DAGGERHEART.GENERAL.Tiers.singular"}} - {{ formField systemFields.tier value=source.system.tier }} + {{formField systemFields.tier value=source.system.tier}} {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}} - {{ formField systemFields.armor.fields.max value=source.system.armor.max }} + {{formField systemFields.baseScore value=source.system.baseScore}} {{localize "TYPES.Item.feature"}} diff --git a/templates/ui/tooltip/armorManagement.hbs b/templates/ui/tooltip/armorManagement.hbs index 963959c5..aa8c9878 100644 --- a/templates/ui/tooltip/armorManagement.hbs +++ b/templates/ui/tooltip/armorManagement.hbs @@ -1,18 +1,18 @@