mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Merge 6a5c6d6908 into 876e496d24
This commit is contained in:
commit
8f945b4ca7
91 changed files with 3160 additions and 435 deletions
|
|
@ -43,6 +43,7 @@ CONFIG.Item.dataModels = models.items.config;
|
||||||
|
|
||||||
CONFIG.ActiveEffect.documentClass = documents.DhActiveEffect;
|
CONFIG.ActiveEffect.documentClass = documents.DhActiveEffect;
|
||||||
CONFIG.ActiveEffect.dataModels = models.activeEffects.config;
|
CONFIG.ActiveEffect.dataModels = models.activeEffects.config;
|
||||||
|
CONFIG.ActiveEffect.changeTypes = { ...CONFIG.ActiveEffect.changeTypes, ...models.activeEffects.changeTypes };
|
||||||
|
|
||||||
CONFIG.Combat.documentClass = documents.DhpCombat;
|
CONFIG.Combat.documentClass = documents.DhpCombat;
|
||||||
CONFIG.Combat.dataModels = { base: models.DhCombat };
|
CONFIG.Combat.dataModels = { base: models.DhCombat };
|
||||||
|
|
@ -211,10 +212,22 @@ Hooks.once('init', () => {
|
||||||
SYSTEM.id,
|
SYSTEM.id,
|
||||||
applications.sheetConfigs.ActiveEffectConfig,
|
applications.sheetConfigs.ActiveEffectConfig,
|
||||||
{
|
{
|
||||||
|
types: ['base', 'beastform', 'horde'],
|
||||||
makeDefault: true,
|
makeDefault: true,
|
||||||
label: sheetLabel('DOCUMENT.ActiveEffect')
|
label: sheetLabel('DOCUMENT.ActiveEffect')
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
DocumentSheetConfig.registerSheet(
|
||||||
|
CONFIG.ActiveEffect.documentClass,
|
||||||
|
SYSTEM.id,
|
||||||
|
applications.sheetConfigs.ArmorActiveEffectConfig,
|
||||||
|
{
|
||||||
|
types: ['armor'],
|
||||||
|
makeDefault: true,
|
||||||
|
label: () =>
|
||||||
|
`${game.i18n.localize('TYPES.ActiveEffect.armor')} ${game.i18n.localize('DAGGERHEART.GENERAL.effect')}`
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
game.socket.on(`system.${SYSTEM.id}`, socketRegistration.handleSocketEvent);
|
game.socket.on(`system.${SYSTEM.id}`, socketRegistration.handleSocketEvent);
|
||||||
|
|
||||||
|
|
|
||||||
28
lang/en.json
28
lang/en.json
|
|
@ -16,7 +16,8 @@
|
||||||
"ActiveEffect": {
|
"ActiveEffect": {
|
||||||
"base": "Standard",
|
"base": "Standard",
|
||||||
"beastform": "Beastform",
|
"beastform": "Beastform",
|
||||||
"horde": "Horde"
|
"horde": "Horde",
|
||||||
|
"armor": "Armor"
|
||||||
},
|
},
|
||||||
"Actor": {
|
"Actor": {
|
||||||
"character": "Character",
|
"character": "Character",
|
||||||
|
|
@ -436,7 +437,7 @@
|
||||||
"text": "Are you sure you want to delete {name}?"
|
"text": "Are you sure you want to delete {name}?"
|
||||||
},
|
},
|
||||||
"DamageReduction": {
|
"DamageReduction": {
|
||||||
"armorMarks": "Armor Marks",
|
"maxUseableArmor": "Useable Armor Slots",
|
||||||
"armorWithStress": "Spend 1 stress to use an extra mark",
|
"armorWithStress": "Spend 1 stress to use an extra mark",
|
||||||
"thresholdImmunities": "Threshold Immunities",
|
"thresholdImmunities": "Threshold Immunities",
|
||||||
"stress": "Stress",
|
"stress": "Stress",
|
||||||
|
|
@ -760,6 +761,11 @@
|
||||||
"bruiser": "for each Bruiser adversary.",
|
"bruiser": "for each Bruiser adversary.",
|
||||||
"solo": "for each Solo adversary."
|
"solo": "for each Solo adversary."
|
||||||
},
|
},
|
||||||
|
"ArmorInteraction": {
|
||||||
|
"none": { "label": "Ignores Armor" },
|
||||||
|
"active": { "label": "Only Active With Armor" },
|
||||||
|
"inactive": { "label": "Only Active Without Armor" }
|
||||||
|
},
|
||||||
"ArmorFeature": {
|
"ArmorFeature": {
|
||||||
"burning": {
|
"burning": {
|
||||||
"name": "Burning",
|
"name": "Burning",
|
||||||
|
|
@ -1860,6 +1866,15 @@
|
||||||
"Attachments": {
|
"Attachments": {
|
||||||
"attachHint": "Drop items here to attach them",
|
"attachHint": "Drop items here to attach them",
|
||||||
"transferHint": "If checked, this effect will be applied to any actor that owns this Effect's parent Item. The effect is always applied if this Item is attached to another one."
|
"transferHint": "If checked, this effect will be applied to any actor that owns this Effect's parent Item. The effect is always applied if this Item is attached to another one."
|
||||||
|
},
|
||||||
|
"Armor": {
|
||||||
|
"newArmorEffect": "Armor Effect",
|
||||||
|
"FIELDS": {
|
||||||
|
"armorInteraction": {
|
||||||
|
"label": "Armor Interaction",
|
||||||
|
"hint": "Does the character wearing armor suppress this effect?"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"GENERAL": {
|
"GENERAL": {
|
||||||
|
|
@ -2244,6 +2259,7 @@
|
||||||
"duality": "Duality",
|
"duality": "Duality",
|
||||||
"dualityDice": "Duality Dice",
|
"dualityDice": "Duality Dice",
|
||||||
"dualityRoll": "Duality Roll",
|
"dualityRoll": "Duality Roll",
|
||||||
|
"effect": "Effect",
|
||||||
"enabled": "Enabled",
|
"enabled": "Enabled",
|
||||||
"evasion": "Evasion",
|
"evasion": "Evasion",
|
||||||
"equipment": "Equipment",
|
"equipment": "Equipment",
|
||||||
|
|
@ -3008,7 +3024,13 @@
|
||||||
"tokenActorsMissing": "[{names}] missing Actors",
|
"tokenActorsMissing": "[{names}] missing Actors",
|
||||||
"domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used",
|
"domainTouchRequirement": "This domain card requires {nr} {domain} cards in the loadout to be used",
|
||||||
"knowTheTide": "Know The Tide gained a token",
|
"knowTheTide": "Know The Tide gained a token",
|
||||||
"lackingItemTransferPermission": "User {user} lacks owner permission needed to transfer items to {target}"
|
"lackingItemTransferPermission": "User {user} lacks owner permission needed to transfer items to {target}",
|
||||||
|
"cannotAlterArmorEffectChanges": "You cannot alter the changes length of an armor effect",
|
||||||
|
"cannotAlterArmorEffectType": "You cannot alter the type of armor effect changes",
|
||||||
|
"cannotAlterArmorEffectKey": "You cannot alter they key of armor effect changes"
|
||||||
|
},
|
||||||
|
"Progress": {
|
||||||
|
"migrationLabel": "Performing system migration. Please wait and do not close Foundry."
|
||||||
},
|
},
|
||||||
"Sidebar": {
|
"Sidebar": {
|
||||||
"actorDirectory": {
|
"actorDirectory": {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
this.reject = reject;
|
this.reject = reject;
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.damage = damage;
|
this.damage = damage;
|
||||||
this.damageType = damageType;
|
// this.damageType = damageType;
|
||||||
|
this.damageType = ['physical'];
|
||||||
this.rulesDefault = game.settings.get(
|
this.rulesDefault = game.settings.get(
|
||||||
CONFIG.DH.id,
|
CONFIG.DH.id,
|
||||||
CONFIG.DH.SETTINGS.gameSettings.Automation
|
CONFIG.DH.SETTINGS.gameSettings.Automation
|
||||||
|
|
@ -20,14 +21,25 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
this.rulesDefault
|
this.rulesDefault
|
||||||
);
|
);
|
||||||
|
|
||||||
const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true);
|
const allArmorEffects = Array.from(actor.allApplicableEffects()).filter(x => x.type === 'armor');
|
||||||
const availableArmor = actor.system.armorScore - actor.system.armor.system.marks.value;
|
const orderedArmorEffects = game.system.api.data.activeEffects.ArmorEffect.orderEffectsForAutoChange(
|
||||||
const maxArmorMarks = canApplyArmor ? availableArmor : 0;
|
allArmorEffects,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
const armor = orderedArmorEffects.reduce((acc, effect) => {
|
||||||
|
if (effect.type !== 'armor') return acc;
|
||||||
|
const { value, max } = effect.system.armorData;
|
||||||
|
acc.push({
|
||||||
|
effect: effect,
|
||||||
|
marks: [...Array(max).keys()].reduce((acc, _, index) => {
|
||||||
|
const spent = index < value;
|
||||||
|
acc[foundry.utils.randomID()] = { selected: false, disabled: spent, spent };
|
||||||
|
return acc;
|
||||||
|
}, {})
|
||||||
|
});
|
||||||
|
|
||||||
const armor = [...Array(maxArmorMarks).keys()].reduce((acc, _) => {
|
|
||||||
acc[foundry.utils.randomID()] = { selected: false };
|
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
}, []);
|
||||||
const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce(
|
const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce(
|
||||||
(acc, _) => {
|
(acc, _) => {
|
||||||
acc[foundry.utils.randomID()] = { selected: false };
|
acc[foundry.utils.randomID()] = { selected: false };
|
||||||
|
|
@ -121,13 +133,11 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
context.thresholdImmunities =
|
context.thresholdImmunities =
|
||||||
Object.keys(this.thresholdImmunities).length > 0 ? this.thresholdImmunities : null;
|
Object.keys(this.thresholdImmunities).length > 0 ? this.thresholdImmunities : null;
|
||||||
|
|
||||||
const { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage } =
|
const { selectedStressMarks, stressReductions, currentMarks, currentDamage, maxArmorUsed, availableArmor } =
|
||||||
this.getDamageInfo();
|
this.getDamageInfo();
|
||||||
|
|
||||||
context.armorScore = this.actor.system.armorScore;
|
context.armorScore = this.actor.system.armorScore.max;
|
||||||
context.armorMarks = currentMarks;
|
context.armorMarks = currentMarks;
|
||||||
context.basicMarksUsed =
|
|
||||||
selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.value;
|
|
||||||
|
|
||||||
const stressReductionStress = this.availableStressReductions
|
const stressReductionStress = this.availableStressReductions
|
||||||
? stressReductions.reduce((acc, red) => acc + red.cost, 0)
|
? stressReductions.reduce((acc, red) => acc + red.cost, 0)
|
||||||
|
|
@ -141,16 +151,27 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
const maxArmor = this.actor.system.rules.damageReduction.maxArmorMarked.value;
|
context.maxArmorUsed = maxArmorUsed;
|
||||||
context.marks = {
|
context.availableArmor = availableArmor;
|
||||||
armor: Object.keys(this.marks.armor).reduce((acc, key, index) => {
|
context.basicMarksUsed = availableArmor === 0 || selectedStressMarks.length;
|
||||||
const mark = this.marks.armor[key];
|
|
||||||
if (!this.rulesOn || index + 1 <= maxArmor) acc[key] = mark;
|
|
||||||
|
|
||||||
return acc;
|
const armorSources = [];
|
||||||
}, {}),
|
for (const source of this.marks.armor) {
|
||||||
|
const parent = source.effect.origin
|
||||||
|
? await foundry.utils.fromUuid(source.effect.origin)
|
||||||
|
: source.effect.parent;
|
||||||
|
armorSources.push({
|
||||||
|
label: parent.name,
|
||||||
|
uuid: source.effect.uuid,
|
||||||
|
marks: source.marks
|
||||||
|
});
|
||||||
|
}
|
||||||
|
context.marks = {
|
||||||
|
armor: armorSources,
|
||||||
stress: this.marks.stress
|
stress: this.marks.stress
|
||||||
};
|
};
|
||||||
|
|
||||||
|
context.usesStressArmor = Object.keys(context.marks.stress).length;
|
||||||
context.availableStressReductions = this.availableStressReductions;
|
context.availableStressReductions = this.availableStressReductions;
|
||||||
|
|
||||||
context.damage = getDamageLabel(this.damage);
|
context.damage = getDamageLabel(this.damage);
|
||||||
|
|
@ -167,27 +188,31 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
|
|
||||||
getDamageInfo = () => {
|
getDamageInfo = () => {
|
||||||
const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected);
|
const selectedArmorMarks = this.marks.armor.flatMap(x => Object.values(x.marks).filter(x => x.selected));
|
||||||
const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected);
|
const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected);
|
||||||
const stressReductions = this.availableStressReductions
|
const stressReductions = this.availableStressReductions
|
||||||
? Object.values(this.availableStressReductions).filter(red => red.selected)
|
? Object.values(this.availableStressReductions).filter(red => red.selected)
|
||||||
: [];
|
: [];
|
||||||
const currentMarks =
|
const currentMarks = this.actor.system.armorScore.value + selectedArmorMarks.length;
|
||||||
this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.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 armorMarkReduction =
|
const armorMarkReduction =
|
||||||
selectedArmorMarks.length * this.actor.system.rules.damageReduction.increasePerArmorMark;
|
selectedArmorMarks.length * this.actor.system.rules.damageReduction.increasePerArmorMark;
|
||||||
let currentDamage = Math.max(
|
let currentDamage = Math.max(this.damage - armorMarkReduction - stressReductions.length, 0);
|
||||||
this.damage - armorMarkReduction - selectedStressMarks.length - stressReductions.length,
|
|
||||||
0
|
|
||||||
);
|
|
||||||
if (this.reduceSeverity) {
|
if (this.reduceSeverity) {
|
||||||
currentDamage = Math.max(currentDamage - this.reduceSeverity, 0);
|
currentDamage = Math.max(currentDamage - this.reduceSeverity, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.thresholdImmunities[currentDamage]) currentDamage = 0;
|
if (this.thresholdImmunities[currentDamage]) currentDamage = 0;
|
||||||
|
|
||||||
return { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage };
|
return { selectedStressMarks, stressReductions, currentMarks, currentDamage, maxArmorUsed, availableArmor };
|
||||||
};
|
};
|
||||||
|
|
||||||
static toggleRules() {
|
static toggleRules() {
|
||||||
|
|
@ -209,8 +234,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
|
|
||||||
static setMarks(_, target) {
|
static setMarks(_, target) {
|
||||||
const currentMark = this.marks[target.dataset.type][target.dataset.key];
|
const currentMark = foundry.utils.getProperty(this.marks, target.dataset.path);
|
||||||
const { selectedStressMarks, stressReductions, currentMarks, currentDamage } = this.getDamageInfo();
|
const { selectedStressMarks, stressReductions, currentDamage, availableArmor } = this.getDamageInfo();
|
||||||
|
|
||||||
if (!currentMark.selected && currentDamage === 0) {
|
if (!currentMark.selected && currentDamage === 0) {
|
||||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.damageAlreadyNone'));
|
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.damageAlreadyNone'));
|
||||||
|
|
@ -218,12 +243,18 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.rulesOn) {
|
if (this.rulesOn) {
|
||||||
if (!currentMark.selected && currentMarks === this.actor.system.armorScore) {
|
if (target.dataset.type === 'armor' && !currentMark.selected && !availableArmor) {
|
||||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noAvailableArmorMarks'));
|
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noAvailableArmorMarks'));
|
||||||
return;
|
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) {
|
if (currentMark.selected) {
|
||||||
const currentDamageLabel = getDamageLabel(currentDamage);
|
const currentDamageLabel = getDamageLabel(currentDamage);
|
||||||
for (let reduction of stressReductions) {
|
for (let reduction of stressReductions) {
|
||||||
|
|
@ -232,8 +263,16 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target.dataset.type === 'armor' && selectedStressMarks.length > 0) {
|
if (target.dataset.type === 'stress' && currentMark.armorMarkId) {
|
||||||
selectedStressMarks.forEach(mark => (mark.selected = false));
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -241,6 +280,25 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
this.render();
|
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) {
|
static useStressReduction(_, target) {
|
||||||
const damageValue = Number(target.dataset.reduction);
|
const damageValue = Number(target.dataset.reduction);
|
||||||
const stressReduction = this.availableStressReductions[damageValue];
|
const stressReduction = this.availableStressReductions[damageValue];
|
||||||
|
|
@ -279,11 +337,19 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
}
|
}
|
||||||
|
|
||||||
static async takeDamage() {
|
static async takeDamage() {
|
||||||
const { selectedArmorMarks, selectedStressMarks, stressReductions, currentDamage } = this.getDamageInfo();
|
const { selectedStressMarks, stressReductions, currentDamage } = this.getDamageInfo();
|
||||||
const armorSpent = selectedArmorMarks.length + selectedStressMarks.length;
|
const armorChanges = this.marks.armor.reduce((acc, source) => {
|
||||||
const stressSpent = selectedStressMarks.length + stressReductions.reduce((acc, red) => acc + red.cost, 0);
|
const amount = Object.values(source.marks).filter(x => x.selected).length;
|
||||||
|
if (!amount) return acc;
|
||||||
|
|
||||||
this.resolve({ modifiedDamage: currentDamage, armorSpent, stressSpent });
|
acc.push({ uuid: source.effect.uuid, amount });
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
const stressSpent =
|
||||||
|
selectedStressMarks.filter(x => x.armorMarkId).length +
|
||||||
|
stressReductions.reduce((acc, red) => acc + red.cost, 0);
|
||||||
|
|
||||||
|
this.resolve({ modifiedDamage: currentDamage, armorChanges, stressSpent });
|
||||||
await this.close(true);
|
await this.close(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ export { default as CompanionSettings } from './companion-settings.mjs';
|
||||||
export { default as SettingActiveEffectConfig } from './setting-active-effect-config.mjs';
|
export { default as SettingActiveEffectConfig } from './setting-active-effect-config.mjs';
|
||||||
export { default as SettingFeatureConfig } from './setting-feature-config.mjs';
|
export { default as SettingFeatureConfig } from './setting-feature-config.mjs';
|
||||||
export { default as EnvironmentSettings } from './environment-settings.mjs';
|
export { default as EnvironmentSettings } from './environment-settings.mjs';
|
||||||
|
export { default as ArmorActiveEffectConfig } from './armorActiveEffectConfig.mjs';
|
||||||
export { default as ActiveEffectConfig } from './activeEffectConfig.mjs';
|
export { default as ActiveEffectConfig } from './activeEffectConfig.mjs';
|
||||||
export { default as DhTokenConfig } from './token-config.mjs';
|
export { default as DhTokenConfig } from './token-config.mjs';
|
||||||
export { default as DhPrototypeTokenConfig } from './prototype-token-config.mjs';
|
export { default as DhPrototypeTokenConfig } from './prototype-token-config.mjs';
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,12 @@ export default class DHActionConfig extends DHActionBaseConfig {
|
||||||
const effectData = this._addEffectData.bind(this)();
|
const effectData = this._addEffectData.bind(this)();
|
||||||
const data = this.action.toObject();
|
const data = this.action.toObject();
|
||||||
|
|
||||||
const [created] = await this.action.item.createEmbeddedDocuments('ActiveEffect', [effectData], {
|
const created = await game.system.api.documents.DhActiveEffect.createDialog(effectData, {
|
||||||
|
parent: this.action.item,
|
||||||
render: false
|
render: false
|
||||||
});
|
});
|
||||||
|
if (!created) return;
|
||||||
|
|
||||||
data.effects.push({ _id: created._id });
|
data.effects.push({ _id: created._id });
|
||||||
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
|
this.constructor.updateForm.bind(this)(null, null, { object: foundry.utils.flattenObject(data) });
|
||||||
this.action.item.effects.get(created._id).sheet.render(true);
|
this.action.item.effects.get(created._id).sheet.render(true);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,67 @@
|
||||||
|
const { HandlebarsApplicationMixin, DocumentSheetV2 } = foundry.applications.api;
|
||||||
|
|
||||||
|
export default class ArmorActiveEffectConfig extends HandlebarsApplicationMixin(DocumentSheetV2) {
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
tag: 'form',
|
||||||
|
classes: ['daggerheart', 'sheet', 'dh-style', 'active-effect-config', 'armor-effect-config'],
|
||||||
|
form: {
|
||||||
|
handler: this.updateForm,
|
||||||
|
submitOnChange: true,
|
||||||
|
closeOnSubmit: false
|
||||||
|
},
|
||||||
|
position: { width: 560 },
|
||||||
|
actions: {
|
||||||
|
finish: ArmorActiveEffectConfig.#finish
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static PARTS = {
|
||||||
|
header: { template: 'systems/daggerheart/templates/sheets/activeEffect/header.hbs' },
|
||||||
|
tabs: { template: 'templates/generic/tab-navigation.hbs' },
|
||||||
|
details: { template: 'systems/daggerheart/templates/sheets/activeEffect/armor/details.hbs' },
|
||||||
|
settings: { template: 'systems/daggerheart/templates/sheets/activeEffect/armor/settings.hbs' },
|
||||||
|
footer: { template: 'systems/daggerheart/templates/sheets/activeEffect/armor/footer.hbs' }
|
||||||
|
};
|
||||||
|
|
||||||
|
static TABS = {
|
||||||
|
sheet: {
|
||||||
|
tabs: [
|
||||||
|
{ id: 'details', icon: 'fa-solid fa-book' },
|
||||||
|
{ id: 'settings', icon: 'fa-solid fa-bars', label: 'DAGGERHEART.GENERAL.Tabs.settings' }
|
||||||
|
],
|
||||||
|
initial: 'details',
|
||||||
|
labelPrefix: 'EFFECT.TABS'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
async _prepareContext(options) {
|
||||||
|
const context = await super._prepareContext(options);
|
||||||
|
context.systemFields = context.document.system.schema.fields;
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
async _preparePartContext(partId, context) {
|
||||||
|
const partContext = await super._preparePartContext(partId, context);
|
||||||
|
if (partId in partContext.tabs) partContext.tab = partContext.tabs[partId];
|
||||||
|
|
||||||
|
switch (partId) {
|
||||||
|
case 'details':
|
||||||
|
partContext.isActorEffect = this.document.parent?.documentName === 'Actor';
|
||||||
|
partContext.isItemEffect = this.document.parent?.documentName === 'Item';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return partContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static async updateForm(_event, _form, formData) {
|
||||||
|
await this.document.update(formData.object);
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
static #finish() {
|
||||||
|
this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -34,7 +34,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
advanceResourceDie: CharacterSheet.#advanceResourceDie,
|
advanceResourceDie: CharacterSheet.#advanceResourceDie,
|
||||||
cancelBeastform: CharacterSheet.#cancelBeastform,
|
cancelBeastform: CharacterSheet.#cancelBeastform,
|
||||||
useDowntime: this.useDowntime,
|
useDowntime: this.useDowntime,
|
||||||
viewParty: CharacterSheet.#viewParty
|
viewParty: CharacterSheet.#viewParty,
|
||||||
|
toggleArmorMangement: CharacterSheet.#toggleArmorManagement
|
||||||
},
|
},
|
||||||
window: {
|
window: {
|
||||||
resizable: true,
|
resizable: true,
|
||||||
|
|
@ -629,12 +630,12 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateArmorMarks(event) {
|
async updateArmorMarks(event) {
|
||||||
const armor = this.document.system.armor;
|
const inputValue = Number(event.currentTarget.value);
|
||||||
if (!armor) return;
|
const { value, max } = this.document.system.armorScore;
|
||||||
|
const changeValue = Math.min(inputValue - value, max - value);
|
||||||
|
|
||||||
const maxMarks = this.document.system.armorScore;
|
event.currentTarget.value = inputValue < 0 ? 0 : value + changeValue;
|
||||||
const value = Math.min(Math.max(Number(event.currentTarget.value), 0), maxMarks);
|
this.document.system.updateArmorValue({ value: changeValue });
|
||||||
await armor.update({ 'system.marks.value': value });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
@ -813,10 +814,13 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
||||||
* Toggles ArmorScore resource value.
|
* Toggles ArmorScore resource value.
|
||||||
* @type {ApplicationClickAction}
|
* @type {ApplicationClickAction}
|
||||||
*/
|
*/
|
||||||
static async #toggleArmor(_, button, element) {
|
static async #toggleArmor(_, button, _element) {
|
||||||
const ArmorValue = Number.parseInt(button.dataset.value);
|
const { value, max } = this.document.system.armorScore;
|
||||||
const newValue = this.document.system.armor.system.marks.value >= ArmorValue ? ArmorValue - 1 : ArmorValue;
|
const inputValue = Number.parseInt(button.dataset.value);
|
||||||
await this.document.system.armor.update({ 'system.marks.value': newValue });
|
const newValue = value >= inputValue ? inputValue - 1 : inputValue;
|
||||||
|
const changeValue = Math.min(newValue - value, max - value);
|
||||||
|
|
||||||
|
this.document.system.updateArmorValue({ value: changeValue });
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -942,6 +946,117 @@ 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 = [];
|
||||||
|
for (var effect of Array.from(this.document.allApplicableEffects())) {
|
||||||
|
const origin = effect.origin ? await foundry.utils.fromUuid(effect.origin) : effect.parent;
|
||||||
|
if (effect.type !== 'armor' || effect.disabled || effect.isSuppressed) continue;
|
||||||
|
armorSources.push({
|
||||||
|
uuid: effect.uuid,
|
||||||
|
name: origin.name,
|
||||||
|
...effect.system.armorData
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (armorSources.length <= 1) 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-marks-input').forEach(element => {
|
||||||
|
element.addEventListener('blur', CharacterSheet.armorSourceUpdate);
|
||||||
|
element.addEventListener('input', CharacterSheet.armorSourceInput);
|
||||||
|
});
|
||||||
|
|
||||||
|
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 armorSourceUpdate(event) {
|
||||||
|
const effect = await foundry.utils.fromUuid(event.target.dataset.uuid);
|
||||||
|
if (effect.system.changes.length !== 1) return;
|
||||||
|
const value = Math.max(Math.min(Number.parseInt(event.target.value), effect.system.armorData.max), 0);
|
||||||
|
|
||||||
|
const newChanges = [
|
||||||
|
{
|
||||||
|
...effect.system.changes[0],
|
||||||
|
value
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
event.target.value = value;
|
||||||
|
const progressBar = event.target.closest('.status-bar.armor-slots').querySelector('progress');
|
||||||
|
progressBar.value = value;
|
||||||
|
|
||||||
|
await effect.update({ 'system.changes': newChanges });
|
||||||
|
}
|
||||||
|
|
||||||
|
static async armorSourcePipUpdate(event) {
|
||||||
|
const target = event.target.closest('.armor-slot');
|
||||||
|
const effect = await foundry.utils.fromUuid(target.dataset.uuid);
|
||||||
|
if (effect.system.changes.length !== 1) return;
|
||||||
|
const { value, max } = effect.system.armorData;
|
||||||
|
|
||||||
|
const inputValue = Number.parseInt(target.dataset.value);
|
||||||
|
const decreasing = value >= inputValue;
|
||||||
|
const newValue = decreasing ? inputValue - 1 : inputValue;
|
||||||
|
|
||||||
|
const newChanges = [
|
||||||
|
{
|
||||||
|
...effect.system.changes[0],
|
||||||
|
value: newValue
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
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 >= newValue) {
|
||||||
|
armorSlot.classList.remove('fa-shield');
|
||||||
|
armorSlot.classList.add('fa-shield-halved');
|
||||||
|
} else if (!decreasing && index < newValue) {
|
||||||
|
armorSlot.classList.add('fa-shield');
|
||||||
|
armorSlot.classList.remove('fa-shield-halved');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await effect.update({ 'system.changes': newChanges });
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the downtime application.
|
* Open the downtime application.
|
||||||
* @type {ApplicationClickAction}
|
* @type {ApplicationClickAction}
|
||||||
|
|
|
||||||
|
|
@ -712,17 +712,23 @@ export default function DHApplicationMixin(Base) {
|
||||||
|
|
||||||
const cls =
|
const cls =
|
||||||
type === 'action' ? game.system.api.models.actions.actionsTypes.base : getDocumentClass(documentClass);
|
type === 'action' ? game.system.api.models.actions.actionsTypes.base : getDocumentClass(documentClass);
|
||||||
|
|
||||||
const data = {
|
const data = {
|
||||||
name: cls.defaultName({ type, parent }),
|
name: cls.defaultName({ type, parent }),
|
||||||
type,
|
type,
|
||||||
system: systemData
|
system: systemData
|
||||||
};
|
};
|
||||||
|
|
||||||
if (inVault) data['system.inVault'] = true;
|
if (inVault) data['system.inVault'] = true;
|
||||||
if (disabled) data.disabled = true;
|
if (disabled) data.disabled = true;
|
||||||
if (type === 'domainCard' && parent?.system.domains?.length) {
|
if (type === 'domainCard' && parent?.system.domains?.length) {
|
||||||
data.system.domain = parent.system.domains[0];
|
data.system.domain = parent.system.domains[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (documentClass === 'ActiveEffect') {
|
||||||
|
return cls.createDialog(data, { parent: this.document });
|
||||||
|
}
|
||||||
|
|
||||||
const doc = await cls.create(data, { parent, renderSheet: !event.shiftKey });
|
const doc = await cls.create(data, { parent, renderSheet: !event.shiftKey });
|
||||||
if (parentIsItem && type === 'feature') {
|
if (parentIsItem && type === 'feature') {
|
||||||
await this.document.update({
|
await this.document.update({
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
||||||
inactives: []
|
inactives: []
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const effect of this.actor.allApplicableEffects()) {
|
for (const effect of this.actor.allApplicableEffects({ noTransferArmor: true })) {
|
||||||
const list = effect.active ? context.effects.actives : context.effects.inactives;
|
const list = effect.active ? context.effects.actives : context.effects.inactives;
|
||||||
list.push(effect);
|
list.push(effect);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,13 @@ export default class ArmorSheet extends ItemAttachmentSheet(DHBaseItemSheet) {
|
||||||
...super.PARTS
|
...super.PARTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_attachPartListeners(partId, htmlElement, options) {
|
||||||
|
super._attachPartListeners(partId, htmlElement, options);
|
||||||
|
|
||||||
|
for (const element of htmlElement.querySelectorAll('.base-score-input'))
|
||||||
|
element.addEventListener('change', this.updateArmorEffect.bind(this));
|
||||||
|
}
|
||||||
|
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
async _preparePartContext(partId, context) {
|
async _preparePartContext(partId, context) {
|
||||||
await super._preparePartContext(partId, context);
|
await super._preparePartContext(partId, context);
|
||||||
|
|
@ -41,12 +48,26 @@ export default class ArmorSheet extends ItemAttachmentSheet(DHBaseItemSheet) {
|
||||||
switch (partId) {
|
switch (partId) {
|
||||||
case 'settings':
|
case 'settings':
|
||||||
context.features = this.document.system.armorFeatures.map(x => x.value);
|
context.features = this.document.system.armorFeatures.map(x => x.value);
|
||||||
|
context.armorScore = this.document.system.armorData.max;
|
||||||
|
break;
|
||||||
|
case 'effects':
|
||||||
|
context.effects.actives = context.effects.actives.filter(x => x.type !== 'armor');
|
||||||
|
context.effects.inactives = context.effects.actives.filter(x => x.type !== 'armor');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return context;
|
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.updateArmorMax(value);
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback function used by `tagifyElement`.
|
* Callback function used by `tagifyElement`.
|
||||||
* @param {Array<Object>} selectedOptions - The currently selected tag objects.
|
* @param {Array<Object>} selectedOptions - The currently selected tag objects.
|
||||||
|
|
|
||||||
|
|
@ -7,3 +7,4 @@ export { default as DhFearTracker } from './fearTracker.mjs';
|
||||||
export { default as DhHotbar } from './hotbar.mjs';
|
export { default as DhHotbar } from './hotbar.mjs';
|
||||||
export { default as DhSceneNavigation } from './sceneNavigation.mjs';
|
export { default as DhSceneNavigation } from './sceneNavigation.mjs';
|
||||||
export { ItemBrowser } from './itemBrowser.mjs';
|
export { ItemBrowser } from './itemBrowser.mjs';
|
||||||
|
export { default as DhProgress } from './progress.mjs';
|
||||||
|
|
|
||||||
27
module/applications/ui/progress.mjs
Normal file
27
module/applications/ui/progress.mjs
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
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') });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -855,6 +855,11 @@ export const sceneRangeMeasurementSetting = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const activeEffectModes = {
|
export const activeEffectModes = {
|
||||||
|
armor: {
|
||||||
|
id: 'armor',
|
||||||
|
priority: 20,
|
||||||
|
label: 'TYPES.ActiveEffect.armor'
|
||||||
|
},
|
||||||
custom: {
|
custom: {
|
||||||
id: 'custom',
|
id: 'custom',
|
||||||
priority: 0,
|
priority: 0,
|
||||||
|
|
@ -887,6 +892,12 @@ export const activeEffectModes = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 = {
|
export const activeEffectDurations = {
|
||||||
temporary: {
|
temporary: {
|
||||||
id: 'temporary',
|
id: 'temporary',
|
||||||
|
|
|
||||||
|
|
@ -489,17 +489,24 @@ export const weaponFeatures = {
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.barrier.effects.barrier.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.barrier.effects.barrier.description',
|
||||||
img: 'icons/skills/melee/shield-block-bash-blue.webp',
|
img: 'icons/skills/melee/shield-block-bash-blue.webp',
|
||||||
changes: [
|
changes: [
|
||||||
{
|
|
||||||
key: 'system.armorScore',
|
|
||||||
mode: 2,
|
|
||||||
value: 'ITEM.@system.tier + 1'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'system.evasion',
|
key: 'system.evasion',
|
||||||
mode: 2,
|
mode: 2,
|
||||||
value: '-1'
|
value: '-1'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'armor',
|
||||||
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.barrier.effects.barrier.name',
|
||||||
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.barrier.effects.barrier.description',
|
||||||
|
img: 'icons/skills/melee/shield-block-bash-blue.webp',
|
||||||
|
changes: [
|
||||||
|
{
|
||||||
|
type: 'armor',
|
||||||
|
max: 'ITEM.@system.tier + 1'
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -789,11 +796,6 @@ export const weaponFeatures = {
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.effects.doubleDuty.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.effects.doubleDuty.description',
|
||||||
img: 'icons/skills/melee/sword-shield-stylized-white.webp',
|
img: 'icons/skills/melee/sword-shield-stylized-white.webp',
|
||||||
changes: [
|
changes: [
|
||||||
{
|
|
||||||
key: 'system.armorScore',
|
|
||||||
mode: 2,
|
|
||||||
value: '1'
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
key: 'system.bonuses.damage.primaryWeapon.bonus',
|
key: 'system.bonuses.damage.primaryWeapon.bonus',
|
||||||
mode: 2,
|
mode: 2,
|
||||||
|
|
@ -808,6 +810,26 @@ export const weaponFeatures = {
|
||||||
type: 'withinRange'
|
type: 'withinRange'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'armor',
|
||||||
|
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: [
|
||||||
|
{
|
||||||
|
type: 'armor',
|
||||||
|
max: 1
|
||||||
|
}
|
||||||
|
],
|
||||||
|
system: {
|
||||||
|
rangeDependence: {
|
||||||
|
enabled: true,
|
||||||
|
range: 'melee',
|
||||||
|
target: 'hostile',
|
||||||
|
type: 'withinRange'
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
@ -1186,14 +1208,14 @@ export const weaponFeatures = {
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.description',
|
||||||
effects: [
|
effects: [
|
||||||
{
|
{
|
||||||
|
type: 'armor',
|
||||||
name: 'DAGGERHEART.CONFIG.WeaponFeature.protective.effects.protective.name',
|
name: 'DAGGERHEART.CONFIG.WeaponFeature.protective.effects.protective.name',
|
||||||
description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.effects.protective.description',
|
description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.effects.protective.description',
|
||||||
img: 'icons/skills/melee/shield-block-gray-orange.webp',
|
img: 'icons/skills/melee/shield-block-gray-orange.webp',
|
||||||
changes: [
|
changes: [
|
||||||
{
|
{
|
||||||
key: 'system.armorScore',
|
type: 'armor',
|
||||||
mode: 2,
|
max: 'ITEM.@system.tier'
|
||||||
value: 'ITEM.@system.tier'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -295,17 +295,19 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
||||||
static async getEffects(actor, effectParent) {
|
static async getEffects(actor, effectParent) {
|
||||||
if (!actor) return [];
|
if (!actor) return [];
|
||||||
|
|
||||||
return Array.from(await actor.allApplicableEffects()).filter(effect => {
|
return Array.from(await actor.allApplicableEffects({ noTransferArmor: true, noSelfArmor: true })).filter(
|
||||||
/* Effects on weapons only ever apply for the weapon itself */
|
effect => {
|
||||||
if (effect.parent.type === 'weapon') {
|
/* Effects on weapons only ever apply for the weapon itself */
|
||||||
/* Unless they're secondary - then they apply only to other primary weapons */
|
if (effect.parent.type === 'weapon') {
|
||||||
if (effect.parent.system.secondary) {
|
/* Unless they're secondary - then they apply only to other primary weapons */
|
||||||
if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) return false;
|
if (effect.parent.system.secondary) {
|
||||||
} else if (effectParent?.id !== effect.parent.id) return false;
|
if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) return false;
|
||||||
}
|
} else if (effectParent?.id !== effect.parent.id) return false;
|
||||||
|
}
|
||||||
|
|
||||||
return !effect.isSuppressed;
|
return !effect.isSuppressed;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
import BaseEffect from './baseEffect.mjs';
|
import BaseEffect from './baseEffect.mjs';
|
||||||
import BeastformEffect from './beastformEffect.mjs';
|
import BeastformEffect from './beastformEffect.mjs';
|
||||||
import HordeEffect from './hordeEffect.mjs';
|
import HordeEffect from './hordeEffect.mjs';
|
||||||
|
import ArmorEffect from './armorEffect.mjs';
|
||||||
|
|
||||||
export { BaseEffect, BeastformEffect, HordeEffect };
|
export { BaseEffect, BeastformEffect, HordeEffect, ArmorEffect };
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
base: BaseEffect,
|
base: BaseEffect,
|
||||||
beastform: BeastformEffect,
|
beastform: BeastformEffect,
|
||||||
horde: HordeEffect
|
horde: HordeEffect,
|
||||||
|
armor: ArmorEffect
|
||||||
|
};
|
||||||
|
|
||||||
|
export const changeTypes = {
|
||||||
|
armor: ArmorEffect.armorChangeEffect
|
||||||
};
|
};
|
||||||
|
|
|
||||||
244
module/data/activeEffect/armorEffect.mjs
Normal file
244
module/data/activeEffect/armorEffect.mjs
Normal file
|
|
@ -0,0 +1,244 @@
|
||||||
|
import { getScrollTextData, itemAbleRollParse } from '../../helpers/utils.mjs';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArmorEffects are ActiveEffects that have a static changes field of length 1. It includes current and maximum armor.
|
||||||
|
* When applied to a character, it adds to their currently marked and maximum armor.
|
||||||
|
*/
|
||||||
|
export default class ArmorEffect extends foundry.data.ActiveEffectTypeDataModel {
|
||||||
|
static defineSchema() {
|
||||||
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...super.defineSchema(),
|
||||||
|
changes: new fields.ArrayField(
|
||||||
|
new fields.SchemaField({
|
||||||
|
key: new fields.StringField({
|
||||||
|
required: true,
|
||||||
|
nullable: false,
|
||||||
|
initial: 'system.armorScore'
|
||||||
|
}),
|
||||||
|
type: new fields.StringField({
|
||||||
|
required: true,
|
||||||
|
blank: false,
|
||||||
|
initial: CONFIG.DH.GENERAL.activeEffectModes.armor.id,
|
||||||
|
validate: ArmorEffect.#validateType
|
||||||
|
}),
|
||||||
|
phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }),
|
||||||
|
priority: new fields.NumberField({ integer: true, initial: 20 }),
|
||||||
|
value: new fields.NumberField({
|
||||||
|
required: true,
|
||||||
|
integer: true,
|
||||||
|
initial: 0,
|
||||||
|
min: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.value'
|
||||||
|
}),
|
||||||
|
max: new fields.StringField({
|
||||||
|
required: true,
|
||||||
|
nullable: false,
|
||||||
|
initial: '1',
|
||||||
|
label: 'DAGGERHEART.GENERAL.max'
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
initial: [
|
||||||
|
{
|
||||||
|
key: 'system.armorScore',
|
||||||
|
type: CONFIG.DH.GENERAL.activeEffectModes.armor.id,
|
||||||
|
phase: 'initial',
|
||||||
|
priority: 20,
|
||||||
|
value: 0,
|
||||||
|
max: '1'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
),
|
||||||
|
armorInteraction: new fields.StringField({
|
||||||
|
required: true,
|
||||||
|
choices: CONFIG.DH.GENERAL.activeEffectArmorInteraction,
|
||||||
|
initial: CONFIG.DH.GENERAL.activeEffectArmorInteraction.none.id,
|
||||||
|
label: 'DAGGERHEART.EFFECTS.Armor.FIELDS.armorInteraction.label',
|
||||||
|
hint: 'DAGGERHEART.EFFECTS.Armor.FIELDS.armorInteraction.hint'
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get isSuppressed() {
|
||||||
|
if (this.parent.actor?.type !== 'character') return false;
|
||||||
|
|
||||||
|
switch (this.armorInteraction) {
|
||||||
|
case CONFIG.DH.GENERAL.activeEffectArmorInteraction.active.id:
|
||||||
|
return !this.parent.actor.system.armor;
|
||||||
|
case CONFIG.DH.GENERAL.activeEffectArmorInteraction.inactive.id:
|
||||||
|
return Boolean(this.parent.actor.system.armor);
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Type Functions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that an {@link EffectChangeData#type} string is well-formed.
|
||||||
|
* @param {string} type The string to be validated
|
||||||
|
* @returns {true}
|
||||||
|
* @throws {Error} An error if the type string is malformed
|
||||||
|
*/
|
||||||
|
static #validateType(type) {
|
||||||
|
if (type !== CONFIG.DH.GENERAL.activeEffectModes.armor.id)
|
||||||
|
throw new Error('An armor effect must have change.type "armor"');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static armorChangeEffect = {
|
||||||
|
label: 'Armor',
|
||||||
|
defaultPriortiy: 20,
|
||||||
|
handler: (actor, change, _options, _field, replacementData) => {
|
||||||
|
game.system.api.documents.DhActiveEffect.applyChange(
|
||||||
|
actor,
|
||||||
|
{
|
||||||
|
...change,
|
||||||
|
key: 'system.armorScore.value',
|
||||||
|
type: CONFIG.DH.GENERAL.activeEffectModes.add.id,
|
||||||
|
value: change.value
|
||||||
|
},
|
||||||
|
replacementData
|
||||||
|
);
|
||||||
|
game.system.api.documents.DhActiveEffect.applyChange(
|
||||||
|
actor,
|
||||||
|
{
|
||||||
|
...change,
|
||||||
|
key: 'system.armorScore.max',
|
||||||
|
type: CONFIG.DH.GENERAL.activeEffectModes.add.id,
|
||||||
|
value: change.max
|
||||||
|
},
|
||||||
|
replacementData
|
||||||
|
);
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
render: null
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Helpers */
|
||||||
|
|
||||||
|
get armorChange() {
|
||||||
|
if (this.changes.length !== 1)
|
||||||
|
throw new Error('Unexpected error. An armor effect should have a changes field of length 1.');
|
||||||
|
|
||||||
|
const actor = this.parent.actor?.type === 'character' ? this.parent.actor : null;
|
||||||
|
const changeData = this.changes[0];
|
||||||
|
const maxParse = actor ? itemAbleRollParse(changeData.max, actor, this.parent.parent) : null;
|
||||||
|
const maxRoll = maxParse ? new Roll(maxParse).evaluateSync() : null;
|
||||||
|
const maxEvaluated = maxRoll ? (maxRoll.isDeterministic ? maxRoll.total : null) : null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...changeData,
|
||||||
|
max: maxEvaluated ?? changeData.max
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get armorData() {
|
||||||
|
return { value: this.armorChange.value, max: this.armorChange.max };
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateArmorMax(newMax) {
|
||||||
|
const { effect, ...baseChange } = this.armorChange;
|
||||||
|
const newChanges = [
|
||||||
|
{
|
||||||
|
...baseChange,
|
||||||
|
max: newMax,
|
||||||
|
value: Math.min(this.armorChange.value, newMax)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
await this.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)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Overrides */
|
||||||
|
|
||||||
|
static getDefaultObject() {
|
||||||
|
return {
|
||||||
|
key: 'system.armorScore',
|
||||||
|
type: 'armor',
|
||||||
|
name: game.i18n.localize('DAGGERHEART.EFFECTS.Armor.newArmorEffect'),
|
||||||
|
img: 'icons/equipment/chest/breastplate-helmet-metal.webp'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async _preUpdate(changes, options, user) {
|
||||||
|
const allowed = await super._preUpdate(changes, options, user);
|
||||||
|
if (allowed === false) return false;
|
||||||
|
|
||||||
|
if (changes.system?.changes) {
|
||||||
|
const changesChanged = changes.system.changes.length !== this.changes.length;
|
||||||
|
if (changesChanged) {
|
||||||
|
ui.notifications.error(
|
||||||
|
game.i18n.localize('DAGGERHEART.UI.Notifications.cannotAlterArmorEffectChanges')
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.system.changes.length === 1) {
|
||||||
|
if (changes.system.changes[0].type !== CONFIG.DH.GENERAL.activeEffectModes.armor.id) {
|
||||||
|
ui.notifications.error(
|
||||||
|
game.i18n.localize('DAGGERHEART.UI.Notifications.cannotAlterArmorEffectType')
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changes.system.changes[0].key !== 'system.armorScore') {
|
||||||
|
ui.notifications.error(
|
||||||
|
game.i18n.localize('DAGGERHEART.UI.Notifications.cannotAlterArmorEffectKey')
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
changes.system.changes[0].value !== this.armorChange.value &&
|
||||||
|
this.parent.actor?.type === 'character'
|
||||||
|
) {
|
||||||
|
const increased = changes.system.changes[0].value > this.armorChange.value;
|
||||||
|
const value = -1 * (this.armorChange.value - changes.system.changes[0].value);
|
||||||
|
options.scrollingTextData = [getScrollTextData(increased, value, 'armor')];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_onUpdate(changes, options, userId) {
|
||||||
|
super._onUpdate(changes, options, userId);
|
||||||
|
|
||||||
|
if (options.scrollingTextData && this.parent.actor?.type === 'character')
|
||||||
|
this.parent.actor.queueScrollText(options.scrollingTextData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs';
|
import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs';
|
||||||
import DHItem from '../../documents/item.mjs';
|
import DHItem from '../../documents/item.mjs';
|
||||||
import { getScrollTextData } from '../../helpers/utils.mjs';
|
import { getResourceScrollTextData } from '../../helpers/utils.mjs';
|
||||||
|
|
||||||
const fields = foundry.data.fields;
|
const fields = foundry.data.fields;
|
||||||
|
|
||||||
|
|
@ -211,7 +211,7 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel {
|
||||||
const textData = Object.keys(changes.system.resources).reduce((acc, key) => {
|
const textData = Object.keys(changes.system.resources).reduce((acc, key) => {
|
||||||
const resource = changes.system.resources[key];
|
const resource = changes.system.resources[key];
|
||||||
if (resource.value !== undefined && resource.value !== this.resources[key].value) {
|
if (resource.value !== undefined && resource.value !== this.resources[key].value) {
|
||||||
acc.push(getScrollTextData(this.resources, resource, key));
|
acc.push(getResourceScrollTextData(this.resources, resource, key));
|
||||||
}
|
}
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,20 @@ export default class DhCharacter extends DhCreature {
|
||||||
label: 'DAGGERHEART.GENERAL.proficiency'
|
label: 'DAGGERHEART.GENERAL.proficiency'
|
||||||
}),
|
}),
|
||||||
evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }),
|
evasion: new fields.NumberField({ initial: 0, integer: true, label: 'DAGGERHEART.GENERAL.evasion' }),
|
||||||
armorScore: new fields.NumberField({ integer: true, initial: 0, label: 'DAGGERHEART.GENERAL.armorScore' }),
|
armorScore: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({
|
||||||
|
integer: true,
|
||||||
|
initial: 0,
|
||||||
|
min: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.armorScore'
|
||||||
|
}),
|
||||||
|
max: new fields.NumberField({
|
||||||
|
integer: true,
|
||||||
|
initial: 0,
|
||||||
|
min: 0,
|
||||||
|
label: 'DAGGERHEART.GENERAL.armorScore'
|
||||||
|
})
|
||||||
|
}),
|
||||||
damageThresholds: new fields.SchemaField({
|
damageThresholds: new fields.SchemaField({
|
||||||
severe: new fields.NumberField({
|
severe: new fields.NumberField({
|
||||||
integer: true,
|
integer: true,
|
||||||
|
|
@ -487,6 +500,70 @@ 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 armorEffects = Array.from(this.parent.allApplicableEffects()).filter(x => x.type === 'armor');
|
||||||
|
const orderedEffects = game.system.api.data.activeEffects.ArmorEffect.orderEffectsForAutoChange(
|
||||||
|
armorEffects,
|
||||||
|
increasing
|
||||||
|
);
|
||||||
|
|
||||||
|
const embeddedUpdates = [];
|
||||||
|
for (const armorEffect of orderedEffects) {
|
||||||
|
let usedArmorChange = 0;
|
||||||
|
if (clear) {
|
||||||
|
usedArmorChange -= armorEffect.system.armorChange.value;
|
||||||
|
} else {
|
||||||
|
if (increasing) {
|
||||||
|
const remainingArmor = armorEffect.system.armorChange.max - armorEffect.system.armorChange.value;
|
||||||
|
usedArmorChange = Math.min(remainingChange, remainingArmor);
|
||||||
|
remainingChange -= usedArmorChange;
|
||||||
|
} else {
|
||||||
|
const changeChange = Math.min(armorEffect.system.armorChange.value, remainingChange);
|
||||||
|
usedArmorChange -= changeChange;
|
||||||
|
remainingChange -= changeChange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!usedArmorChange) continue;
|
||||||
|
else {
|
||||||
|
if (!embeddedUpdates[armorEffect.parent.id])
|
||||||
|
embeddedUpdates[armorEffect.parent.id] = { doc: armorEffect.parent, updates: [] };
|
||||||
|
|
||||||
|
embeddedUpdates[armorEffect.parent.id].updates.push({
|
||||||
|
'_id': armorEffect.id,
|
||||||
|
'system.changes': [
|
||||||
|
{
|
||||||
|
...armorEffect.system.armorChange,
|
||||||
|
value: armorEffect.system.armorChange.value + usedArmorChange
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remainingChange === 0 && !clear) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateValues = Object.values(embeddedUpdates);
|
||||||
|
for (const [index, { doc, updates }] of updateValues.entries())
|
||||||
|
doc.updateEmbeddedDocuments('ActiveEffect', updates, { render: index === updateValues.length - 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateArmorEffectValue({ uuid, value }) {
|
||||||
|
const effect = await foundry.utils.fromUuid(uuid);
|
||||||
|
await effect.update({
|
||||||
|
'system.changes': [
|
||||||
|
{
|
||||||
|
...effect.system.armorChange,
|
||||||
|
value: effect.system.armorChange.value + value
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
get sheetLists() {
|
get sheetLists() {
|
||||||
const ancestryFeatures = [],
|
const ancestryFeatures = [],
|
||||||
communityFeatures = [],
|
communityFeatures = [],
|
||||||
|
|
@ -658,14 +735,12 @@ export default class DhCharacter extends DhCreature {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const armor = this.armor;
|
|
||||||
this.armorScore = armor ? armor.system.baseScore : 0;
|
|
||||||
this.damageThresholds = {
|
this.damageThresholds = {
|
||||||
major: armor
|
major: this.armor
|
||||||
? armor.system.baseThresholds.major + this.levelData.level.current
|
? this.armor.system.baseThresholds.major + this.levelData.level.current
|
||||||
: this.levelData.level.current,
|
: this.levelData.level.current,
|
||||||
severe: armor
|
severe: this.armor
|
||||||
? armor.system.baseThresholds.severe + this.levelData.level.current
|
? this.armor.system.baseThresholds.severe + this.levelData.level.current
|
||||||
: this.levelData.level.current * 2
|
: this.levelData.level.current * 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -699,8 +774,7 @@ export default class DhCharacter extends DhCreature {
|
||||||
this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait;
|
this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait;
|
||||||
|
|
||||||
this.resources.armor = {
|
this.resources.armor = {
|
||||||
value: this.armor?.system?.marks?.value ?? 0,
|
...this.armorScore,
|
||||||
max: this.armorScore,
|
|
||||||
isReversed: true
|
isReversed: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ export default class DHArmor extends AttachableItem {
|
||||||
...super.defineSchema(),
|
...super.defineSchema(),
|
||||||
tier: new fields.NumberField({ required: true, integer: true, initial: 1, min: 1 }),
|
tier: new fields.NumberField({ required: true, integer: true, initial: 1, min: 1 }),
|
||||||
equipped: new fields.BooleanField({ initial: false }),
|
equipped: new fields.BooleanField({ initial: false }),
|
||||||
baseScore: new fields.NumberField({ integer: true, initial: 0 }),
|
|
||||||
armorFeatures: new fields.ArrayField(
|
armorFeatures: new fields.ArrayField(
|
||||||
new fields.SchemaField({
|
new fields.SchemaField({
|
||||||
value: new fields.StringField({
|
value: new fields.StringField({
|
||||||
|
|
@ -52,6 +51,17 @@ export default class DHArmor extends AttachableItem {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get armorEffect() {
|
||||||
|
return this.parent.effects.find(x => x.type === 'armor');
|
||||||
|
}
|
||||||
|
|
||||||
|
get armorData() {
|
||||||
|
const armorEffect = this.armorEffect;
|
||||||
|
if (!armorEffect) return { value: 0, max: 0 };
|
||||||
|
|
||||||
|
return armorEffect.system.armorData;
|
||||||
|
}
|
||||||
|
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
async getDescriptionData() {
|
async getDescriptionData() {
|
||||||
const baseDescription = this.description;
|
const baseDescription = this.description;
|
||||||
|
|
@ -66,6 +76,17 @@ export default class DHArmor extends AttachableItem {
|
||||||
return { prefix, value: baseDescription, suffix: null };
|
return { prefix, value: baseDescription, suffix: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**@inheritdoc */
|
||||||
|
async _onCreate(_data, _options, userId) {
|
||||||
|
if (userId !== game.user.id) return;
|
||||||
|
|
||||||
|
if (!this.parent.effects.some(x => x.type === 'armor')) {
|
||||||
|
this.parent.createEmbeddedDocuments('ActiveEffect', [
|
||||||
|
game.system.api.data.activeEffects.ArmorEffect.getDefaultObject()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**@inheritdoc */
|
/**@inheritdoc */
|
||||||
async _preUpdate(changes, options, user) {
|
async _preUpdate(changes, options, user) {
|
||||||
const allowed = await super._preUpdate(changes, options, user);
|
const allowed = await super._preUpdate(changes, options, user);
|
||||||
|
|
@ -151,13 +172,22 @@ export default class DHArmor extends AttachableItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
static migrateDocumentData(source) {
|
||||||
|
if (source.system.baseScore !== undefined && !source.effects.some(x => x.type === 'armor')) {
|
||||||
|
if (!source.flags) source.flags = {};
|
||||||
|
if (!source.flags.daggerheart) source.flags.daggerheart = {};
|
||||||
|
source.flags.daggerheart.baseScoreMigrationValue = source.system.baseScore;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a list of localized tags based on this item's type-specific properties.
|
* Generates a list of localized tags based on this item's type-specific properties.
|
||||||
* @returns {string[]} An array of localized tag strings.
|
* @returns {string[]} An array of localized tag strings.
|
||||||
*/
|
*/
|
||||||
_getTags() {
|
_getTags() {
|
||||||
const tags = [
|
const tags = [
|
||||||
`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`,
|
`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.armorData.max}`,
|
||||||
`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseThresholds.base')}: ${this.baseThresholds.major} / ${this.baseThresholds.severe}`
|
`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseThresholds.base')}: ${this.baseThresholds.major} / ${this.baseThresholds.severe}`
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
@ -169,9 +199,7 @@ export default class DHArmor extends AttachableItem {
|
||||||
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
|
* @returns {(string | { value: string, icons: string[] })[]} An array of localized strings and damage label objects.
|
||||||
*/
|
*/
|
||||||
_getLabels() {
|
_getLabels() {
|
||||||
const labels = [];
|
const labels = [`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.armorData.max}`];
|
||||||
if (this.baseScore)
|
|
||||||
labels.push(`${game.i18n.localize('DAGGERHEART.ITEMS.Armor.baseScore')}: ${this.baseScore}`);
|
|
||||||
return labels;
|
return labels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
* @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item
|
* @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { addLinkedItemsDiff, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs';
|
import { addLinkedItemsDiff, getResourceScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs';
|
||||||
import { ActionsField } from '../fields/actionField.mjs';
|
import { ActionsField } from '../fields/actionField.mjs';
|
||||||
import FormulaField from '../fields/formulaField.mjs';
|
import FormulaField from '../fields/formulaField.mjs';
|
||||||
|
|
||||||
|
|
@ -224,7 +224,11 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel {
|
||||||
const armorChanged =
|
const armorChanged =
|
||||||
changed.system?.marks?.value !== undefined && changed.system.marks.value !== this.marks.value;
|
changed.system?.marks?.value !== undefined && changed.system.marks.value !== this.marks.value;
|
||||||
if (armorChanged && autoSettings.resourceScrollTexts && this.parent.parent?.type === 'character') {
|
if (armorChanged && autoSettings.resourceScrollTexts && this.parent.parent?.type === 'character') {
|
||||||
const armorData = getScrollTextData(this.parent.parent.system.resources, changed.system.marks, 'armor');
|
const armorData = getResourceScrollTextData(
|
||||||
|
this.parent.parent.system.resources,
|
||||||
|
changed.system.marks,
|
||||||
|
'armor'
|
||||||
|
);
|
||||||
options.scrollingTextData = [armorData];
|
options.scrollingTextData = [armorData];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
|
|
||||||
/**@override */
|
/**@override */
|
||||||
get isSuppressed() {
|
get isSuppressed() {
|
||||||
|
if (this.system.isSuppressed === true) return true;
|
||||||
|
|
||||||
// If this is a copied effect from an attachment, never suppress it
|
// If this is a copied effect from an attachment, never suppress it
|
||||||
// (These effects have attachmentSource metadata)
|
// (These effects have attachmentSource metadata)
|
||||||
if (this.flags?.daggerheart?.attachmentSource) {
|
if (this.flags?.daggerheart?.attachmentSource) {
|
||||||
|
|
@ -15,7 +17,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then apply the standard suppression rules
|
// Then apply the standard suppression rules
|
||||||
if (['weapon', 'armor'].includes(this.parent?.type)) {
|
if (['weapon', 'armor'].includes(this.parent?.type) && this.transfer) {
|
||||||
return !this.parent.system.equipped;
|
return !this.parent.system.equipped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,7 +78,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
throw new Error('The array of sub-types to restrict to must not be empty.');
|
throw new Error('The array of sub-types to restrict to must not be empty.');
|
||||||
}
|
}
|
||||||
|
|
||||||
const creatableEffects = ['base'];
|
const creatableEffects = types || ['base', 'armor'];
|
||||||
const documentTypes = this.TYPES.filter(type => creatableEffects.includes(type)).map(type => {
|
const documentTypes = this.TYPES.filter(type => creatableEffects.includes(type)).map(type => {
|
||||||
const labelKey = `TYPES.ActiveEffect.${type}`;
|
const labelKey = `TYPES.ActiveEffect.${type}`;
|
||||||
const label = game.i18n.has(labelKey) ? game.i18n.localize(labelKey) : type;
|
const label = game.i18n.has(labelKey) ? game.i18n.localize(labelKey) : type;
|
||||||
|
|
@ -153,6 +155,11 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
/* Methods */
|
/* Methods */
|
||||||
/* -------------------------------------------- */
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/**@inheritdoc */
|
||||||
|
static applyChange(actor, change, options) {
|
||||||
|
super.applyChange(actor, change, options);
|
||||||
|
}
|
||||||
|
|
||||||
/**@inheritdoc*/
|
/**@inheritdoc*/
|
||||||
static applyChangeField(model, change, field) {
|
static applyChangeField(model, change, field) {
|
||||||
change.value = Number.isNumeric(change.value)
|
change.value = Number.isNumeric(change.value)
|
||||||
|
|
@ -161,9 +168,9 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
|
||||||
super.applyChangeField(model, change, field);
|
super.applyChangeField(model, change, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
_applyLegacy(actor, change, changes) {
|
_applyChangeUnguided(actor, change, changes, options) {
|
||||||
change.value = DhActiveEffect.getChangeValue(actor, change, change.effect);
|
change.value = DhActiveEffect.getChangeValue(actor, change, change.effect);
|
||||||
super._applyLegacy(actor, change, changes);
|
super._applyChangeUnguided(actor, change, changes, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
static getChangeValue(model, change, effect) {
|
static getChangeValue(model, change, effect) {
|
||||||
|
|
|
||||||
|
|
@ -573,8 +573,7 @@ export default class DhpActor extends Actor {
|
||||||
const availableStress = this.system.resources.stress.max - this.system.resources.stress.value;
|
const availableStress = this.system.resources.stress.max - this.system.resources.stress.value;
|
||||||
|
|
||||||
const canUseArmor =
|
const canUseArmor =
|
||||||
this.system.armor &&
|
this.system.armorScore.value < this.system.armorScore.max &&
|
||||||
this.system.armor.system.marks.value < this.system.armorScore &&
|
|
||||||
type.every(t => this.system.armorApplicableDamageTypes[t] === true);
|
type.every(t => this.system.armorApplicableDamageTypes[t] === true);
|
||||||
const canUseStress = Object.keys(stressDamageReduction).reduce((acc, x) => {
|
const canUseStress = Object.keys(stressDamageReduction).reduce((acc, x) => {
|
||||||
const rule = stressDamageReduction[x];
|
const rule = stressDamageReduction[x];
|
||||||
|
|
@ -614,12 +613,7 @@ export default class DhpActor extends Actor {
|
||||||
const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id);
|
const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id);
|
||||||
if (hpDamage?.value) {
|
if (hpDamage?.value) {
|
||||||
hpDamage.value = this.convertDamageToThreshold(hpDamage.value);
|
hpDamage.value = this.convertDamageToThreshold(hpDamage.value);
|
||||||
if (
|
if (this.type === 'character' && !isDirect && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) {
|
||||||
this.type === 'character' &&
|
|
||||||
!isDirect &&
|
|
||||||
this.system.armor &&
|
|
||||||
this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)
|
|
||||||
) {
|
|
||||||
const armorSlotResult = await this.owner.query(
|
const armorSlotResult = await this.owner.query(
|
||||||
'armorSlot',
|
'armorSlot',
|
||||||
{
|
{
|
||||||
|
|
@ -632,12 +626,10 @@ export default class DhpActor extends Actor {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
if (armorSlotResult) {
|
if (armorSlotResult) {
|
||||||
const { modifiedDamage, armorSpent, stressSpent } = armorSlotResult;
|
const { modifiedDamage, armorChanges, stressSpent } = armorSlotResult;
|
||||||
updates.find(u => u.key === 'hitPoints').value = modifiedDamage;
|
updates.find(u => u.key === 'hitPoints').value = modifiedDamage;
|
||||||
if (armorSpent) {
|
for (const armorChange of armorChanges) {
|
||||||
const armorUpdate = updates.find(u => u.key === 'armor');
|
updates.push({ value: armorChange.amount, key: 'armor', uuid: armorChange.uuid });
|
||||||
if (armorUpdate) armorUpdate.value += armorSpent;
|
|
||||||
else updates.push({ value: armorSpent, key: 'armor' });
|
|
||||||
}
|
}
|
||||||
if (stressSpent) {
|
if (stressSpent) {
|
||||||
const stressUpdate = updates.find(u => u.key === 'stress');
|
const stressUpdate = updates.find(u => u.key === 'stress');
|
||||||
|
|
@ -784,12 +776,8 @@ export default class DhpActor extends Actor {
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case 'armor':
|
case 'armor':
|
||||||
if (this.system.armor?.system?.marks) {
|
if (!r.uuid) this.system.updateArmorValue(r);
|
||||||
updates.armor.resources['system.marks.value'] = Math.max(
|
else this.system.updateArmorEffectValue(r);
|
||||||
Math.min(valueFunc(this.system.armor.system.marks, r), this.system.armorScore),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (this.system.resources?.[r.key]) {
|
if (this.system.resources?.[r.key]) {
|
||||||
|
|
@ -1005,4 +993,20 @@ export default class DhpActor extends Actor {
|
||||||
|
|
||||||
return allTokens;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -230,4 +230,14 @@ export default class DHItem extends foundry.documents.Item {
|
||||||
async _preDelete() {
|
async _preDelete() {
|
||||||
this.deleteTriggers();
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -378,14 +378,18 @@ export const arraysEqual = (a, b) =>
|
||||||
|
|
||||||
export const setsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value));
|
export const setsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value));
|
||||||
|
|
||||||
export function getScrollTextData(resources, resource, key) {
|
export function getResourceScrollTextData(resources, resource, key) {
|
||||||
const { reversed, label } = CONFIG.DH.ACTOR.scrollingTextResource[key];
|
|
||||||
const { BOTTOM, TOP } = CONST.TEXT_ANCHOR_POINTS;
|
|
||||||
const increased = resources[key].value < resource.value;
|
const increased = resources[key].value < resource.value;
|
||||||
const value = -1 * (resources[key].value - resource.value);
|
const value = -1 * (resources[key].value - resource.value);
|
||||||
|
|
||||||
const text = `${game.i18n.localize(label)} ${value.signedString()}`;
|
return getScrollTextData(increased, value, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getScrollTextData(increased, value, key) {
|
||||||
|
const { reversed, label } = CONFIG.DH.ACTOR.scrollingTextResource[key];
|
||||||
|
const { BOTTOM, TOP } = CONST.TEXT_ANCHOR_POINTS;
|
||||||
|
|
||||||
|
const text = `${game.i18n.localize(label)} ${value.signedString()}`;
|
||||||
const stroke = increased ? (reversed ? 0xffffff : 0x000000) : reversed ? 0x000000 : 0xffffff;
|
const stroke = increased ? (reversed ? 0xffffff : 0x000000) : reversed ? 0x000000 : 0xffffff;
|
||||||
const fill = increased ? (reversed ? 0x0032b1 : 0xffe760) : reversed ? 0xffe760 : 0x0032b1;
|
const fill = increased ? (reversed ? 0x0032b1 : 0xffe760) : reversed ? 0xffe760 : 0x0032b1;
|
||||||
const direction = increased ? (reversed ? BOTTOM : TOP) : reversed ? TOP : BOTTOM;
|
const direction = increased ? (reversed ? BOTTOM : TOP) : reversed ? TOP : BOTTOM;
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,171 @@ export async function runMigrations() {
|
||||||
|
|
||||||
lastMigrationVersion = '1.6.0';
|
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 => {
|
||||||
|
const effectChangeData = [];
|
||||||
|
for (const effect of entity.effects) {
|
||||||
|
const oldArmorChanges = effect.system.changes.filter(x => x.key === 'system.armorScore');
|
||||||
|
if (!oldArmorChanges.length) continue;
|
||||||
|
|
||||||
|
const changeData = {};
|
||||||
|
const newChanges = effect.system.changes.filter(x => x.key !== 'system.armorScore');
|
||||||
|
if (newChanges.length) {
|
||||||
|
await effect.update({ 'system.changes': newChanges });
|
||||||
|
} else {
|
||||||
|
changeData.deleteId = effect.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldEffectData = effect.toObject();
|
||||||
|
changeData.createData = {
|
||||||
|
...oldEffectData,
|
||||||
|
type: 'armor',
|
||||||
|
system: {
|
||||||
|
...oldEffectData.sytem,
|
||||||
|
changes: oldArmorChanges.map(change => ({
|
||||||
|
key: 'system.armorScore',
|
||||||
|
type: CONFIG.DH.GENERAL.activeEffectModes.armor.id,
|
||||||
|
phase: 'initial',
|
||||||
|
priority: 20,
|
||||||
|
value: 0,
|
||||||
|
max: change.value
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
effectChangeData.push(changeData);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const changeData of effectChangeData) {
|
||||||
|
const relatedActions = Array.from(entity.system.actions ?? []).filter(x =>
|
||||||
|
x.effects.some(effect => effect._id === changeData.deleteId)
|
||||||
|
);
|
||||||
|
const [newEffect] = await entity.createEmbeddedDocuments('ActiveEffect', [
|
||||||
|
{
|
||||||
|
...changeData.createData,
|
||||||
|
transfer: relatedActions.length ? false : true
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
for (const action of relatedActions) {
|
||||||
|
await action.update({
|
||||||
|
effects: action.effects.map(effect => ({
|
||||||
|
...effect,
|
||||||
|
_id: effect._id === changeData.deleteId ? newEffect.id : effect._id
|
||||||
|
}))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await entity.deleteEmbeddedDocuments(
|
||||||
|
'ActiveEffect',
|
||||||
|
effectChangeData.reduce((acc, data) => {
|
||||||
|
if (data.deleteId) acc.push(data.deleteId);
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Migrate existing armors to the new Armor Effects */
|
||||||
|
const migrateItems = async items => {
|
||||||
|
for (const item of items) {
|
||||||
|
await migrateEffects(item);
|
||||||
|
|
||||||
|
if (item instanceof game.system.api.documents.DHItem && item.type === 'armor') {
|
||||||
|
const hasArmorEffect = item.effects.some(x => x.type === 'armor');
|
||||||
|
const migrationArmorScore = item.flags.daggerheart?.baseScoreMigrationValue;
|
||||||
|
if (migrationArmorScore !== undefined && !hasArmorEffect) {
|
||||||
|
await item.createEmbeddedDocuments('ActiveEffect', [
|
||||||
|
{
|
||||||
|
...game.system.api.data.activeEffects.ArmorEffect.getDefaultObject(),
|
||||||
|
changes: [
|
||||||
|
{
|
||||||
|
key: 'system.armorScore',
|
||||||
|
type: CONFIG.DH.GENERAL.activeEffectModes.armor.id,
|
||||||
|
phase: 'initial',
|
||||||
|
priority: 20,
|
||||||
|
value: 0,
|
||||||
|
max: migrationArmorScore.toString()
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
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
|
//#endregion
|
||||||
|
|
||||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion);
|
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion);
|
||||||
|
|
|
||||||
|
|
@ -90,36 +90,30 @@
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"name": "Armorer",
|
"name": "Armorer",
|
||||||
"type": "base",
|
"type": "armor",
|
||||||
"system": {
|
"system": {
|
||||||
"rangeDependence": {
|
"changes": [
|
||||||
"enabled": false,
|
{
|
||||||
"type": "withinRange",
|
"key": "system.armorScore",
|
||||||
"target": "hostile",
|
"type": "armor",
|
||||||
"range": "melee"
|
"phase": "initial",
|
||||||
}
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "1"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"armorInteraction": "active"
|
||||||
},
|
},
|
||||||
"_id": "cED730OjuMW5haJR",
|
"_id": "tJw2JIPcT9hEMRXg",
|
||||||
"img": "icons/tools/hand/hammer-and-nail.webp",
|
"img": "icons/tools/hand/hammer-and-nail.webp",
|
||||||
"changes": [
|
|
||||||
{
|
|
||||||
"key": "system.armorScore",
|
|
||||||
"mode": 2,
|
|
||||||
"value": "1",
|
|
||||||
"priority": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"description": "<p><span style=\"color:rgb(239, 230, 216);font-family:Montserrat, sans-serif;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;orphans:2;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;white-space:normal;background-color:rgba(24, 22, 46, 0.376);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;display:inline !important;float:none\">While you’re wearing armor, gain a +1 bonus to your </span><span class=\"tooltip-convert\" style=\"box-sizing:border-box;scrollbar-width:thin;scrollbar-color:rgb(93, 20, 43) rgba(0, 0, 0, 0);color:rgb(239, 230, 216);font-family:Montserrat, sans-serif;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;orphans:2;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;white-space:normal;background-color:rgba(24, 22, 46, 0.376);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial\">Armor Score</span><span style=\"color:rgb(239, 230, 216);font-family:Montserrat, sans-serif;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;orphans:2;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;white-space:normal;background-color:rgba(24, 22, 46, 0.376);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;display:inline !important;float:none\">.</p>",
|
"description": "<p><span style=\"color:rgb(239, 230, 216);font-family:Montserrat, sans-serif;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;orphans:2;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;white-space:normal;background-color:rgba(24, 22, 46, 0.376);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;display:inline !important;float:none\">While you’re wearing armor, gain a +1 bonus to your </span><span style=\"box-sizing:border-box;scrollbar-width:thin;scrollbar-color:rgb(93, 20, 43) rgba(0, 0, 0, 0);color:rgb(239, 230, 216);font-family:Montserrat, sans-serif;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;orphans:2;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;white-space:normal;background-color:rgba(24, 22, 46, 0.376);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial\" class=\"tooltip-convert\">Armor Score</span><span style=\"color:rgb(239, 230, 216);font-family:Montserrat, sans-serif;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;orphans:2;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;white-space:normal;background-color:rgba(24, 22, 46, 0.376);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;display:inline !important;float:none\">.</span></p>",
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
"transfer": true,
|
"transfer": true,
|
||||||
|
|
@ -129,7 +123,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!cy8GjBPGc9w9RaGO.cED730OjuMW5haJR"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!cy8GjBPGc9w9RaGO.tJw2JIPcT9hEMRXg"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ownership": {
|
"ownership": {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,99 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flags": {},
|
"flags": {},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"name": "Bare Bones Armor",
|
||||||
|
"type": "armor",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"value": 0,
|
||||||
|
"max": "3 + @system.traits.strength.value",
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"armorInteraction": "inactive"
|
||||||
|
},
|
||||||
|
"_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": "<p><span style=\"color:rgb(239, 230, 216);font-family:Montserrat, sans-serif;font-size:14px;font-style:normal;font-variant-ligatures:normal;font-variant-caps:normal;font-weight:400;letter-spacing:normal;orphans:2;text-align:start;text-indent:0px;text-transform:none;widows:2;word-spacing:0px;-webkit-text-stroke-width:0px;white-space:normal;background-color:rgba(24, 22, 46, 0.565);text-decoration-thickness:initial;text-decoration-style:initial;text-decoration-color:initial;display:inline !important;float:none\">You have a base Armor Score of 3 + your Strength.</span></p>",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!l5D9kq901JDESaXw.FCsgz7Tdsw6QUzBs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Bare Bones",
|
||||||
|
"type": "base",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.damageThresholds.major",
|
||||||
|
"type": "add",
|
||||||
|
"value": "9 + (@tier - 1) * 5 + max(0, (@tier -2) * 2 )",
|
||||||
|
"priority": null,
|
||||||
|
"phase": "initial"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "system.damageThresholds.severe",
|
||||||
|
"type": "add",
|
||||||
|
"value": "19 + (@tier - 1) * 5 + max(0, (@tier -2) * 2 )",
|
||||||
|
"priority": null,
|
||||||
|
"phase": "initial"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rangeDependence": {
|
||||||
|
"enabled": false,
|
||||||
|
"type": "withinRange",
|
||||||
|
"target": "hostile",
|
||||||
|
"range": "melee"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"_id": "8flPpWNoBeuFPFTK",
|
||||||
|
"img": "icons/magic/control/buff-strength-muscle-damage-orange.webp",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "<p>You use the following as your base damage thresholds:</p><ul><li class=\"vertical-card-list-found\"><p><em><strong>Tier 1:</strong></em> 9/19</p></li><li class=\"vertical-card-list-found\"><p><em><strong>Tier 2:</strong></em> 11/24</p></li><li class=\"vertical-card-list-found\"><p><em><strong>Tier 3:</strong></em> 13/31</p></li><li class=\"vertical-card-list-found\"><p><em><strong>Tier 4:</strong></em> 15/38</p></li></ul>",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!l5D9kq901JDESaXw.8flPpWNoBeuFPFTK"
|
||||||
|
}
|
||||||
|
],
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
"MQSznptE5yLT7kj8": 3
|
"MQSznptE5yLT7kj8": 3
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,7 @@
|
||||||
},
|
},
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"_id": "LdcT1nrkd5ORCU4n",
|
"_id": "ptYT10JZ2WJHvFMd",
|
||||||
"onSave": false
|
"onSave": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -252,8 +252,8 @@
|
||||||
"img": "icons/magic/defensive/shield-barrier-glowing-triangle-blue.webp",
|
"img": "icons/magic/defensive/shield-barrier-glowing-triangle-blue.webp",
|
||||||
"origin": "Compendium.daggerheart.domains.Item.YtZzYBtR0yLPPA93",
|
"origin": "Compendium.daggerheart.domains.Item.YtZzYBtR0yLPPA93",
|
||||||
"transfer": false,
|
"transfer": false,
|
||||||
"_id": "LdcT1nrkd5ORCU4n",
|
"_id": "ptYT10JZ2WJHvFMd",
|
||||||
"type": "base",
|
"type": "armor",
|
||||||
"system": {
|
"system": {
|
||||||
"rangeDependence": {
|
"rangeDependence": {
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
|
@ -264,9 +264,11 @@
|
||||||
"changes": [
|
"changes": [
|
||||||
{
|
{
|
||||||
"key": "system.armorScore",
|
"key": "system.armorScore",
|
||||||
"value": 1,
|
"type": "armor",
|
||||||
"priority": null,
|
"phase": "initial",
|
||||||
"type": "add"
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "1"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"duration": {
|
"duration": {
|
||||||
|
|
@ -298,7 +300,7 @@
|
||||||
},
|
},
|
||||||
"showIcon": 1,
|
"showIcon": 1,
|
||||||
"folder": null,
|
"folder": null,
|
||||||
"_key": "!items.effects!YtZzYBtR0yLPPA93.LdcT1nrkd5ORCU4n"
|
"_key": "!items.effects!YtZzYBtR0yLPPA93.ptYT10JZ2WJHvFMd"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ownership": {
|
"ownership": {
|
||||||
|
|
|
||||||
|
|
@ -91,34 +91,27 @@
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"name": "Valor-Touched",
|
"name": "Valor-Touched",
|
||||||
"type": "base",
|
"type": "armor",
|
||||||
"system": {
|
"system": {
|
||||||
"rangeDependence": {
|
"changes": [
|
||||||
"enabled": false,
|
{
|
||||||
"type": "withinRange",
|
"key": "system.armorScore",
|
||||||
"target": "hostile",
|
"type": "armor",
|
||||||
"range": "melee"
|
"phase": "initial",
|
||||||
}
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"_id": "H9lgIqqp1imSNOv9",
|
"_id": "Ma8Zp005QYKPWIEN",
|
||||||
"img": "icons/magic/control/control-influence-rally-purple.webp",
|
"img": "icons/magic/control/control-influence-rally-purple.webp",
|
||||||
"changes": [
|
|
||||||
{
|
|
||||||
"key": "system.armorScore",
|
|
||||||
"mode": 2,
|
|
||||||
"value": "1",
|
|
||||||
"priority": null
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"description": "<ul><li class=\"vertical-card-list-found\"><p>+1 bonus to your Armor Score</p></li><li class=\"vertical-card-list-found\"><p>When you mark 1 or more Hit Points without marking an Armor Slot, clear an Armor Slot.</p></li></ul>",
|
"description": "<ul><li class=\"vertical-card-list-found\"><p>+1 bonus to your Armor Score</p></li><li class=\"vertical-card-list-found\"><p>When you mark 1 or more Hit Points without marking an Armor Slot, clear an Armor Slot.</p></li></ul>",
|
||||||
"origin": null,
|
"origin": null,
|
||||||
|
|
@ -130,7 +123,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!k1AtYd3lSchIymBr.H9lgIqqp1imSNOv9"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!k1AtYd3lSchIymBr.Ma8Zp005QYKPWIEN"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ownership": {
|
"ownership": {
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!LzLOJ9EVaHWAjoq9.qlzHOAnpBYzosQxK"
|
"_key": "!items.effects!LzLOJ9EVaHWAjoq9.qlzHOAnpBYzosQxK"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "YehcKtTeJ18q0THd",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!LzLOJ9EVaHWAjoq9.YehcKtTeJ18q0THd"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!crIbCb9NZ4K0VpoU.awdHgEaM54G3emOU"
|
"_key": "!items.effects!crIbCb9NZ4K0VpoU.awdHgEaM54G3emOU"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "Xp0MlTLdCe2oP36X",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!crIbCb9NZ4K0VpoU.Xp0MlTLdCe2oP36X"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!epkAmlZVk7HOfUUT.Fq9Q93IHCchhfSss"
|
"_key": "!items.effects!epkAmlZVk7HOfUUT.Fq9Q93IHCchhfSss"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "GyPhsm7zLznZDfN2",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!epkAmlZVk7HOfUUT.GyPhsm7zLznZDfN2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "XJueICAnl5vu2q2U",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!itSOp2GCyem0f7oM.XJueICAnl5vu2q2U"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -23,34 +23,27 @@
|
||||||
"effects": [
|
"effects": [
|
||||||
{
|
{
|
||||||
"name": "Bare Bones",
|
"name": "Bare Bones",
|
||||||
"type": "base",
|
"type": "armor",
|
||||||
"system": {
|
"system": {
|
||||||
"rangeDependence": {
|
"changes": [
|
||||||
"enabled": false,
|
{
|
||||||
"type": "withinRange",
|
"key": "system.armorScore",
|
||||||
"target": "hostile",
|
"type": "armor",
|
||||||
"range": "melee"
|
"phase": "initial",
|
||||||
}
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "@system.traits.strength.value"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"_id": "8ze88zUwdkQSKKJq",
|
"_id": "C7as6q5bx3S0Xxfn",
|
||||||
"img": "icons/magic/control/buff-strength-muscle-damage.webp",
|
"img": "icons/magic/control/buff-strength-muscle-damage.webp",
|
||||||
"changes": [
|
|
||||||
{
|
|
||||||
"key": "system.armorScore",
|
|
||||||
"mode": 2,
|
|
||||||
"value": "@system.traits.strength.value",
|
|
||||||
"priority": 21
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"description": "<p></p><p class=\"Body-Foundation\">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:</p><ul><li class=\"vertical-card-list-found\"><em><strong>Tier 1:</strong></em> 9/19</li><li class=\"vertical-card-list-found\"><em><strong>Tier 2:</strong></em> 11/24</li><li class=\"vertical-card-list-found\"><em><strong>Tier 3:</strong></em> 13/31</li><li class=\"vertical-card-list-found\"><em><strong>Tier 4:</strong></em> 15/38</li></ul>",
|
"description": "<p></p><p class=\"Body-Foundation\">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:</p><ul><li class=\"vertical-card-list-found\"><em><strong>Tier 1:</strong></em> 9/19</li><li class=\"vertical-card-list-found\"><em><strong>Tier 2:</strong></em> 11/24</li><li class=\"vertical-card-list-found\"><em><strong>Tier 3:</strong></em> 13/31</li><li class=\"vertical-card-list-found\"><em><strong>Tier 4:</strong></em> 15/38</li></ul>",
|
||||||
"origin": null,
|
"origin": null,
|
||||||
|
|
@ -62,7 +55,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!ITAjcigTcUw5pMCN.8ze88zUwdkQSKKJq"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!ITAjcigTcUw5pMCN.C7as6q5bx3S0Xxfn"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!WuoVwZA53XRAIt6d.Hy0sNtFS1JAXxgwC"
|
"_key": "!items.effects!WuoVwZA53XRAIt6d.Hy0sNtFS1JAXxgwC"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "2OMciFns3bSETeH9",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!WuoVwZA53XRAIt6d.2OMciFns3bSETeH9"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!mNN6pvcsS10ChrWF.s8KtTIngTjnOlaTP"
|
"_key": "!items.effects!mNN6pvcsS10ChrWF.s8KtTIngTjnOlaTP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "dIb9PWvzyS3jYDUj",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!mNN6pvcsS10ChrWF.dIb9PWvzyS3jYDUj"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!haULhuEg37zUUvhb.ZfO5NjpqEIzZVlPq"
|
"_key": "!items.effects!haULhuEg37zUUvhb.ZfO5NjpqEIzZVlPq"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "hA0EcaykFiIpg4ZH",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!haULhuEg37zUUvhb.hA0EcaykFiIpg4ZH"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!vMJxEWz1srfwMsoj.8bwf1Ri3jYkjphEv"
|
"_key": "!items.effects!vMJxEWz1srfwMsoj.8bwf1Ri3jYkjphEv"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "Wejd1c4e8VtnFoc4",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!vMJxEWz1srfwMsoj.Wejd1c4e8VtnFoc4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "FgjNYkbghYSz8gwW",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!mdQ69eFHyAQUDmE7.FgjNYkbghYSz8gwW"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "n4wyEBHbHIuYNBzt",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!hAY6UgdGT7dj22Pr.n4wyEBHbHIuYNBzt"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!Q6LxmtFetDDkoZVZ.xGxqTCO8MjNq5Cw6"
|
"_key": "!items.effects!Q6LxmtFetDDkoZVZ.xGxqTCO8MjNq5Cw6"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "gZfuMqjYTYLspQop",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!Q6LxmtFetDDkoZVZ.gZfuMqjYTYLspQop"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "5t3jCX3AGiWBB4DN",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!bcQUh4QG3qFX0Vx6.5t3jCX3AGiWBB4DN"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!7emTSt6nhZuTlvt5.QIefVb73cm9gYju8"
|
"_key": "!items.effects!7emTSt6nhZuTlvt5.QIefVb73cm9gYju8"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "9jCrg3Acd75jVclW",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!7emTSt6nhZuTlvt5.9jCrg3Acd75jVclW"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!UdUJNa31WxFW2noa.mfKMW9SX3Mnos1nY"
|
"_key": "!items.effects!UdUJNa31WxFW2noa.mfKMW9SX3Mnos1nY"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "OmGtjOMcTHNN6OsH",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!UdUJNa31WxFW2noa.OmGtjOMcTHNN6OsH"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!yJFp1bfpecDcStVK.v1FNEsypRF5W6vVc"
|
"_key": "!items.effects!yJFp1bfpecDcStVK.v1FNEsypRF5W6vVc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "ySw8mkws8rxzxsg4",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!yJFp1bfpecDcStVK.ySw8mkws8rxzxsg4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "nyoNusMuukJt1MJw",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!dvyQeUVRLc9y6rnt.nyoNusMuukJt1MJw"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!K5WkjS0NGqHYmhU3.JHupzYULxdQzFzuj"
|
"_key": "!items.effects!K5WkjS0NGqHYmhU3.JHupzYULxdQzFzuj"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "7FdWcilv74zKcXWk",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!K5WkjS0NGqHYmhU3.7FdWcilv74zKcXWk"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!9f7RozpPTqrzJS1m.wstJ1aKKtmXgCwxB"
|
"_key": "!items.effects!9f7RozpPTqrzJS1m.wstJ1aKKtmXgCwxB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "qgA4nbITVOp2WTpl",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!9f7RozpPTqrzJS1m.qgA4nbITVOp2WTpl"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!jphnMZjnS2FkOH3s.BFwU3ErPaajUSMUz"
|
"_key": "!items.effects!jphnMZjnS2FkOH3s.BFwU3ErPaajUSMUz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "dtkOq7rUKj5nLGJP",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!jphnMZjnS2FkOH3s.dtkOq7rUKj5nLGJP"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "JqnUKeUDbH4YJbVb",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!t91M61pSCMKStTNt.JqnUKeUDbH4YJbVb"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!tzZntboNtHL5C6VM.P3aCN8PQgPXP4C9M"
|
"_key": "!items.effects!tzZntboNtHL5C6VM.P3aCN8PQgPXP4C9M"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "6Mh24zh1c3aK60wZ",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!tzZntboNtHL5C6VM.6Mh24zh1c3aK60wZ"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "2enPnnikOoG0oIZP",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!nibfdNtp2PtxvbVz.2enPnnikOoG0oIZP"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!EsIN5OLKe9ZYFNXZ.8Oa6Y375X8UpcPph"
|
"_key": "!items.effects!EsIN5OLKe9ZYFNXZ.8Oa6Y375X8UpcPph"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "kqNdkD1d4FOQloMV",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!EsIN5OLKe9ZYFNXZ.kqNdkD1d4FOQloMV"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!SXWjUR2aUR6bYvdl.zvzkRX2Uevemmbz4"
|
"_key": "!items.effects!SXWjUR2aUR6bYvdl.zvzkRX2Uevemmbz4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "kFxM3Et2bPzghJWm",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!SXWjUR2aUR6bYvdl.kFxM3Et2bPzghJWm"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!c6tMXz4rPf9ioQrf.3AUNxBoj7mp1ziJQ"
|
"_key": "!items.effects!c6tMXz4rPf9ioQrf.3AUNxBoj7mp1ziJQ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "jdD0dJoh8gdGdh6W",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!c6tMXz4rPf9ioQrf.jdD0dJoh8gdGdh6W"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "gP4PsefQLSTcBAQm",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!Tptgl5WOj76TyFn7.gP4PsefQLSTcBAQm"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!AQzU2RsqS5V5bd1v.3n4O7PyAWMEFdr5p"
|
"_key": "!items.effects!AQzU2RsqS5V5bd1v.3n4O7PyAWMEFdr5p"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "xMJr6Zj9zZd7v5uD",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!AQzU2RsqS5V5bd1v.xMJr6Zj9zZd7v5uD"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "ebhSsuWrFYUVkGXC",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!tN8kAeBvNKM3EBFo.ebhSsuWrFYUVkGXC"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "pw8CD3IFNqb7530v",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!P4qAEDJUoNLgVRsA.pw8CD3IFNqb7530v"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "Y4ZSoO0iGxLiNr80",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!tHlBUDQC24YMZqd6.Y4ZSoO0iGxLiNr80"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!8X16lJQ3xltTwynm.rkrqlwqtR9REgRx7"
|
"_key": "!items.effects!8X16lJQ3xltTwynm.rkrqlwqtR9REgRx7"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "8"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "vNGSiFtcEBCz6jFQ",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!8X16lJQ3xltTwynm.vNGSiFtcEBCz6jFQ"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,45 @@
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!QjwsIhXKqnlvRBMv.V8CcTcVAIxHq8KNd"
|
"_key": "!items.effects!QjwsIhXKqnlvRBMv.V8CcTcVAIxHq8KNd"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "jfcv9NL2RtlfpECz",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!QjwsIhXKqnlvRBMv.jfcv9NL2RtlfpECz"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "E8iCCJSpPbCMostx",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!PSW3BxCGmtLeWOxM.E8iCCJSpPbCMostx"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,47 @@
|
||||||
"artist": ""
|
"artist": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects": [],
|
"effects": [
|
||||||
|
{
|
||||||
|
"type": "armor",
|
||||||
|
"name": "Armor Effect",
|
||||||
|
"img": "icons/equipment/chest/breastplate-helmet-metal.webp",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "avGWSRMFFLbdJaYC",
|
||||||
|
"disabled": false,
|
||||||
|
"start": null,
|
||||||
|
"duration": {
|
||||||
|
"value": null,
|
||||||
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
|
},
|
||||||
|
"description": "",
|
||||||
|
"origin": null,
|
||||||
|
"tint": "#ffffff",
|
||||||
|
"transfer": true,
|
||||||
|
"statuses": [],
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"sort": 0,
|
||||||
|
"flags": {},
|
||||||
|
"_stats": {
|
||||||
|
"compendiumSource": null
|
||||||
|
},
|
||||||
|
"_key": "!items.effects!OvzgUTYy2RCN85vV.avGWSRMFFLbdJaYC"
|
||||||
|
}
|
||||||
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
"ownership": {
|
"ownership": {
|
||||||
"default": 0,
|
"default": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,26 +113,26 @@
|
||||||
"name": "Protective",
|
"name": "Protective",
|
||||||
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
||||||
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
||||||
"changes": [
|
"_id": "7285CRGdZfHCEtT2",
|
||||||
{
|
"type": "armor",
|
||||||
"key": "system.armorScore",
|
"system": {
|
||||||
"mode": 2,
|
"changes": [
|
||||||
"value": "ITEM.@system.tier",
|
{
|
||||||
"priority": null
|
"key": "system.armorScore",
|
||||||
}
|
"type": "armor",
|
||||||
],
|
"phase": "initial",
|
||||||
"_id": "i5HfkF5aKQuUCTEG",
|
"priority": 20,
|
||||||
"type": "base",
|
"value": 0,
|
||||||
"system": {},
|
"max": "ITEM.@system.tier"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -143,7 +143,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!hiEOGF2reabGLUoi.i5HfkF5aKQuUCTEG"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!hiEOGF2reabGLUoi.7285CRGdZfHCEtT2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,25 +113,25 @@
|
||||||
"name": "Barrier",
|
"name": "Barrier",
|
||||||
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
||||||
"img": "icons/skills/melee/shield-block-bash-blue.webp",
|
"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",
|
"_id": "87gedjJZGdFY81Mt",
|
||||||
"type": "base",
|
"type": "base",
|
||||||
"system": {},
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.evasion",
|
||||||
|
"type": "add",
|
||||||
|
"value": -1,
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -142,7 +142,49 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
"_key": "!items.effects!OfOzQbs4hg6QbfTG.87gedjJZGdFY81Mt"
|
"_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": "armor",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"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,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,26 +113,26 @@
|
||||||
"name": "Protective",
|
"name": "Protective",
|
||||||
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
||||||
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
||||||
"changes": [
|
"_id": "pZCrWd7zLTarvEQK",
|
||||||
{
|
"type": "armor",
|
||||||
"key": "system.armorScore",
|
"system": {
|
||||||
"mode": 2,
|
"changes": [
|
||||||
"value": "ITEM.@system.tier",
|
{
|
||||||
"priority": null
|
"key": "system.armorScore",
|
||||||
}
|
"type": "armor",
|
||||||
],
|
"phase": "initial",
|
||||||
"_id": "cXWSV50apzaNQkdA",
|
"priority": 20,
|
||||||
"type": "base",
|
"value": 0,
|
||||||
"system": {},
|
"max": "ITEM.@system.tier"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -143,7 +143,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!DlinEBGZfIlvreO3.cXWSV50apzaNQkdA"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!DlinEBGZfIlvreO3.pZCrWd7zLTarvEQK"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,25 +113,25 @@
|
||||||
"name": "Barrier",
|
"name": "Barrier",
|
||||||
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
||||||
"img": "icons/skills/melee/shield-block-bash-blue.webp",
|
"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",
|
"_id": "tkNEA1PO3jEFhKCa",
|
||||||
"type": "base",
|
"type": "base",
|
||||||
"system": {},
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.evasion",
|
||||||
|
"type": "add",
|
||||||
|
"value": -1,
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -142,7 +142,49 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
"_key": "!items.effects!bxt3NsbMqTSdI5ab.tkNEA1PO3jEFhKCa"
|
"_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": "armor",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"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,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,20 +113,26 @@
|
||||||
"name": "Protective",
|
"name": "Protective",
|
||||||
"description": "Add your character's Tier to your Armor Score",
|
"description": "Add your character's Tier to your Armor Score",
|
||||||
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
||||||
"changes": [
|
"_id": "vnR4Zhnb0rOqwrFw",
|
||||||
{
|
"type": "armor",
|
||||||
"key": "system.armorScore",
|
"system": {
|
||||||
"mode": 2,
|
"changes": [
|
||||||
"value": "ITEM.@system.tier"
|
{
|
||||||
}
|
"key": "system.armorScore",
|
||||||
],
|
"type": "armor",
|
||||||
"_id": "qTxADRsQnKiYfOiQ",
|
"phase": "initial",
|
||||||
"type": "base",
|
"priority": 20,
|
||||||
"system": {},
|
"value": 0,
|
||||||
|
"max": "ITEM.@system.tier"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -137,7 +143,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!ijWppQzSOqVCb3rE.qTxADRsQnKiYfOiQ"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!ijWppQzSOqVCb3rE.vnR4Zhnb0rOqwrFw"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,26 +113,26 @@
|
||||||
"name": "Protective",
|
"name": "Protective",
|
||||||
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
||||||
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
||||||
"changes": [
|
"_id": "EixxJrRHyc6kj3Wg",
|
||||||
{
|
"type": "armor",
|
||||||
"key": "system.armorScore",
|
"system": {
|
||||||
"mode": 2,
|
"changes": [
|
||||||
"value": "ITEM.@system.tier",
|
{
|
||||||
"priority": null
|
"key": "system.armorScore",
|
||||||
}
|
"type": "armor",
|
||||||
],
|
"phase": "initial",
|
||||||
"_id": "Z2p00q5h6x6seXys",
|
"priority": 20,
|
||||||
"type": "base",
|
"value": 0,
|
||||||
"system": {},
|
"max": "ITEM.@system.tier"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -143,7 +143,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!A28WL9E2lJ3iLZHW.Z2p00q5h6x6seXys"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!A28WL9E2lJ3iLZHW.EixxJrRHyc6kj3Wg"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,25 +113,25 @@
|
||||||
"name": "Barrier",
|
"name": "Barrier",
|
||||||
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
||||||
"img": "icons/skills/melee/shield-block-bash-blue.webp",
|
"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",
|
"_id": "lBJMzxdGO2nJdTQS",
|
||||||
"type": "base",
|
"type": "base",
|
||||||
"system": {},
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.evasion",
|
||||||
|
"type": "add",
|
||||||
|
"value": -1,
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -142,7 +142,49 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
"_key": "!items.effects!MaJIROht7A9LxIZx.lBJMzxdGO2nJdTQS"
|
"_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": "armor",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"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,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,26 +113,26 @@
|
||||||
"name": "Protective",
|
"name": "Protective",
|
||||||
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
"description": "<p>Add the item's Tier to your Armor Score</p>",
|
||||||
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
"img": "icons/skills/melee/shield-block-gray-orange.webp",
|
||||||
"changes": [
|
"_id": "eV4lFIpQMiKERj4U",
|
||||||
{
|
"type": "armor",
|
||||||
"key": "system.armorScore",
|
"system": {
|
||||||
"mode": 2,
|
"changes": [
|
||||||
"value": "ITEM.@system.tier",
|
{
|
||||||
"priority": null
|
"key": "system.armorScore",
|
||||||
}
|
"type": "armor",
|
||||||
],
|
"phase": "initial",
|
||||||
"_id": "M70a81e0Mg66jHRL",
|
"priority": 20,
|
||||||
"type": "base",
|
"value": 0,
|
||||||
"system": {},
|
"max": "ITEM.@system.tier"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null,
|
"units": "seconds",
|
||||||
"seconds": null,
|
"expiry": null,
|
||||||
"rounds": null,
|
"expired": false
|
||||||
"turns": null,
|
|
||||||
"startRound": null,
|
|
||||||
"startTurn": null
|
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -143,7 +143,10 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
"_key": "!items.effects!mxwWKDujgsRcZWPT.M70a81e0Mg66jHRL"
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
|
"_key": "!items.effects!mxwWKDujgsRcZWPT.eV4lFIpQMiKERj4U"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"sort": 0,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,32 +113,31 @@
|
||||||
"name": "Double Duty",
|
"name": "Double Duty",
|
||||||
"description": "+1 to Armor Score; +1 to primary weapon damage within Melee range",
|
"description": "+1 to Armor Score; +1 to primary weapon damage within Melee range",
|
||||||
"img": "icons/skills/melee/sword-shield-stylized-white.webp",
|
"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": {
|
"system": {
|
||||||
"rangeDependence": {
|
"rangeDependence": {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"range": "melee",
|
"range": "melee",
|
||||||
"target": "hostile",
|
"target": "hostile",
|
||||||
"type": "withinRange"
|
"type": "withinRange"
|
||||||
}
|
},
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.bonuses.damage.primaryWeapon.bonus",
|
||||||
|
"type": "add",
|
||||||
|
"value": 1,
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"_id": "d3TJtlpoHBCztbom",
|
"_id": "d3TJtlpoHBCztbom",
|
||||||
"type": "base",
|
"type": "base",
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -149,7 +148,49 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
"_key": "!items.effects!vzyzFwLUniWZV1rt.d3TJtlpoHBCztbom"
|
"_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": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"max": "1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"_id": "mvUY9LGfwICak7cE",
|
||||||
|
"type": "armor",
|
||||||
|
"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,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -113,25 +113,25 @@
|
||||||
"name": "Barrier",
|
"name": "Barrier",
|
||||||
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
"description": "Gain Weapon Tier + 1 to Armor Score; -1 to Evasion",
|
||||||
"img": "icons/skills/melee/shield-block-bash-blue.webp",
|
"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",
|
"_id": "8r0TcKWXboFV0eqS",
|
||||||
"type": "base",
|
"type": "base",
|
||||||
"system": {},
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.evasion",
|
||||||
|
"type": "add",
|
||||||
|
"value": -1,
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"disabled": false,
|
"disabled": false,
|
||||||
"duration": {
|
"duration": {
|
||||||
"startTime": null,
|
"value": null,
|
||||||
"combat": null
|
"units": "seconds",
|
||||||
|
"expiry": null,
|
||||||
|
"expired": false
|
||||||
},
|
},
|
||||||
"origin": null,
|
"origin": null,
|
||||||
"tint": "#ffffff",
|
"tint": "#ffffff",
|
||||||
|
|
@ -142,7 +142,49 @@
|
||||||
"_stats": {
|
"_stats": {
|
||||||
"compendiumSource": null
|
"compendiumSource": null
|
||||||
},
|
},
|
||||||
|
"start": null,
|
||||||
|
"showIcon": 1,
|
||||||
|
"folder": null,
|
||||||
"_key": "!items.effects!C9aWpK1shVMWP4m5.8r0TcKWXboFV0eqS"
|
"_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": "armor",
|
||||||
|
"system": {
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"key": "system.armorScore",
|
||||||
|
"type": "armor",
|
||||||
|
"phase": "initial",
|
||||||
|
"priority": 20,
|
||||||
|
"value": 0,
|
||||||
|
"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,
|
"sort": 0,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,10 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 100%;
|
|
||||||
|
&.full-width {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.padded {
|
.padded {
|
||||||
|
|
@ -45,6 +48,7 @@
|
||||||
.armor-title {
|
.armor-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.resources-container {
|
.resources-container {
|
||||||
|
|
@ -62,12 +66,17 @@
|
||||||
|
|
||||||
.mark-selection {
|
.mark-selection {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.mark-selection-inner {
|
.mark-selection-inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
gap: 8px;
|
gap: 8px;
|
||||||
|
|
||||||
.mark-container {
|
.mark-container {
|
||||||
|
|
@ -91,6 +100,19 @@
|
||||||
opacity: 0.2;
|
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 {
|
.fa-shield {
|
||||||
position: relative;
|
position: relative;
|
||||||
right: 0.5px;
|
right: 0.5px;
|
||||||
|
|
|
||||||
5
styles/less/sheets/activeEffects/armorEffects.less
Normal file
5
styles/less/sheets/activeEffects/armorEffects.less
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
.application.sheet.daggerheart.dh-style.armor-effect-config {
|
||||||
|
.tab-form-footer {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -276,6 +276,23 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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 {
|
.status-value {
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
}
|
}
|
||||||
|
|
@ -298,6 +315,10 @@
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
background: light-dark(@dark-blue, @golden);
|
background: light-dark(@dark-blue, @golden);
|
||||||
clip-path: none;
|
clip-path: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
h4 {
|
h4 {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
@ -306,6 +327,11 @@
|
||||||
color: light-dark(@beige, @dark-blue);
|
color: light-dark(@beige, @dark-blue);
|
||||||
font-size: var(--font-size-12);
|
font-size: var(--font-size-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-size: 12px;
|
||||||
|
color: light-dark(@beige, @dark-blue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.slot-value {
|
.slot-value {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,4 @@
|
||||||
@import './actions/actions.less';
|
@import './actions/actions.less';
|
||||||
|
|
||||||
@import './activeEffects/activeEffects.less';
|
@import './activeEffects/activeEffects.less';
|
||||||
|
@import './activeEffects/armorEffects.less';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
@import './tooltip/tooltip.less';
|
@import './tooltip/tooltip.less';
|
||||||
|
@import './tooltip/armorManagement.less';
|
||||||
@import './tooltip/battlepoints.less';
|
@import './tooltip/battlepoints.less';
|
||||||
@import './tooltip/bordered-tooltip.less';
|
@import './tooltip/bordered-tooltip.less';
|
||||||
@import './tooltip/domain-cards.less';
|
@import './tooltip/domain-cards.less';
|
||||||
|
|
|
||||||
|
|
@ -97,4 +97,27 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
justify-content: center;
|
||||||
|
color: light-dark(@dark-blue, @golden);
|
||||||
|
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -278,7 +278,8 @@
|
||||||
},
|
},
|
||||||
"ActiveEffect": {
|
"ActiveEffect": {
|
||||||
"beastform": {},
|
"beastform": {},
|
||||||
"horde": {}
|
"horde": {},
|
||||||
|
"armor": {}
|
||||||
},
|
},
|
||||||
"Combat": {
|
"Combat": {
|
||||||
"combat": {}
|
"combat": {}
|
||||||
|
|
|
||||||
|
|
@ -7,53 +7,57 @@
|
||||||
<div class="section-container padded">
|
<div class="section-container padded">
|
||||||
<div class="resources-container">
|
<div class="resources-container">
|
||||||
<div class="resource-container">
|
<div class="resource-container">
|
||||||
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.armorMarks"}}</h4>
|
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.maxUseableArmor"}}</h4>
|
||||||
<div class="markers-subtitle">{{armorMarks}}/{{armorScore}}</div>
|
<div class="markers-subtitle">{{availableArmor}}</div>
|
||||||
</div>
|
</div>
|
||||||
{{#if this.stress}}
|
|
||||||
<div class="resource-container">
|
|
||||||
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.stress"}}</h4>
|
|
||||||
<div class="markers-subtitle">{{this.stress.value}}/{{this.stress.max}}</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-container">
|
<div class="section-container full-width">
|
||||||
<h4 class="mark-selection divider">
|
{{#each marks.armor as |source|}}
|
||||||
<div class="mark-selection-inner">
|
<div class="mark-selection">
|
||||||
{{#each marks.armor}}
|
<h4 class="divider">{{source.label}}</h4>
|
||||||
<div
|
<div class="mark-selection-inner">
|
||||||
class="mark-container {{#if this.selected}}selected{{/if}}"
|
{{#each source.marks}}
|
||||||
data-action="setMarks" data-key="{{@key}}" data-type="armor"
|
<a
|
||||||
>
|
class="mark-container {{#if this.selected}}selected{{/if}} {{#if this.spent}}spent{{/if}} {{#if this.disabled}}inactive{{/if}}"
|
||||||
<i class="fa-solid fa-shield"></i>
|
data-action="setMarks" data-type="armor" data-path="{{concat "armor." @../key ".marks." @key}}" data-id="{{@key}}"
|
||||||
</div>
|
{{#if this.disabled}}disabled{{/if}}
|
||||||
{{/each}}
|
>
|
||||||
|
<i class="fa-solid fa-shield"></i>
|
||||||
|
</a>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
{{#if usesStressArmor}}
|
||||||
|
<div class="mark-selection">
|
||||||
|
<h4 class="divider">{{localize "Stress"}}</h4>
|
||||||
|
<div class="mark-selection-inner">
|
||||||
{{#each marks.stress}}
|
{{#each marks.stress}}
|
||||||
<div
|
<div
|
||||||
class="mark-container {{#if this.selected}}selected{{/if}} {{#if (not @root.basicMarksUsed)}}inactive{{/if}}"
|
class="mark-container {{#if this.selected}}selected{{/if}} {{#if (not @root.basicMarksUsed)}}inactive{{/if}}"
|
||||||
{{#if @root.basicMarksUsed}}data-action="setMarks"{{/if}} data-key="{{@key}}" data-type="stress" data-tooltip="{{#if @root.basicMarksUsed}}{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.armorWithStress"}}{{else}}{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.unncessaryStress"}}{{/if}}"
|
{{#if @root.basicMarksUsed}}data-action="setMarks"{{/if}} data-type="stress" data-path="{{concat "stress." @key}}" data-tooltip="{{#if @root.basicMarksUsed}}{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.armorWithStress"}}{{else}}{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.unncessaryStress"}}{{/if}}"
|
||||||
>
|
>
|
||||||
<i class="fa-solid fa-bolt"></i>
|
<i class="fa-solid fa-bolt"></i>
|
||||||
</div>
|
</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</h4>
|
{{/if}}
|
||||||
<div class="markers-subtitle bold">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.usedMarks"}}</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if availableStressReductions}}
|
{{#if availableStressReductions}}
|
||||||
<div class="resources-container">
|
<div class="resources-container">
|
||||||
<div class="resource-container">
|
<div class="resource-container">
|
||||||
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.stressReduction"}}</h4>
|
<h4 class="armor-title divider">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.stressReduction"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#each availableStressReductions}}
|
{{#each availableStressReductions}}
|
||||||
<div class="section-container">
|
<div class="section-container">
|
||||||
<h4 class="chip-container divider">
|
<h4 class="chip-container">
|
||||||
<div class="chip-inner-container selectable {{#if (or this.any (eq this.from @root.currentDamage))}}active{{/if}} {{#if this.selected}}selected{{/if}}" data-action="useStressReduction" data-reduction="{{@key}}">
|
<div class="chip-inner-container selectable {{#if (or this.any (eq this.from @root.currentDamage))}}active{{/if}} {{#if this.selected}}selected{{/if}}" data-action="useStressReduction" data-reduction="{{@key}}">
|
||||||
{{#if this.any}}
|
{{#if this.any}}
|
||||||
{{localize "DAGGERHEART.GENERAL.any"}}
|
{{localize "DAGGERHEART.GENERAL.any"}}
|
||||||
|
|
@ -74,7 +78,7 @@
|
||||||
{{#if reduceSeverity}}
|
{{#if reduceSeverity}}
|
||||||
<div class="resources-container">
|
<div class="resources-container">
|
||||||
<div class="resource-container">
|
<div class="resource-container">
|
||||||
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.reduceSeverity" nr=reduceSeverity}}</h4>
|
<h4 class="armor-title divider">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.reduceSeverity" nr=reduceSeverity}}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
@ -82,7 +86,7 @@
|
||||||
{{#if thresholdImmunities}}
|
{{#if thresholdImmunities}}
|
||||||
<div class="resources-container">
|
<div class="resources-container">
|
||||||
<div class="resource-container">
|
<div class="resource-container">
|
||||||
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.thresholdImmunities"}}</h4>
|
<h4 class="armor-title divider">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.thresholdImmunities"}}</h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
|
||||||
20
templates/sheets/activeEffect/armor/details.hbs
Normal file
20
templates/sheets/activeEffect/armor/details.hbs
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
<section class="tab scrollable{{#if tab.active}} active{{/if}}" data-group="{{tab.group}}" data-tab="{{tab.id}}">
|
||||||
|
{{formGroup fields.tint value=source.tint rootId=rootId placeholder="#ffffff"}}
|
||||||
|
{{formGroup fields.description value=source.description rootId=rootId}}
|
||||||
|
{{formGroup fields.disabled value=source.disabled rootId=rootId}}
|
||||||
|
|
||||||
|
{{#if isActorEffect}}
|
||||||
|
<div class="form-group">
|
||||||
|
<label>{{localize "EFFECT.FIELDS.origin.label"}}</label>
|
||||||
|
<div class="form-fields">
|
||||||
|
<input type="text" value="{{source.origin}}" disabled />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if isItemEffect}}
|
||||||
|
{{formGroup fields.transfer value=source.transfer rootId=rootId label=legacyTransfer.label hint=(localize "DAGGERHEART.EFFECTS.Attachments.transferHint")}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{formGroup fields.showIcon value=source.showIcon options=showIconOptions rootId=rootId}}
|
||||||
|
</section>
|
||||||
3
templates/sheets/activeEffect/armor/footer.hbs
Normal file
3
templates/sheets/activeEffect/armor/footer.hbs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
<section class='tab-form-footer padded'>
|
||||||
|
<button type="button" data-action="finish"><i class="fa-solid fa-floppy-disk"></i> {{localize "Save"}}</button>
|
||||||
|
</section>
|
||||||
17
templates/sheets/activeEffect/armor/settings.hbs
Normal file
17
templates/sheets/activeEffect/armor/settings.hbs
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<section class="tab{{#if tab.active}} active{{/if}}" data-group="{{tab.group}}" data-tab="{{tab.id}}">
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{localize "Armor"}}</legend>
|
||||||
|
<div class="two-columns even">
|
||||||
|
{{#each source.system.changes as |change index|}}
|
||||||
|
{{formGroup @root.systemFields.changes.element.fields.value name=(concat 'system.changes.' index '.value') value=change.value localize=true}}
|
||||||
|
{{formGroup @root.systemFields.changes.element.fields.max name=(concat 'system.changes.' index '.max') value=change.max localize=true}}
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</fieldset>
|
||||||
|
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{localize "DAGGERHEART.GENERAL.general"}}</legend>
|
||||||
|
|
||||||
|
{{formGroup @root.systemFields.armorInteraction name="system.armorInteraction" value=source.system.armorInteraction localize=true}}
|
||||||
|
</fieldset>
|
||||||
|
</section>
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
collection=effects.inactives
|
collection=effects.inactives
|
||||||
canCreate=true
|
canCreate=true
|
||||||
hideResources=true
|
hideResources=true
|
||||||
|
disabled=true
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -30,14 +30,14 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if document.system.armor.system.marks}}
|
{{#if document.system.armorScore.max}}
|
||||||
<div class="status-bar armor-slots">
|
<div class="status-bar armor-slots">
|
||||||
{{#if useResourcePips}}
|
{{#if useResourcePips}}
|
||||||
<div class='slot-value'>
|
<div class='slot-value'>
|
||||||
<div class="slot-bar">
|
<div class="slot-bar">
|
||||||
{{#times document.system.armorScore}}
|
{{#times document.system.armorScore.max}}
|
||||||
<a class='armor-slot' data-action='toggleArmor' data-value="{{add this 1}}">
|
<a class='armor-slot' data-action='toggleArmor' data-value="{{add this 1}}">
|
||||||
{{#if (gte ../document.system.armor.system.marks.value (add this 1))}}
|
{{#if (gte ../document.system.armorScore.value (add this 1))}}
|
||||||
<i class="fa-solid fa-shield"></i>
|
<i class="fa-solid fa-shield"></i>
|
||||||
{{else}}
|
{{else}}
|
||||||
<i class="fa-solid fa-shield-halved"></i>
|
<i class="fa-solid fa-shield-halved"></i>
|
||||||
|
|
@ -45,25 +45,29 @@
|
||||||
</a>
|
</a>
|
||||||
{{/times}}
|
{{/times}}
|
||||||
</div>
|
</div>
|
||||||
<div class="slot-label">
|
<a class="slot-label" data-action="toggleArmorMangement">
|
||||||
<span class="label">{{localize "DAGGERHEART.GENERAL.armorSlots"}}</span>
|
<span class="label">{{localize "DAGGERHEART.GENERAL.armorSlots"}}</span>
|
||||||
<span class="value">{{document.system.armor.system.marks.value}} / {{document.system.armorScore}}</span>
|
<div class="slot-value-container">
|
||||||
</div>
|
<span class="value">{{document.system.armorScore.value}} / {{document.system.armorScore.max}}</span>
|
||||||
|
<i class="fa-solid fa-gear"></i>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class='status-value'>
|
<div class='status-value'>
|
||||||
<input class="bar-input armor-marks-input" value="{{document.system.armor.system.marks.value}}" type="number">
|
<input class="bar-input armor-marks-input" value="{{document.system.armorScore.value}}" type="number">
|
||||||
<span>/</span>
|
<span>/</span>
|
||||||
<span class="bar-label">{{document.system.armorScore}}</span>
|
<span class="bar-label">{{document.system.armorScore.max}}</span>
|
||||||
</div>
|
</div>
|
||||||
<progress
|
<progress
|
||||||
class='progress-bar stress-color'
|
class='progress-bar stress-color'
|
||||||
value='{{document.system.armor.system.marks.value}}'
|
value='{{document.system.armorScore.value}}'
|
||||||
max='{{document.system.armorScore}}'
|
max='{{document.system.armorScore.max}}'
|
||||||
></progress>
|
></progress>
|
||||||
<div class="status-label">
|
<a class="status-label" data-action="toggleArmorMangement">
|
||||||
<h4>{{localize "DAGGERHEART.GENERAL.armorSlots"}}</h4>
|
<h4>{{localize "DAGGERHEART.GENERAL.armorSlots"}}</h4>
|
||||||
</div>
|
<i class="fa-solid fa-gear"></i>
|
||||||
|
</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,6 @@
|
||||||
collection=effects.inactives
|
collection=effects.inactives
|
||||||
canCreate=true
|
canCreate=true
|
||||||
hideResources=true
|
hideResources=true
|
||||||
|
disabled=true
|
||||||
}}
|
}}
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -7,8 +7,12 @@
|
||||||
<legend>{{localize tabs.settings.label}}</legend>
|
<legend>{{localize tabs.settings.label}}</legend>
|
||||||
<span>{{localize "DAGGERHEART.GENERAL.Tiers.singular"}}</span>
|
<span>{{localize "DAGGERHEART.GENERAL.Tiers.singular"}}</span>
|
||||||
{{formField systemFields.tier value=source.system.tier}}
|
{{formField systemFields.tier value=source.system.tier}}
|
||||||
<span>{{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}</span>
|
{{#if this.armorScore includeZero=true}}
|
||||||
{{formField systemFields.baseScore value=source.system.baseScore}}
|
<span>{{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}</span>
|
||||||
|
<div class="form-fields">
|
||||||
|
<input type="text" data-dtype="Number" class="base-score-input" value="{{this.armorScore}}" />
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<span>{{localize "TYPES.Item.feature"}}</span>
|
<span>{{localize "TYPES.Item.feature"}}</span>
|
||||||
<input type="text" class="features-input" value="{{features}}" />
|
<input type="text" class="features-input" value="{{features}}" />
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,36 @@
|
||||||
<div class="daggerheart armor-management-container">
|
<div class="daggerheart armor-management-container">
|
||||||
{{#each sources as |source|}}
|
{{#each sources as |source|}}
|
||||||
<div class="armor-source-container">
|
{{#if ../useResourcePips}}
|
||||||
<label class="armor-source-label">{{source.name}}</label>
|
<div class="armor-source-container">
|
||||||
<div class="status-bar armor-slots">
|
<label class="armor-source-label">{{source.name}}</label>
|
||||||
<div class='status-value'>
|
<div class="slot-bar">
|
||||||
<input class="bar-input armor-marks-input" value="{{source.value}}" data-uuid="{{source.uuid}}" type="number">
|
{{#times source.max}}
|
||||||
<span>/</span>
|
<a class='armor-slot' data-value="{{add this 1}}" data-uuid="{{source.uuid}}">
|
||||||
<span class="bar-label">{{source.max}}</span>
|
{{#if (gte ../value (add this 1))}}
|
||||||
|
<i class="fa-solid fa-shield" data-index="{{this}}"></i>
|
||||||
|
{{else}}
|
||||||
|
<i class="fa-solid fa-shield-halved" data-index="{{this}}"></i>
|
||||||
|
{{/if}}
|
||||||
|
</a>
|
||||||
|
{{/times}}
|
||||||
</div>
|
</div>
|
||||||
<progress
|
|
||||||
class='progress-bar stress-color'
|
|
||||||
value='{{source.value}}'
|
|
||||||
max='{{source.max}}'
|
|
||||||
></progress>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
{{else}}
|
||||||
|
<div class="armor-source-container">
|
||||||
|
<label class="armor-source-label">{{source.name}}</label>
|
||||||
|
<div class="status-bar armor-slots">
|
||||||
|
<div class='status-value'>
|
||||||
|
<input class="bar-input armor-marks-input" value="{{source.value}}" data-uuid="{{source.uuid}}" type="number">
|
||||||
|
<span>/</span>
|
||||||
|
<span class="bar-label">{{source.max}}</span>
|
||||||
|
</div>
|
||||||
|
<progress
|
||||||
|
class='progress-bar stress-color'
|
||||||
|
value='{{source.value}}'
|
||||||
|
max='{{source.max}}'
|
||||||
|
></progress>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue