mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-16 05:31:07 +01:00
Temp
This commit is contained in:
parent
0d60cd90b6
commit
c952580f6b
10 changed files with 418 additions and 56 deletions
16
lang/en.json
16
lang/en.json
|
|
@ -207,6 +207,12 @@
|
||||||
"Session": "Session",
|
"Session": "Session",
|
||||||
"Shortrest": "Short Rest",
|
"Shortrest": "Short Rest",
|
||||||
"Longrest": "Long Rest"
|
"Longrest": "Long Rest"
|
||||||
|
},
|
||||||
|
"Damage": {
|
||||||
|
"Severe": "Severe",
|
||||||
|
"Major": "Major",
|
||||||
|
"Minor": "Minor",
|
||||||
|
"None": "None"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"ActionType": {
|
"ActionType": {
|
||||||
|
|
@ -1084,6 +1090,16 @@
|
||||||
"Title": "Ownership Selection - {name}",
|
"Title": "Ownership Selection - {name}",
|
||||||
"Default": "Default Ownership"
|
"Default": "Default Ownership"
|
||||||
},
|
},
|
||||||
|
"DamageReduction": {
|
||||||
|
"Title": "Damage Reduction",
|
||||||
|
"ArmorMarks": "Armor Marks",
|
||||||
|
"UsedMarks": "Used Marks",
|
||||||
|
"Stress": "Stress",
|
||||||
|
"Notifications": {
|
||||||
|
"DamageAlreadyNone": "The damage has already been reduced to none",
|
||||||
|
"NotEnoughArmor": "You don't have enough unspent armor marks"
|
||||||
|
}
|
||||||
|
},
|
||||||
"Sheets": {
|
"Sheets": {
|
||||||
"PC": {
|
"PC": {
|
||||||
"Name": "Name",
|
"Name": "Name",
|
||||||
|
|
|
||||||
112
module/applications/damageReductionDialog.mjs
Normal file
112
module/applications/damageReductionDialog.mjs
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
import { getDamageLabel } from '../helpers/utils.mjs';
|
||||||
|
|
||||||
|
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
|
||||||
|
|
||||||
|
export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||||
|
constructor(resolve, reject, actor, damage) {
|
||||||
|
super({});
|
||||||
|
|
||||||
|
this.resolve = resolve;
|
||||||
|
this.reject = reject;
|
||||||
|
this.actor = actor;
|
||||||
|
this.damage = damage;
|
||||||
|
|
||||||
|
this.availableArmorMarks = {
|
||||||
|
max: actor.system.rules.maxArmorMarked.total + (actor.system.rules.stressExtra ?? 0),
|
||||||
|
maxUseable: actor.system.armorScore - actor.system.armor.system.marks.value,
|
||||||
|
stressIndex:
|
||||||
|
(actor.system.rules.stressExtra ?? 0) > 0 ? actor.system.rules.maxArmorMarked.total : undefined,
|
||||||
|
selected: 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return game.i18n.localize('DAGGERHEART.DamageReduction.Title');
|
||||||
|
}
|
||||||
|
|
||||||
|
static DEFAULT_OPTIONS = {
|
||||||
|
tag: 'form',
|
||||||
|
classes: ['daggerheart', 'views', 'damage-reduction'],
|
||||||
|
position: {
|
||||||
|
width: 240,
|
||||||
|
height: 'auto'
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setMarks: this.setMarks,
|
||||||
|
takeDamage: this.takeDamage
|
||||||
|
},
|
||||||
|
form: {
|
||||||
|
handler: this.updateData,
|
||||||
|
submitOnChange: true,
|
||||||
|
closeOnSubmit: false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @override */
|
||||||
|
static PARTS = {
|
||||||
|
damageSelection: {
|
||||||
|
id: 'damageReduction',
|
||||||
|
template: 'systems/daggerheart/templates/views/damageReduction.hbs'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* -------------------------------------------- */
|
||||||
|
|
||||||
|
/** @inheritDoc */
|
||||||
|
get title() {
|
||||||
|
return `Damage Options`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async _prepareContext(_options) {
|
||||||
|
const context = await super._prepareContext(_options);
|
||||||
|
context.armorScore = this.actor.system.armorScore;
|
||||||
|
context.armorMarks = this.actor.system.armor.system.marks.value + this.availableArmorMarks.selected;
|
||||||
|
context.availableArmorMarks = this.availableArmorMarks;
|
||||||
|
|
||||||
|
context.damage = getDamageLabel(this.damage);
|
||||||
|
context.reducedDamage =
|
||||||
|
this.availableArmorMarks.selected > 0
|
||||||
|
? getDamageLabel(this.damage - this.availableArmorMarks.selected)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static updateData(event, _, formData) {
|
||||||
|
const form = foundry.utils.expandObject(formData.object);
|
||||||
|
this.render(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static setMarks(_, target) {
|
||||||
|
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;
|
||||||
|
if (!isDecreasing && this.damage - this.availableArmorMarks.selected === 0) {
|
||||||
|
ui.notifications.info(game.i18n.localize('DAGGERHEART.DamageReduction.Notifications.DamageAlreadyNone'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.availableArmorMarks.selected = isDecreasing ? index : index + 1;
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
static async takeDamage() {
|
||||||
|
const armorSpent = this.availableArmorMarks.selected;
|
||||||
|
const modifiedDamage = this.damage - armorSpent;
|
||||||
|
|
||||||
|
this.resolve({ modifiedDamage, armorSpent });
|
||||||
|
await this.close(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async close(fromSave) {
|
||||||
|
if (!fromSave) {
|
||||||
|
this.reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
await super.close({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -83,6 +83,18 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
attack: new fields.NumberField({ integer: true, initial: 0 }),
|
attack: new fields.NumberField({ integer: true, initial: 0 }),
|
||||||
spellcast: new fields.NumberField({ integer: true, initial: 0 }),
|
spellcast: new fields.NumberField({ integer: true, initial: 0 }),
|
||||||
armorScore: new fields.NumberField({ integer: true, initial: 0 })
|
armorScore: new fields.NumberField({ integer: true, initial: 0 })
|
||||||
|
}),
|
||||||
|
rules: new fields.SchemaField({
|
||||||
|
maxArmorMarked: new fields.SchemaField({
|
||||||
|
value: new fields.NumberField({ required: true, integer: true, initial: 1 }),
|
||||||
|
bonus: new fields.NumberField({ required: true, integer: true, initial: 0 }),
|
||||||
|
stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 })
|
||||||
|
}),
|
||||||
|
stressDamageReduction: new fields.SchemaField({
|
||||||
|
enabled: new fields.BooleanField({ required: true, initial: false }),
|
||||||
|
cost: new fields.NumberField({ integer: true }),
|
||||||
|
fromSeverity: new fields.NumberField({ integer: true, max: 3 })
|
||||||
|
})
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -232,6 +244,9 @@ export default class DhCharacter extends BaseDataActor {
|
||||||
experience.total = experience.value + experience.bonus;
|
experience.total = experience.value + experience.bonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.rules.maxArmorMarked.total = this.rules.maxArmorMarked.value + this.rules.maxArmorMarked.bonus;
|
||||||
|
|
||||||
|
this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0;
|
||||||
this.resources.hitPoints.maxTotal = this.resources.hitPoints.max + this.resources.hitPoints.bonus;
|
this.resources.hitPoints.maxTotal = this.resources.hitPoints.max + this.resources.hitPoints.bonus;
|
||||||
this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus;
|
this.resources.stress.maxTotal = this.resources.stress.max + this.resources.stress.bonus;
|
||||||
this.evasion.total = (this.class?.evasion ?? 0) + this.evasion.bonus;
|
this.evasion.total = (this.class?.evasion ?? 0) + this.evasion.bonus;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ export default class DHArmor extends BaseDataItem {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
marks: new fields.SchemaField({
|
marks: new fields.SchemaField({
|
||||||
max: new fields.NumberField({ initial: 6, integer: true }),
|
|
||||||
value: new fields.NumberField({ initial: 0, integer: true })
|
value: new fields.NumberField({ initial: 0, integer: true })
|
||||||
}),
|
}),
|
||||||
baseThresholds: new fields.SchemaField({
|
baseThresholds: new fields.SchemaField({
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import RollSelectionDialog from '../applications/rollSelectionDialog.mjs';
|
||||||
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
|
import { GMUpdateEvent, socketEvent } from '../helpers/socket.mjs';
|
||||||
import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
|
||||||
import DHDualityRoll from '../data/chat-message/dualityRoll.mjs';
|
import DHDualityRoll from '../data/chat-message/dualityRoll.mjs';
|
||||||
|
import DamageReductionDialog from '../applications/damageReductionDialog.mjs';
|
||||||
|
|
||||||
export default class DhpActor extends Actor {
|
export default class DhpActor extends Actor {
|
||||||
async _preCreate(data, options, user) {
|
async _preCreate(data, options, user) {
|
||||||
|
|
@ -266,21 +267,21 @@ export default class DhpActor extends Actor {
|
||||||
*/
|
*/
|
||||||
async diceRoll(config, action) {
|
async diceRoll(config, action) {
|
||||||
// console.log(config)
|
// console.log(config)
|
||||||
config.source = {...(config.source ?? {}), actor: this.id};
|
config.source = { ...(config.source ?? {}), actor: this.id };
|
||||||
const newConfig = {
|
const newConfig = {
|
||||||
// data: {
|
// data: {
|
||||||
...config,
|
...config,
|
||||||
/* action, */
|
/* action, */
|
||||||
// actor: this.getRollData(),
|
// actor: this.getRollData(),
|
||||||
actor: this.system
|
actor: this.system
|
||||||
// },
|
// },
|
||||||
// options: {
|
// options: {
|
||||||
// dialog: false,
|
// dialog: false,
|
||||||
// },
|
// },
|
||||||
// event: config.event
|
// event: config.event
|
||||||
}
|
};
|
||||||
// console.log(this, newConfig)
|
// console.log(this, newConfig)
|
||||||
const roll = CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(newConfig)
|
const roll = CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(newConfig);
|
||||||
return config;
|
return config;
|
||||||
/* let hopeDice = 'd12',
|
/* let hopeDice = 'd12',
|
||||||
fearDice = 'd12',
|
fearDice = 'd12',
|
||||||
|
|
@ -508,67 +509,67 @@ export default class DhpActor extends Actor {
|
||||||
async takeDamage(damage, type) {
|
async takeDamage(damage, type) {
|
||||||
const hpDamage =
|
const hpDamage =
|
||||||
damage >= this.system.damageThresholds.severe
|
damage >= this.system.damageThresholds.severe
|
||||||
? -3
|
? 3
|
||||||
: damage >= this.system.damageThresholds.major
|
: damage >= this.system.damageThresholds.major
|
||||||
? -2
|
? 2
|
||||||
: damage >= this.system.damageThresholds.minor
|
: damage >= this.system.damageThresholds.minor
|
||||||
? -1
|
? 1
|
||||||
: 0;
|
: 0;
|
||||||
await this.modifyResource([{value: hpDamage, type}]);
|
|
||||||
/* const update = {
|
|
||||||
'system.resources.hitPoints.value': Math.min(
|
|
||||||
this.system.resources.hitPoints.value + hpDamage,
|
|
||||||
this.system.resources.hitPoints.max
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
if (game.user.isGM) {
|
if (
|
||||||
await this.update(update);
|
this.type === 'character' &&
|
||||||
} else {
|
this.system.armor &&
|
||||||
await game.socket.emit(`system.${SYSTEM.id}`, {
|
this.system.armor.system.marks.value < this.system.armorScore
|
||||||
action: socketEvent.GMUpdate,
|
) {
|
||||||
data: {
|
new Promise((resolve, reject) => {
|
||||||
action: GMUpdateEvent.UpdateDocument,
|
new DamageReductionDialog(resolve, reject, this, hpDamage).render(true);
|
||||||
uuid: this.uuid,
|
}).then(async ({ modifiedDamage, armorSpent }) => {
|
||||||
update: update
|
const resources = [
|
||||||
}
|
{ value: modifiedDamage, type: 'hitPoints' },
|
||||||
|
...(armorSpent ? [{ value: armorSpent, type: 'armorStack' }] : [])
|
||||||
|
];
|
||||||
|
await this.modifyResource(resources);
|
||||||
});
|
});
|
||||||
} */
|
} else {
|
||||||
|
await this.modifyResource([{ value: hpDamage, type: 'hitPoints' }]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async modifyResource(resources) {
|
async modifyResource(resources) {
|
||||||
if(!resources.length) return;
|
if (!resources.length) return;
|
||||||
let updates = { actor: { target: this, resources: {} }, armor: { target: this.armor, resources: {} } };
|
let updates = { actor: { target: this, resources: {} }, armor: { target: this.system.armor, resources: {} } };
|
||||||
resources.forEach(r => {
|
resources.forEach(r => {
|
||||||
switch (type) {
|
switch (r.type) {
|
||||||
case 'armorStrack':
|
case 'armorStack':
|
||||||
// resource = 'system.stacks.value';
|
updates.armor.resources['system.marks.value'] = Math.min(
|
||||||
// target = this.armor;
|
this.system.armor.system.marks.value + r.value,
|
||||||
// update = Math.min(this.marks.value + value, this.marks.max);
|
this.system.armorScore
|
||||||
updates.armor.resources['system.stacks.value'] = Math.min(this.marks.value + value, this.marks.max);
|
);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// resource = `system.resources.${type}`;
|
updates.actor.resources[`system.resources.${r.type}.value`] = Math.min(
|
||||||
// target = this;
|
this.system.resources[r.type].value + r.value,
|
||||||
// update = Math.min(this.resources[type].value + value, this.resources[type].max);
|
this.system.resources[r.type].max
|
||||||
updates.armor.resources[`system.resources.${type}`] = Math.min(this.resources[type].value + value, this.resources[type].max);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
Object.values(updates).forEach(async (u) => {
|
Object.values(updates).forEach(async u => {
|
||||||
if (game.user.isGM) {
|
if (Object.keys(u.resources).length > 0) {
|
||||||
await u.target.update(u.resources);
|
if (game.user.isGM) {
|
||||||
} else {
|
await u.target.update(u.resources);
|
||||||
await game.socket.emit(`system.${SYSTEM.id}`, {
|
} else {
|
||||||
action: socketEvent.GMUpdate,
|
await game.socket.emit(`system.${SYSTEM.id}`, {
|
||||||
data: {
|
action: socketEvent.GMUpdate,
|
||||||
action: GMUpdateEvent.UpdateDocument,
|
data: {
|
||||||
uuid: u.target.uuid,
|
action: GMUpdateEvent.UpdateDocument,
|
||||||
update: u.resources
|
uuid: u.target.uuid,
|
||||||
}
|
update: u.resources
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* async takeHealing(healing, type) {
|
/* async takeHealing(healing, type) {
|
||||||
|
|
|
||||||
|
|
@ -235,3 +235,16 @@ Roll.replaceFormulaData = function (formula, data, { missing, warn = false } = {
|
||||||
formula = terms.reduce((a, c) => a.replaceAll(`@${c.term}`, data[c.term] ?? c.default), formula);
|
formula = terms.reduce((a, c) => a.replaceAll(`@${c.term}`, data[c.term] ?? c.default), formula);
|
||||||
return nativeReplaceFormulaData(formula, data, { missing, warn });
|
return nativeReplaceFormulaData(formula, data, { missing, warn });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getDamageLabel = damage => {
|
||||||
|
switch (damage) {
|
||||||
|
case 3:
|
||||||
|
return game.i18n.localize('DAGGERHEART.General.Damage.Severe');
|
||||||
|
case 2:
|
||||||
|
return game.i18n.localize('DAGGERHEART.General.Damage.Major');
|
||||||
|
case 1:
|
||||||
|
return game.i18n.localize('DAGGERHEART.General.Damage.Minor');
|
||||||
|
case 0:
|
||||||
|
return game.i18n.localize('DAGGERHEART.General.Damage.None');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
|
||||||
|
|
@ -3113,6 +3113,80 @@ div.daggerheart.views.multiclass {
|
||||||
.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container select {
|
.daggerheart.views.ownership-selection .ownership-outer-container .ownership-container select {
|
||||||
margin: 4px 0;
|
margin: 4px 0;
|
||||||
}
|
}
|
||||||
|
.daggerheart.views.damage-reduction .window-content {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .section-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .padded {
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .armor-title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-container {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid light-dark(#18162e, #f3c267);
|
||||||
|
border-radius: 6px;
|
||||||
|
height: 26px;
|
||||||
|
width: 26px;
|
||||||
|
font-size: 18px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-container.selected {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .mark-selection .mark-container.disabled {
|
||||||
|
cursor: initial;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle {
|
||||||
|
margin: -4px 0 0 0;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container .markers-subtitle.bold {
|
||||||
|
font-variant: all-small-caps;
|
||||||
|
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 {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.daggerheart.views.damage-reduction .damage-reduction-container footer button {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
: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;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
@import './characterCreation.less';
|
@import './characterCreation.less';
|
||||||
@import './levelup.less';
|
@import './levelup.less';
|
||||||
@import './ownershipSelection.less';
|
@import './ownershipSelection.less';
|
||||||
|
@import './damageReduction.less';
|
||||||
@import './resources.less';
|
@import './resources.less';
|
||||||
@import './countdown.less';
|
@import './countdown.less';
|
||||||
@import './settings.less';
|
@import './settings.less';
|
||||||
|
|
|
||||||
91
styles/damageReduction.less
Normal file
91
styles/damageReduction.less
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
.daggerheart.views.damage-reduction {
|
||||||
|
.window-content {
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.damage-reduction-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
|
||||||
|
.section-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.padded {
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.armor-title {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mark-selection {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
.mark-container {
|
||||||
|
cursor: pointer;
|
||||||
|
border: 1px solid light-dark(#18162e, #f3c267);
|
||||||
|
border-radius: 6px;
|
||||||
|
height: 26px;
|
||||||
|
width: 26px;
|
||||||
|
font-size: 18px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
opacity: 0.4;
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.markers-subtitle {
|
||||||
|
margin: -4px 0 0 0;
|
||||||
|
|
||||||
|
&.bold {
|
||||||
|
font-variant: all-small-caps;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.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 {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
button {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
templates/views/damageReduction.hbs
Normal file
40
templates/views/damageReduction.hbs
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
<div class="damage-reduction-container">
|
||||||
|
<div class="section-container padded">
|
||||||
|
<h4 class="armor-title">{{localize "DAGGERHEART.DamageReduction.ArmorMarks"}}</h4>
|
||||||
|
<div class="markers-subtitle">{{armorMarks}}/{{armorScore}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section-container">
|
||||||
|
<h4 class="mark-selection divider">
|
||||||
|
{{#times availableArmorMarks.max}}
|
||||||
|
<div
|
||||||
|
class="mark-container {{#if (lt this @root.availableArmorMarks.selected)}}selected{{/if}} {{#if (gte this this.maxUseable)}}disabled{{/if}}"
|
||||||
|
data-action="setMarks" data-index="{{this}}"
|
||||||
|
>
|
||||||
|
{{#if (or (not @root.availableArmorMarks.stressIndex) (lt this @root.availableArmorMarks.stressIndex))}}
|
||||||
|
<i class="fa-solid fa-shield"></i>
|
||||||
|
{{else}}
|
||||||
|
<i class="fa-solid fa-bolt"></i>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
</div>
|
||||||
|
{{/times}}
|
||||||
|
</h4>
|
||||||
|
<div class="markers-subtitle bold">{{localize "DAGGERHEART.DamageReduction.UsedMarks"}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section-container">
|
||||||
|
<div>{{localize "Incoming Damage"}}</div>
|
||||||
|
<div class="damage-container">
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<footer class="padded">
|
||||||
|
<button type="button" data-action="takeDamage">{{localize "Take Damage"}}</button>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue