mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 06:26:13 +01:00
Compare commits
2 commits
3b011e2580
...
6176c3265d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6176c3265d | ||
|
|
8f0b1f6ed3 |
11 changed files with 293 additions and 90 deletions
|
|
@ -437,7 +437,7 @@
|
|||
"text": "Are you sure you want to delete {name}?"
|
||||
},
|
||||
"DamageReduction": {
|
||||
"armorMarks": "Armor Marks",
|
||||
"maxUseableArmor": "Useable Armor Slots",
|
||||
"armorWithStress": "Spend 1 stress to use an extra mark",
|
||||
"thresholdImmunities": "Threshold Immunities",
|
||||
"stress": "Stress",
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
this.reject = reject;
|
||||
this.actor = actor;
|
||||
this.damage = damage;
|
||||
this.damageType = damageType;
|
||||
// this.damageType = damageType;
|
||||
this.damageType = ['physical'];
|
||||
this.rulesDefault = game.settings.get(
|
||||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Automation
|
||||
|
|
@ -20,14 +21,25 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
this.rulesDefault
|
||||
);
|
||||
|
||||
const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true);
|
||||
const availableArmor = actor.system.armorScore.max - actor.system.armorScore.value;
|
||||
const maxArmorMarks = canApplyArmor ? availableArmor : 0;
|
||||
const allArmorEffects = Array.from(actor.allApplicableEffects()).filter(x => x.type === 'armor');
|
||||
const orderedArmorEffects = game.system.api.data.activeEffects.ArmorEffect.orderEffectsForAutoChange(
|
||||
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;
|
||||
}, {});
|
||||
}, []);
|
||||
const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce(
|
||||
(acc, _) => {
|
||||
acc[foundry.utils.randomID()] = { selected: false };
|
||||
|
|
@ -121,13 +133,11 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
context.thresholdImmunities =
|
||||
Object.keys(this.thresholdImmunities).length > 0 ? this.thresholdImmunities : null;
|
||||
|
||||
const { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage } =
|
||||
const { selectedStressMarks, stressReductions, currentMarks, currentDamage, maxArmorUsed, availableArmor } =
|
||||
this.getDamageInfo();
|
||||
|
||||
context.armorScore = this.actor.system.armorScore.max;
|
||||
context.armorMarks = currentMarks;
|
||||
context.basicMarksUsed =
|
||||
selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.value;
|
||||
|
||||
const stressReductionStress = this.availableStressReductions
|
||||
? stressReductions.reduce((acc, red) => acc + red.cost, 0)
|
||||
|
|
@ -141,16 +151,27 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
}
|
||||
: null;
|
||||
|
||||
const maxArmor = this.actor.system.rules.damageReduction.maxArmorMarked.value;
|
||||
context.marks = {
|
||||
armor: Object.keys(this.marks.armor).reduce((acc, key, index) => {
|
||||
const mark = this.marks.armor[key];
|
||||
if (!this.rulesOn || index + 1 <= maxArmor) acc[key] = mark;
|
||||
context.maxArmorUsed = maxArmorUsed;
|
||||
context.availableArmor = availableArmor;
|
||||
context.basicMarksUsed = availableArmor === 0 || selectedStressMarks.length;
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
context.usesStressArmor = Object.keys(context.marks.stress).length;
|
||||
context.availableStressReductions = this.availableStressReductions;
|
||||
|
||||
context.damage = getDamageLabel(this.damage);
|
||||
|
|
@ -167,27 +188,31 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
}
|
||||
|
||||
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 stressReductions = this.availableStressReductions
|
||||
? Object.values(this.availableStressReductions).filter(red => red.selected)
|
||||
: [];
|
||||
const currentMarks =
|
||||
this.actor.system.armorScore.value + selectedArmorMarks.length + selectedStressMarks.length;
|
||||
const currentMarks = this.actor.system.armorScore.value + selectedArmorMarks.length;
|
||||
|
||||
const maxArmorUsed = this.actor.system.rules.damageReduction.maxArmorMarked.value + selectedStressMarks.length;
|
||||
const availableArmor =
|
||||
maxArmorUsed -
|
||||
this.marks.armor.reduce((acc, source) => {
|
||||
acc += Object.values(source.marks).filter(x => x.selected).length;
|
||||
return acc;
|
||||
}, 0);
|
||||
|
||||
const armorMarkReduction =
|
||||
selectedArmorMarks.length * this.actor.system.rules.damageReduction.increasePerArmorMark;
|
||||
let currentDamage = Math.max(
|
||||
this.damage - armorMarkReduction - selectedStressMarks.length - stressReductions.length,
|
||||
0
|
||||
);
|
||||
let currentDamage = Math.max(this.damage - armorMarkReduction - stressReductions.length, 0);
|
||||
if (this.reduceSeverity) {
|
||||
currentDamage = Math.max(currentDamage - this.reduceSeverity, 0);
|
||||
}
|
||||
|
||||
if (this.thresholdImmunities[currentDamage]) currentDamage = 0;
|
||||
|
||||
return { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage };
|
||||
return { selectedStressMarks, stressReductions, currentMarks, currentDamage, maxArmorUsed, availableArmor };
|
||||
};
|
||||
|
||||
static toggleRules() {
|
||||
|
|
@ -209,8 +234,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
}
|
||||
|
||||
static setMarks(_, target) {
|
||||
const currentMark = this.marks[target.dataset.type][target.dataset.key];
|
||||
const { selectedStressMarks, stressReductions, currentMarks, currentDamage } = this.getDamageInfo();
|
||||
const currentMark = foundry.utils.getProperty(this.marks, target.dataset.path);
|
||||
const { selectedStressMarks, stressReductions, currentDamage, availableArmor } = this.getDamageInfo();
|
||||
|
||||
if (!currentMark.selected && currentDamage === 0) {
|
||||
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 (!currentMark.selected && currentMarks === this.actor.system.armorScore.max) {
|
||||
if (target.dataset.type === 'armor' && !currentMark.selected && !availableArmor) {
|
||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noAvailableArmorMarks'));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const stressUsed = selectedStressMarks.length;
|
||||
if (target.dataset.type === 'armor' && stressUsed) {
|
||||
const updateResult = this.updateStressArmor(target.dataset.id, !currentMark.selected);
|
||||
if (updateResult === false) return;
|
||||
}
|
||||
|
||||
if (currentMark.selected) {
|
||||
const currentDamageLabel = getDamageLabel(currentDamage);
|
||||
for (let reduction of stressReductions) {
|
||||
|
|
@ -232,8 +263,16 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
}
|
||||
}
|
||||
|
||||
if (target.dataset.type === 'armor' && selectedStressMarks.length > 0) {
|
||||
selectedStressMarks.forEach(mark => (mark.selected = false));
|
||||
if (target.dataset.type === 'stress' && currentMark.armorMarkId) {
|
||||
for (const source of this.marks.armor) {
|
||||
const match = Object.keys(source.marks).find(key => key === currentMark.armorMarkId);
|
||||
if (match) {
|
||||
source.marks[match].selected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
currentMark.armorMarkId = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -241,6 +280,25 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
this.render();
|
||||
}
|
||||
|
||||
updateStressArmor(armorMarkId, select) {
|
||||
let stressMarkKey = null;
|
||||
if (select) {
|
||||
stressMarkKey = Object.keys(this.marks.stress).find(
|
||||
key => this.marks.stress[key].selected && !this.marks.stress[key].armorMarkId
|
||||
);
|
||||
} else {
|
||||
stressMarkKey = Object.keys(this.marks.stress).find(
|
||||
key => this.marks.stress[key].armorMarkId === armorMarkId
|
||||
);
|
||||
if (!stressMarkKey)
|
||||
stressMarkKey = Object.keys(this.marks.stress).find(key => this.marks.stress[key].selected);
|
||||
}
|
||||
|
||||
if (!stressMarkKey) return false;
|
||||
|
||||
this.marks.stress[stressMarkKey].armorMarkId = select ? armorMarkId : null;
|
||||
}
|
||||
|
||||
static useStressReduction(_, target) {
|
||||
const damageValue = Number(target.dataset.reduction);
|
||||
const stressReduction = this.availableStressReductions[damageValue];
|
||||
|
|
@ -279,11 +337,19 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
}
|
||||
|
||||
static async takeDamage() {
|
||||
const { selectedArmorMarks, selectedStressMarks, stressReductions, currentDamage } = this.getDamageInfo();
|
||||
const armorSpent = selectedArmorMarks.length + selectedStressMarks.length;
|
||||
const stressSpent = selectedStressMarks.length + stressReductions.reduce((acc, red) => acc + red.cost, 0);
|
||||
const { selectedStressMarks, stressReductions, currentDamage } = this.getDamageInfo();
|
||||
const armorChanges = this.marks.armor.reduce((acc, source) => {
|
||||
const amount = Object.values(source.marks).filter(x => x.selected).length;
|
||||
if (!amount) 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -966,11 +966,16 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
|
||||
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
|
||||
sources: armorSources,
|
||||
useResourcePips
|
||||
}
|
||||
);
|
||||
|
||||
|
|
@ -986,6 +991,10 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
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) {
|
||||
|
|
@ -1000,12 +1009,11 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
static async armorSourceUpdate(event) {
|
||||
const effect = await foundry.utils.fromUuid(event.target.dataset.uuid);
|
||||
if (effect.system.changes.length !== 1) return;
|
||||
const armorEffect = effect.system.changes[0];
|
||||
const value = Math.max(Math.min(Number.parseInt(event.target.value), effect.system.armorData.max), 0);
|
||||
|
||||
const newChanges = [
|
||||
{
|
||||
...armorEffect,
|
||||
...effect.system.changes[0],
|
||||
value
|
||||
}
|
||||
];
|
||||
|
|
@ -1017,6 +1025,38 @@ export default class CharacterSheet extends DHBaseActorSheet {
|
|||
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.
|
||||
* @type {ApplicationClickAction}
|
||||
|
|
|
|||
|
|
@ -559,6 +559,18 @@ export default class DhCharacter extends BaseDataActor {
|
|||
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() {
|
||||
const ancestryFeatures = [],
|
||||
communityFeatures = [],
|
||||
|
|
|
|||
|
|
@ -626,12 +626,10 @@ export default class DhpActor extends Actor {
|
|||
}
|
||||
);
|
||||
if (armorSlotResult) {
|
||||
const { modifiedDamage, armorSpent, stressSpent } = armorSlotResult;
|
||||
const { modifiedDamage, armorChanges, stressSpent } = armorSlotResult;
|
||||
updates.find(u => u.key === 'hitPoints').value = modifiedDamage;
|
||||
if (armorSpent) {
|
||||
const armorUpdate = updates.find(u => u.key === 'armor');
|
||||
if (armorUpdate) armorUpdate.value += armorSpent;
|
||||
else updates.push({ value: armorSpent, key: 'armor' });
|
||||
for (const armorChange of armorChanges) {
|
||||
updates.push({ value: armorChange.amount, key: 'armor', uuid: armorChange.uuid });
|
||||
}
|
||||
if (stressSpent) {
|
||||
const stressUpdate = updates.find(u => u.key === 'stress');
|
||||
|
|
@ -778,7 +776,8 @@ export default class DhpActor extends Actor {
|
|||
);
|
||||
break;
|
||||
case 'armor':
|
||||
this.system.updateArmorValue(r);
|
||||
if (!r.uuid) this.system.updateArmorValue(r);
|
||||
else this.system.updateArmorEffectValue(r);
|
||||
break;
|
||||
default:
|
||||
if (this.system.resources?.[r.key]) {
|
||||
|
|
|
|||
|
|
@ -35,7 +35,10 @@
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
|
||||
&.full-width {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.padded {
|
||||
|
|
@ -45,6 +48,7 @@
|
|||
.armor-title {
|
||||
margin: 0;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.resources-container {
|
||||
|
|
@ -62,12 +66,17 @@
|
|||
|
||||
.mark-selection {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
||||
h4 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.mark-selection-inner {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
|
||||
.mark-container {
|
||||
|
|
@ -91,6 +100,19 @@
|
|||
opacity: 0.2;
|
||||
}
|
||||
|
||||
&.spent {
|
||||
::after {
|
||||
position: absolute;
|
||||
content: '/';
|
||||
color: red;
|
||||
font-weight: 700;
|
||||
font-size: 1.8em;
|
||||
left: -1px;
|
||||
top: -7px;
|
||||
rotate: 13deg;
|
||||
}
|
||||
}
|
||||
|
||||
.fa-shield {
|
||||
position: relative;
|
||||
right: 0.5px;
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,53 +7,57 @@
|
|||
<div class="section-container padded">
|
||||
<div class="resources-container">
|
||||
<div class="resource-container">
|
||||
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.armorMarks"}}</h4>
|
||||
<div class="markers-subtitle">{{armorMarks}}/{{armorScore}}</div>
|
||||
<h4 class="armor-title">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.maxUseableArmor"}}</h4>
|
||||
<div class="markers-subtitle">{{availableArmor}}</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 class="section-container">
|
||||
<h4 class="mark-selection divider">
|
||||
<div class="mark-selection-inner">
|
||||
{{#each marks.armor}}
|
||||
<div
|
||||
class="mark-container {{#if this.selected}}selected{{/if}}"
|
||||
data-action="setMarks" data-key="{{@key}}" data-type="armor"
|
||||
>
|
||||
<i class="fa-solid fa-shield"></i>
|
||||
</div>
|
||||
{{/each}}
|
||||
<div class="section-container full-width">
|
||||
{{#each marks.armor as |source|}}
|
||||
<div class="mark-selection">
|
||||
<h4 class="divider">{{source.label}}</h4>
|
||||
<div class="mark-selection-inner">
|
||||
{{#each source.marks}}
|
||||
<a
|
||||
class="mark-container {{#if this.selected}}selected{{/if}} {{#if this.spent}}spent{{/if}} {{#if this.disabled}}inactive{{/if}}"
|
||||
data-action="setMarks" data-type="armor" data-path="{{concat "armor." @../key ".marks." @key}}" data-id="{{@key}}"
|
||||
{{#if this.disabled}}disabled{{/if}}
|
||||
>
|
||||
<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}}
|
||||
<div
|
||||
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>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="markers-subtitle bold">{{localize "DAGGERHEART.APPLICATIONS.DamageReduction.usedMarks"}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{#if availableStressReductions}}
|
||||
<div class="resources-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>
|
||||
{{/if}}
|
||||
|
||||
{{#each availableStressReductions}}
|
||||
<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}}">
|
||||
{{#if this.any}}
|
||||
{{localize "DAGGERHEART.GENERAL.any"}}
|
||||
|
|
@ -74,7 +78,7 @@
|
|||
{{#if reduceSeverity}}
|
||||
<div class="resources-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>
|
||||
{{/if}}
|
||||
|
|
@ -82,7 +86,7 @@
|
|||
{{#if thresholdImmunities}}
|
||||
<div class="resources-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>
|
||||
{{/if}}
|
||||
|
|
|
|||
|
|
@ -45,10 +45,13 @@
|
|||
</a>
|
||||
{{/times}}
|
||||
</div>
|
||||
<div class="slot-label">
|
||||
<a class="slot-label" data-action="toggleArmorMangement">
|
||||
<span class="label">{{localize "DAGGERHEART.GENERAL.armorSlots"}}</span>
|
||||
<span class="value">{{document.system.armorScore.value}} / {{document.system.armorScore.max}}</span>
|
||||
</div>
|
||||
<div class="slot-value-container">
|
||||
<span class="value">{{document.system.armorScore.value}} / {{document.system.armorScore.max}}</span>
|
||||
<i class="fa-solid fa-gear"></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class='status-value'>
|
||||
|
|
@ -61,10 +64,10 @@
|
|||
value='{{document.system.armorScore.value}}'
|
||||
max='{{document.system.armorScore.max}}'
|
||||
></progress>
|
||||
<div class="status-label" data-action="toggleArmorMangement">
|
||||
<a class="status-label" data-action="toggleArmorMangement">
|
||||
<h4>{{localize "DAGGERHEART.GENERAL.armorSlots"}}</h4>
|
||||
<i class="fa-solid fa-gear"></i>
|
||||
</div>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{else}}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,36 @@
|
|||
<div class="daggerheart armor-management-container">
|
||||
{{#each sources as |source|}}
|
||||
<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>
|
||||
{{#if ../useResourcePips}}
|
||||
<div class="armor-source-container">
|
||||
<label class="armor-source-label">{{source.name}}</label>
|
||||
<div class="slot-bar">
|
||||
{{#times source.max}}
|
||||
<a class='armor-slot' data-value="{{add this 1}}" data-uuid="{{source.uuid}}">
|
||||
{{#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>
|
||||
<progress
|
||||
class='progress-bar stress-color'
|
||||
value='{{source.value}}'
|
||||
max='{{source.max}}'
|
||||
></progress>
|
||||
</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}}
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue