mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-13 04:01:06 +01:00
Fixed Stress Reductions
This commit is contained in:
parent
f4539ab158
commit
0e1320e31d
8 changed files with 279 additions and 74 deletions
|
|
@ -1095,9 +1095,11 @@
|
||||||
"ArmorMarks": "Armor Marks",
|
"ArmorMarks": "Armor Marks",
|
||||||
"UsedMarks": "Used Marks",
|
"UsedMarks": "Used Marks",
|
||||||
"Stress": "Stress",
|
"Stress": "Stress",
|
||||||
|
"ArmorWithStress": "Spend 1 stress to use an extra mark",
|
||||||
|
"StressReduction": "Reduce By Stress",
|
||||||
"Notifications": {
|
"Notifications": {
|
||||||
"DamageAlreadyNone": "The damage has already been reduced to none",
|
"DamageAlreadyNone": "The damage has already been reduced to none",
|
||||||
"NotEnoughArmor": "You don't have enough unspent armor marks"
|
"DamageIgnore": "{character} did not take damage"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"Sheets": {
|
"Sheets": {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { getDamageLabel } from '../helpers/utils.mjs';
|
import { damageKeyToNumber, getDamageLabel } from '../helpers/utils.mjs';
|
||||||
|
|
||||||
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
|
|
||||||
|
|
@ -11,13 +11,32 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.damage = damage;
|
this.damage = damage;
|
||||||
|
|
||||||
|
const maxUseable = actor.system.armorScore - actor.system.armor.system.marks.value;
|
||||||
this.availableArmorMarks = {
|
this.availableArmorMarks = {
|
||||||
max: actor.system.rules.maxArmorMarked.total + (actor.system.rules.stressExtra ?? 0),
|
max: Math.min(
|
||||||
maxUseable: actor.system.armorScore - actor.system.armor.system.marks.value,
|
maxUseable,
|
||||||
stressIndex:
|
actor.system.rules.maxArmorMarked.total + (actor.system.rules.maxArmorMarked.stressExtra ?? 0)
|
||||||
(actor.system.rules.stressExtra ?? 0) > 0 ? actor.system.rules.maxArmorMarked.total : undefined,
|
),
|
||||||
|
stressIndex: actor.system.rules.maxArmorMarked.total,
|
||||||
selected: 0
|
selected: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.availableStressReductions = Object.keys(actor.system.rules.stressDamageReduction).reduce((acc, key) => {
|
||||||
|
const dr = actor.system.rules.stressDamageReduction[key];
|
||||||
|
if (dr.enabled) {
|
||||||
|
if (acc === null) acc = {};
|
||||||
|
|
||||||
|
const damage = damageKeyToNumber(key);
|
||||||
|
acc[damage] = {
|
||||||
|
cost: dr.cost,
|
||||||
|
selected: false,
|
||||||
|
from: getDamageLabel(damage),
|
||||||
|
to: getDamageLabel(damage - 1)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
|
|
@ -33,6 +52,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
setMarks: this.setMarks,
|
setMarks: this.setMarks,
|
||||||
|
useStressReduction: this.useStressReduction,
|
||||||
takeDamage: this.takeDamage
|
takeDamage: this.takeDamage
|
||||||
},
|
},
|
||||||
form: {
|
form: {
|
||||||
|
|
@ -61,13 +81,31 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
const context = await super._prepareContext(_options);
|
const context = await super._prepareContext(_options);
|
||||||
context.armorScore = this.actor.system.armorScore;
|
context.armorScore = this.actor.system.armorScore;
|
||||||
context.armorMarks = this.actor.system.armor.system.marks.value + this.availableArmorMarks.selected;
|
context.armorMarks = this.actor.system.armor.system.marks.value + this.availableArmorMarks.selected;
|
||||||
|
|
||||||
|
const selectedStressReductions = Object.values(this.availableStressReductions).filter(red => red.selected);
|
||||||
|
const stressReductionStress = this.availableStressReductions
|
||||||
|
? selectedStressReductions.reduce((acc, red) => acc + red.cost, 0)
|
||||||
|
: 0;
|
||||||
|
context.stress =
|
||||||
|
this.availableArmorMarks.stressIndex || this.availableStressReductions
|
||||||
|
? {
|
||||||
|
value:
|
||||||
|
this.actor.system.resources.stress.value +
|
||||||
|
(Math.max(this.availableArmorMarks.selected - this.availableArmorMarks.stressIndex, 0) +
|
||||||
|
stressReductionStress),
|
||||||
|
maxTotal: this.actor.system.resources.stress.maxTotal
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
|
||||||
context.availableArmorMarks = this.availableArmorMarks;
|
context.availableArmorMarks = this.availableArmorMarks;
|
||||||
|
context.availableStressReductions = this.availableStressReductions;
|
||||||
|
|
||||||
context.damage = getDamageLabel(this.damage);
|
context.damage = getDamageLabel(this.damage);
|
||||||
context.reducedDamage =
|
context.reducedDamage =
|
||||||
this.availableArmorMarks.selected > 0
|
this.availableArmorMarks.selected > 0 || selectedStressReductions.length > 0
|
||||||
? getDamageLabel(this.damage - this.availableArmorMarks.selected)
|
? getDamageLabel(this.damage - this.availableArmorMarks.selected - selectedStressReductions.length)
|
||||||
: null;
|
: null;
|
||||||
|
context.currentDamage = context.reducedDamage ?? context.damage;
|
||||||
|
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
@ -79,21 +117,51 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
||||||
|
|
||||||
static setMarks(_, target) {
|
static setMarks(_, target) {
|
||||||
const index = Number(target.dataset.index);
|
const index = Number(target.dataset.index);
|
||||||
if (index >= this.availableArmorMarks.maxUseable) {
|
|
||||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.DamageReduction.Notifications.NotEnoughArmor'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isDecreasing = index < this.availableArmorMarks.selected;
|
const isDecreasing = index < this.availableArmorMarks.selected;
|
||||||
if (!isDecreasing && this.damage - this.availableArmorMarks.selected === 0) {
|
if (!isDecreasing && this.damage - this.availableArmorMarks.selected === 0) {
|
||||||
ui.notifications.info(game.i18n.localize('DAGGERHEART.DamageReduction.Notifications.DamageAlreadyNone'));
|
ui.notifications.info(game.i18n.localize('DAGGERHEART.DamageReduction.Notifications.DamageAlreadyNone'));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isDecreasing) {
|
||||||
|
const selectedStressReductions = Object.values(this.availableStressReductions).filter(red => red.selected);
|
||||||
|
const reducedDamage =
|
||||||
|
this.availableArmorMarks.selected > 0 || selectedStressReductions.length > 0
|
||||||
|
? getDamageLabel(this.damage - this.availableArmorMarks.selected - selectedStressReductions.length)
|
||||||
|
: null;
|
||||||
|
const currentDamage = reducedDamage ?? getDamageLabel(this.damage);
|
||||||
|
for (let reduction of selectedStressReductions) {
|
||||||
|
if (reduction.selected && reduction.to === currentDamage) {
|
||||||
|
reduction.selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.availableArmorMarks.selected = isDecreasing ? index : index + 1;
|
this.availableArmorMarks.selected = isDecreasing ? index : index + 1;
|
||||||
this.render();
|
this.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static useStressReduction(_, target) {
|
||||||
|
const damageValue = Number(target.dataset.reduction);
|
||||||
|
const stressReduction = this.availableStressReductions[damageValue];
|
||||||
|
if (stressReduction.selected) {
|
||||||
|
stressReduction.selected = false;
|
||||||
|
this.render();
|
||||||
|
} else {
|
||||||
|
const selectedStressReductions = Object.values(this.availableStressReductions).filter(red => red.selected);
|
||||||
|
const reducedDamage =
|
||||||
|
this.availableArmorMarks.selected > 0 || selectedStressReductions.length > 0
|
||||||
|
? getDamageLabel(this.damage - this.availableArmorMarks.selected - selectedStressReductions.length)
|
||||||
|
: null;
|
||||||
|
const currentDamage = reducedDamage ?? getDamageLabel(this.damage);
|
||||||
|
|
||||||
|
if (stressReduction.from !== currentDamage) return;
|
||||||
|
|
||||||
|
stressReduction.selected = true;
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static async takeDamage() {
|
static async takeDamage() {
|
||||||
const armorSpent = this.availableArmorMarks.selected;
|
const armorSpent = this.availableArmorMarks.selected;
|
||||||
const modifiedDamage = this.damage - armorSpent;
|
const modifiedDamage = this.damage - armorSpent;
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,12 @@ const resourceField = max =>
|
||||||
max: new foundry.data.fields.NumberField({ initial: max, integer: true })
|
max: new foundry.data.fields.NumberField({ initial: max, integer: true })
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const stressDamageReductionRule = () =>
|
||||||
|
new foundry.data.fields.SchemaField({
|
||||||
|
enabled: new foundry.data.fields.BooleanField({ required: true, initial: false }),
|
||||||
|
cost: new foundry.data.fields.NumberField({ integer: true })
|
||||||
|
});
|
||||||
|
|
||||||
export default class DhCharacter extends BaseDataActor {
|
export default class DhCharacter extends BaseDataActor {
|
||||||
static get metadata() {
|
static get metadata() {
|
||||||
return foundry.utils.mergeObject(super.metadata, {
|
return foundry.utils.mergeObject(super.metadata, {
|
||||||
|
|
@ -98,9 +104,9 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 })
|
stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 })
|
||||||
}),
|
}),
|
||||||
stressDamageReduction: new fields.SchemaField({
|
stressDamageReduction: new fields.SchemaField({
|
||||||
enabled: new fields.BooleanField({ required: true, initial: false }),
|
severe: stressDamageReductionRule(),
|
||||||
cost: new fields.NumberField({ integer: true }),
|
major: stressDamageReductionRule(),
|
||||||
fromSeverity: new fields.NumberField({ integer: true, max: 3 })
|
minor: stressDamageReductionRule()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -515,13 +515,24 @@ export default class DhpActor extends Actor {
|
||||||
) {
|
) {
|
||||||
new Promise((resolve, reject) => {
|
new Promise((resolve, reject) => {
|
||||||
new DamageReductionDialog(resolve, reject, this, hpDamage).render(true);
|
new DamageReductionDialog(resolve, reject, this, hpDamage).render(true);
|
||||||
}).then(async ({ modifiedDamage, armorSpent }) => {
|
})
|
||||||
const resources = [
|
.then(async ({ modifiedDamage, armorSpent }) => {
|
||||||
{ value: modifiedDamage, type: 'hitPoints' },
|
const resources = [
|
||||||
...(armorSpent ? [{ value: armorSpent, type: 'armorStack' }] : [])
|
{ value: modifiedDamage, type: 'hitPoints' },
|
||||||
];
|
...(armorSpent ? [{ value: armorSpent, type: 'armorStack' }] : [])
|
||||||
await this.modifyResource(resources);
|
];
|
||||||
});
|
await this.modifyResource(resources);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
const cls = getDocumentClass('ChatMessage');
|
||||||
|
const msg = new cls({
|
||||||
|
user: game.user.id,
|
||||||
|
content: game.i18n.format('DAGGERHEART.DamageReduction.Notifications.DamageIgnore', {
|
||||||
|
character: this.name
|
||||||
|
})
|
||||||
|
});
|
||||||
|
cls.create(msg.toObject());
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
await this.modifyResource([{ value: hpDamage, type: 'hitPoints' }]);
|
await this.modifyResource([{ value: hpDamage, type: 'hitPoints' }]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -248,3 +248,16 @@ export const getDamageLabel = damage => {
|
||||||
return game.i18n.localize('DAGGERHEART.General.Damage.None');
|
return game.i18n.localize('DAGGERHEART.General.Damage.None');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const damageKeyToNumber = key => {
|
||||||
|
switch (key) {
|
||||||
|
case 'severe':
|
||||||
|
return 3;
|
||||||
|
case 'major':
|
||||||
|
return 2;
|
||||||
|
case 'minor':
|
||||||
|
return 1;
|
||||||
|
case 'none':
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -3135,6 +3135,18 @@ div.daggerheart.views.multiclass {
|
||||||
}
|
}
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .armor-title {
|
.daggerheart.views.damage-reduction .damage-reduction-container .armor-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .resources-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .resources-container .resource-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection {
|
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -3148,7 +3160,7 @@ div.daggerheart.views.multiclass {
|
||||||
border: 1px solid light-dark(#18162e, #f3c267);
|
border: 1px solid light-dark(#18162e, #f3c267);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
width: 26px;
|
padding: 0 1px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -3158,8 +3170,38 @@ div.daggerheart.views.multiclass {
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-container.selected {
|
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-container.selected {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-container.disabled {
|
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-container .fa-shield {
|
||||||
cursor: initial;
|
position: relative;
|
||||||
|
right: 0.5px;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction {
|
||||||
|
border: 1px solid light-dark(#18162e, #f3c267);
|
||||||
|
border-radius: 6px;
|
||||||
|
height: 26px;
|
||||||
|
padding: 0 4px;
|
||||||
|
font-size: 18px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4px;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.active {
|
||||||
|
opacity: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction.selected {
|
||||||
|
opacity: 1;
|
||||||
|
background: var(--color-warm-2);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .stress-reduction-container .stress-reduction .stress-reduction-cost {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle {
|
.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle {
|
||||||
margin: -4px 0 0 0;
|
margin: -4px 0 0 0;
|
||||||
|
|
@ -3168,20 +3210,6 @@ div.daggerheart.views.multiclass {
|
||||||
font-variant: all-small-caps;
|
font-variant: all-small-caps;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .damage-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 4px;
|
|
||||||
font-weight: bold;
|
|
||||||
height: 18px;
|
|
||||||
}
|
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .damage-container i {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container .damage-container .reduced-value {
|
|
||||||
opacity: 0.4;
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container footer {
|
.daggerheart.views.damage-reduction .damage-reduction-container footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -3189,6 +3217,13 @@ div.daggerheart.views.multiclass {
|
||||||
.daggerheart.views.damage-reduction .damage-reduction-container footer button {
|
.daggerheart.views.damage-reduction .damage-reduction-container footer button {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container footer button .damage-value.reduced-value {
|
||||||
|
opacity: 0.4;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
:root {
|
:root {
|
||||||
--shadow-text-stroke: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
--shadow-text-stroke: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
||||||
--fear-animation: background 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease;
|
--fear-animation: background 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease;
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,20 @@
|
||||||
|
|
||||||
.armor-title {
|
.armor-title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.resources-container {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.resource-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mark-selection {
|
.mark-selection {
|
||||||
|
|
@ -33,10 +47,10 @@
|
||||||
|
|
||||||
.mark-container {
|
.mark-container {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid light-dark(#18162e, #f3c267);
|
border: 1px solid light-dark(@dark-blue, @golden);
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
width: 26px;
|
padding: 0 1px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
@ -47,8 +61,43 @@
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.disabled {
|
.fa-shield {
|
||||||
cursor: initial;
|
position: relative;
|
||||||
|
right: 0.5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stress-reduction-container {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.stress-reduction {
|
||||||
|
border: 1px solid light-dark(@dark-blue, @golden);
|
||||||
|
border-radius: 6px;
|
||||||
|
height: 26px;
|
||||||
|
padding: 0 4px;
|
||||||
|
font-size: 18px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4px;
|
||||||
|
opacity: 0.4;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
opacity: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
opacity: 1;
|
||||||
|
background: var(--color-warm-2);
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stress-reduction-cost {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -62,29 +111,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.damage-container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 4px;
|
|
||||||
font-weight: bold;
|
|
||||||
height: 18px;
|
|
||||||
|
|
||||||
i {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.reduced-value {
|
|
||||||
opacity: 0.4;
|
|
||||||
text-decoration: line-through;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
button {
|
button {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
|
.damage-value {
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&.reduced-value {
|
||||||
|
opacity: 0.4;
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,25 @@
|
||||||
<div class="damage-reduction-container">
|
<div class="damage-reduction-container">
|
||||||
<div class="section-container padded">
|
<div class="section-container padded">
|
||||||
<h4 class="armor-title">{{localize "DAGGERHEART.DamageReduction.ArmorMarks"}}</h4>
|
<div class="resources-container">
|
||||||
<div class="markers-subtitle">{{armorMarks}}/{{armorScore}}</div>
|
<div class="resource-container">
|
||||||
|
<h4 class="armor-title">{{localize "DAGGERHEART.DamageReduction.ArmorMarks"}}</h4>
|
||||||
|
<div class="markers-subtitle">{{armorMarks}}/{{armorScore}}</div>
|
||||||
|
</div>
|
||||||
|
{{#if this.stress}}
|
||||||
|
<div class="resource-container">
|
||||||
|
<h4 class="armor-title">{{localize "DAGGERHEART.DamageReduction.Stress"}}</h4>
|
||||||
|
<div class="markers-subtitle">{{this.stress.value}}/{{this.stress.maxTotal}}</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-container">
|
<div class="section-container">
|
||||||
<h4 class="mark-selection divider">
|
<h4 class="mark-selection divider">
|
||||||
{{#times availableArmorMarks.max}}
|
{{#times availableArmorMarks.max}}
|
||||||
<div
|
<div
|
||||||
class="mark-container {{#if (lt this @root.availableArmorMarks.selected)}}selected{{/if}} {{#if (gte this this.maxUseable)}}disabled{{/if}}"
|
class="mark-container {{#if (lt this @root.availableArmorMarks.selected)}}selected{{/if}}"
|
||||||
data-action="setMarks" data-index="{{this}}"
|
data-action="setMarks" data-index="{{this}}" {{#if (gte this @root.availableArmorMarks.stressIndex)}}data-tooltip="{{localize "DAGGERHEART.DamageReduction.ArmorWithStress"}}"{{/if}}
|
||||||
>
|
>
|
||||||
{{#if (or (not @root.availableArmorMarks.stressIndex) (lt this @root.availableArmorMarks.stressIndex))}}
|
{{#if (or (not @root.availableArmorMarks.stressIndex) (lt this @root.availableArmorMarks.stressIndex))}}
|
||||||
<i class="fa-solid fa-shield"></i>
|
<i class="fa-solid fa-shield"></i>
|
||||||
|
|
@ -23,18 +33,37 @@
|
||||||
<div class="markers-subtitle bold">{{localize "DAGGERHEART.DamageReduction.UsedMarks"}}</div>
|
<div class="markers-subtitle bold">{{localize "DAGGERHEART.DamageReduction.UsedMarks"}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="section-container">
|
<div class="resources-container">
|
||||||
<div>{{localize "Incoming Damage"}}</div>
|
<div class="resource-container">
|
||||||
<div class="damage-container">
|
<h4 class="armor-title">{{localize "DAGGERHEART.DamageReduction.StressReduction"}}</h4>
|
||||||
<div class="{{#if this.reducedDamage}}reduced-value{{/if}}">{{this.damage}}</div>
|
|
||||||
{{#if this.reducedDamage}}
|
|
||||||
<i class="fa-solid fa-arrow-right-long"></i>
|
|
||||||
<div>{{this.reducedDamage}}</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{#each availableStressReductions}}
|
||||||
|
<div class="section-container">
|
||||||
|
<h4 class="stress-reduction-container divider">
|
||||||
|
<div class="stress-reduction {{#if (eq this.from @root.currentDamage)}}active{{/if}} {{#if this.selected}}selected{{/if}}" data-action="useStressReduction" data-reduction="{{@key}}">
|
||||||
|
{{this.from}}
|
||||||
|
<i class="fa-solid fa-arrow-right-long"></i>
|
||||||
|
{{this.to}}
|
||||||
|
<div class="stress-reduction-cost">
|
||||||
|
{{this.cost}}
|
||||||
|
<i class="fa-solid fa-bolt"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</h4>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
<footer class="padded">
|
<footer class="padded">
|
||||||
<button type="button" data-action="takeDamage">{{localize "Take Damage"}}</button>
|
<button type="button" data-action="takeDamage">
|
||||||
|
{{localize "Take"}}
|
||||||
|
<div class="damage-value {{#if this.reducedDamage}}reduced-value{{/if}}">{{this.damage}}</div>
|
||||||
|
{{#if this.reducedDamage}}
|
||||||
|
<i class="fa-solid fa-arrow-right-long"></i>
|
||||||
|
<div class="damage-value">{{this.reducedDamage}}</div>
|
||||||
|
{{/if}}
|
||||||
|
{{localize "Damage"}}
|
||||||
|
</button>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue