284 - Armor/Weapon Feature Improvements (#292)

* Added parsing of effect values from Item data model. Almost finished with itemConfig.

* Added the last to itemConfig

* Fixed armor

* ContextMenu localization fixes

* Better tooltips for tagify

* Corrected resource logic
This commit is contained in:
WBHarry 2025-07-09 13:06:49 +02:00 committed by GitHub
parent eae4f12910
commit b3e7c6b9b2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
51 changed files with 3043 additions and 2310 deletions

View file

@ -486,14 +486,10 @@
"name": "Impenetrable", "name": "Impenetrable",
"description": "Once per short rest, when you would mark your last Hit Point, you can instead mark a Stress." "description": "Once per short rest, when you would mark your last Hit Point, you can instead mark a Stress."
}, },
"magic": { "magical": {
"name": "Magic", "name": "Magical",
"description": "You can't mark an Armor Slot to reduce physical damage." "description": "You can't mark an Armor Slot to reduce physical damage."
}, },
"painful": {
"name": "Painful",
"description": "Each time you mark an Armor Slot, you must mark a Stress."
},
"physical": { "physical": {
"name": "Physical", "name": "Physical",
"description": "You can't mark an Armor Slot to reduce magic damage." "description": "You can't mark an Armor Slot to reduce magic damage."
@ -897,6 +893,10 @@
"name": "Scary", "name": "Scary",
"description": "On a successful attack, the target must mark a Stress." "description": "On a successful attack, the target must mark a Stress."
}, },
"selfCorrecting": {
"name": "Self Correcting",
"description": "When you roll a 1 on a damage die, it deals 6 damage instead."
},
"serrated": { "serrated": {
"name": "Serrated", "name": "Serrated",
"description": "When you roll a 1 on a damage die, it deals 8 damage instead." "description": "When you roll a 1 on a damage die, it deals 8 damage instead."

View file

@ -3,7 +3,7 @@ import { damageKeyToNumber, getDamageLabel } from '../../helpers/utils.mjs';
const { DialogV2, ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api; const { DialogV2, ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) { export default class DamageReductionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
constructor(resolve, reject, actor, damage) { constructor(resolve, reject, actor, damage, damageType) {
super({}); super({});
this.resolve = resolve; this.resolve = resolve;
@ -11,37 +11,46 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
this.actor = actor; this.actor = actor;
this.damage = damage; this.damage = damage;
const maxArmorMarks = Math.min( const canApplyArmor = actor.system.armorApplicableDamageTypes[damageType];
actor.system.armorScore - actor.system.armor.system.marks.value, const maxArmorMarks = canApplyArmor
actor.system.rules.maxArmorMarked.total ? Math.min(
); actor.system.armorScore - actor.system.armor.system.marks.value,
actor.system.rules.damageReduction.maxArmorMarked.total
)
: 0;
const armor = [...Array(maxArmorMarks).keys()].reduce((acc, _) => { const armor = [...Array(maxArmorMarks).keys()].reduce((acc, _) => {
acc[foundry.utils.randomID()] = { selected: false }; acc[foundry.utils.randomID()] = { selected: false };
return acc; return acc;
}, {}); }, {});
const stress = [...Array(actor.system.rules.maxArmorMarked.stressExtra ?? 0).keys()].reduce((acc, _) => { const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce(
acc[foundry.utils.randomID()] = { selected: false }; (acc, _) => {
return acc; acc[foundry.utils.randomID()] = { selected: false };
}, {}); return acc;
},
{}
);
this.marks = { armor, stress }; this.marks = { armor, stress };
this.availableStressReductions = Object.keys(actor.system.rules.stressDamageReduction).reduce((acc, key) => { this.availableStressReductions = Object.keys(actor.system.rules.damageReduction.stressDamageReduction).reduce(
const dr = actor.system.rules.stressDamageReduction[key]; (acc, key) => {
if (dr.enabled) { const dr = actor.system.rules.damageReduction.stressDamageReduction[key];
if (acc === null) acc = {}; if (dr.enabled) {
if (acc === null) acc = {};
const damage = damageKeyToNumber(key); const damage = damageKeyToNumber(key);
acc[damage] = { acc[damage] = {
cost: dr.cost, cost: dr.cost,
selected: false, selected: false,
from: getDamageLabel(damage), from: getDamageLabel(damage),
to: getDamageLabel(damage - 1) to: getDamageLabel(damage - 1)
}; };
} }
return acc; return acc;
}, null); },
null
);
} }
get title() { get title() {
@ -90,7 +99,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
context.armorScore = this.actor.system.armorScore; context.armorScore = this.actor.system.armorScore;
context.armorMarks = currentMarks; context.armorMarks = currentMarks;
context.basicMarksUsed = selectedArmorMarks.length === this.actor.system.rules.maxArmorMarked.total; context.basicMarksUsed =
selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.total;
const stressReductionStress = this.availableStressReductions const stressReductionStress = this.availableStressReductions
? stressReductions.reduce((acc, red) => acc + red.cost, 0) ? stressReductions.reduce((acc, red) => acc + red.cost, 0)
@ -122,12 +132,15 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
getDamageInfo = () => { getDamageInfo = () => {
const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected); const selectedArmorMarks = Object.values(this.marks.armor).filter(x => x.selected);
const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected); const selectedStressMarks = Object.values(this.marks.stress).filter(x => x.selected);
const stressReductions = Object.values(this.availableStressReductions ?? {}).filter(red => red.selected); const stressReductions = this.availableStressReductions
? Object.values(this.availableStressReductions).filter(red => red.selected)
: [];
const currentMarks = const currentMarks =
this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length; this.actor.system.armor.system.marks.value + selectedArmorMarks.length + selectedStressMarks.length;
const currentDamage = const armorMarkReduction =
this.damage - selectedArmorMarks.length - selectedStressMarks.length - stressReductions.length; selectedArmorMarks.length * this.actor.system.rules.damageReduction.increasePerArmorMark;
const currentDamage = this.damage - armorMarkReduction - selectedStressMarks.length - stressReductions.length;
return { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage }; return { selectedArmorMarks, selectedStressMarks, stressReductions, currentMarks, currentDamage };
}; };
@ -216,11 +229,11 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
await super.close({}); await super.close({});
} }
static async armorStackQuery({actorId, damage}) { static async armorStackQuery({ actorId, damage, type }) {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
const actor = await fromUuid(actorId); const actor = await fromUuid(actorId);
if(!actor || !actor?.isOwner) reject(); if (!actor || !actor?.isOwner) reject();
new DamageReductionDialog(resolve, reject, actor, damage).render({ force: true }); new DamageReductionDialog(resolve, reject, actor, damage, type).render({ force: true });
}) });
} }
} }

View file

@ -35,7 +35,7 @@ export default class ArmorSheet extends DHBaseItemSheet {
switch (partId) { switch (partId) {
case 'settings': case 'settings':
context.features = this.document.system.features.map(x => x.value); context.features = this.document.system.armorFeatures.map(x => x.value);
break; break;
} }
@ -47,6 +47,6 @@ export default class ArmorSheet extends DHBaseItemSheet {
* @param {Array<Object>} selectedOptions - The currently selected tag objects. * @param {Array<Object>} selectedOptions - The currently selected tag objects.
*/ */
static async #onFeatureSelect(selectedOptions) { static async #onFeatureSelect(selectedOptions) {
await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) }); await this.document.update({ 'system.armorFeatures': selectedOptions.map(x => ({ value: x.value })) });
} }
} }

View file

@ -33,7 +33,7 @@ export default class WeaponSheet extends DHBaseItemSheet {
super._preparePartContext(partId, context); super._preparePartContext(partId, context);
switch (partId) { switch (partId) {
case 'settings': case 'settings':
context.features = this.document.system.features.map(x => x.value); context.features = this.document.system.weaponFeatures.map(x => x.value);
context.systemFields.attack.fields = this.document.system.attack.schema.fields; context.systemFields.attack.fields = this.document.system.attack.schema.fields;
break; break;
} }
@ -45,6 +45,6 @@ export default class WeaponSheet extends DHBaseItemSheet {
* @param {Array<Object>} selectedOptions - The currently selected tag objects. * @param {Array<Object>} selectedOptions - The currently selected tag objects.
*/ */
static async #onFeatureSelect(selectedOptions) { static async #onFeatureSelect(selectedOptions) {
await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) }); await this.document.update({ 'system.weaponFeatures': selectedOptions.map(x => ({ value: x.value })) });
} }
} }

View file

@ -80,8 +80,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
actor.system.attack?._id === actionId actor.system.attack?._id === actionId
? actor.system.attack ? actor.system.attack
: item.system.attack?._id === actionId : item.system.attack?._id === actionId
? item.system.attack ? item.system.attack
: item?.system?.actions?.find(a => a._id === actionId); : item?.system?.actions?.find(a => a._id === actionId);
return action; return action;
} }

View file

@ -59,13 +59,13 @@ export const damageTypes = {
id: 'physical', id: 'physical',
label: 'DAGGERHEART.CONFIG.DamageType.physical.name', label: 'DAGGERHEART.CONFIG.DamageType.physical.name',
abbreviation: 'DAGGERHEART.CONFIG.DamageType.physical.abbreviation', abbreviation: 'DAGGERHEART.CONFIG.DamageType.physical.abbreviation',
icon: ["fa-hand-fist"] icon: ['fa-hand-fist']
}, },
magical: { magical: {
id: 'magical', id: 'magical',
label: 'DAGGERHEART.CONFIG.DamageType.magical.name', label: 'DAGGERHEART.CONFIG.DamageType.magical.name',
abbreviation: 'DAGGERHEART.CONFIG.DamageType.magical.abbreviation', abbreviation: 'DAGGERHEART.CONFIG.DamageType.magical.abbreviation',
icon: ["fa-wand-sparkles"] icon: ['fa-wand-sparkles']
} }
}; };

File diff suppressed because it is too large Load diff

View file

@ -14,12 +14,12 @@ export default class DHAttackAction extends DHDamageAction {
prepareData() { prepareData() {
super.prepareData(); super.prepareData();
if(!!this.item?.system?.attack) { if (!!this.item?.system?.attack) {
if (this.damage.includeBase) { if (this.damage.includeBase) {
const baseDamage = this.getParentDamage(); const baseDamage = this.getParentDamage();
this.damage.parts.unshift(new DHDamageData(baseDamage)); this.damage.parts.unshift(new DHDamageData(baseDamage));
} }
if(this.roll.useDefault) { if (this.roll.useDefault) {
this.roll.trait = this.item.system.attack.roll.trait; this.roll.trait = this.item.system.attack.roll.trait;
this.roll.type = 'weapon'; this.roll.type = 'weapon';
} }

View file

@ -161,7 +161,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
updateSource['range'] = parent?.system?.attack?.range; updateSource['range'] = parent?.system?.attack?.range;
updateSource['roll'] = { updateSource['roll'] = {
useDefault: true useDefault: true
} };
} else { } else {
if (parent?.system?.trait) { if (parent?.system?.trait) {
updateSource['roll'] = { updateSource['roll'] = {
@ -295,7 +295,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
} }
prepareTarget() { prepareTarget() {
if(!this.target?.type) return []; if (!this.target?.type) return [];
let targets; let targets;
if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id) if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id)
targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken); targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken);
@ -337,7 +337,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
const resources = config.costs const resources = config.costs
.filter(c => c.enabled !== false) .filter(c => c.enabled !== false)
.map(c => { .map(c => {
return { type: c.type, value: (c.total ?? c.value) * -1 }; const resource = this.actor.system.resources[c.type];
return { type: c.type, value: (c.total ?? c.value) * (resource.hasOwnProperty('maxTotal') ? 1 : -1) };
}); });
await this.actor.modifyResource(resources); await this.actor.modifyResource(resources);
@ -382,15 +383,21 @@ export default class DHBaseAction extends foundry.abstract.DataModel {
const realCosts = this.getRealCosts(costs), const realCosts = this.getRealCosts(costs),
hasFearCost = realCosts.findIndex(c => c.type === 'fear'); hasFearCost = realCosts.findIndex(c => c.type === 'fear');
if (hasFearCost > -1) { if (hasFearCost > -1) {
const fearCost = realCosts.splice(hasFearCost, 1); const fearCost = realCosts.splice(hasFearCost, 1)[0];
if ( if (
!game.user.isGM || !game.user.isGM ||
fearCost[0].total > game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear) fearCost.total > game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear)
) )
return false; return false;
} }
/* maxTotal is a sign that the resource is inverted, IE it counts upwards instead of down */
const resources = this.actor.system.resources;
return realCosts.reduce( return realCosts.reduce(
(a, c) => a && this.actor.system.resources[c.type]?.value >= (c.total ?? c.value), (a, c) =>
a && resources[c.type].hasOwnProperty('maxTotal')
? resources[c.type].value + (c.total ?? c.value) <= resources[c.type].maxTotal
: resources[c.type]?.value >= (c.total ?? c.value),
true true
); );
} }

View file

@ -100,12 +100,19 @@ export default class DhCharacter extends BaseDataActor {
levelData: new fields.EmbeddedDataField(DhLevelData), levelData: new fields.EmbeddedDataField(DhLevelData),
bonuses: new fields.SchemaField({ bonuses: new fields.SchemaField({
armorScore: new fields.NumberField({ integer: true, initial: 0 }), armorScore: new fields.NumberField({ integer: true, initial: 0 }),
damageReduction: new fields.SchemaField({
physical: new fields.NumberField({ integer: true, initial: 0 }),
magical: new fields.NumberField({ integer: true, initial: 0 })
}),
damageThresholds: new fields.SchemaField({ damageThresholds: new fields.SchemaField({
severe: new fields.NumberField({ integer: true, initial: 0 }), severe: new fields.NumberField({ integer: true, initial: 0 }),
major: new fields.NumberField({ integer: true, initial: 0 }) major: new fields.NumberField({ integer: true, initial: 0 })
}), }),
roll: new fields.SchemaField({ roll: new fields.SchemaField({
attack: new fields.NumberField({ integer: true, initial: 0 }), attack: new fields.NumberField({ integer: true, initial: 0 }),
primaryWeapon: new fields.SchemaField({
attack: new fields.NumberField({ integer: true, initial: 0 })
}),
spellcast: new fields.NumberField({ integer: true, initial: 0 }), spellcast: new fields.NumberField({ integer: true, initial: 0 }),
action: new fields.NumberField({ integer: true, initial: 0 }), action: new fields.NumberField({ integer: true, initial: 0 }),
hopeOrFear: new fields.NumberField({ integer: true, initial: 0 }) hopeOrFear: new fields.NumberField({ integer: true, initial: 0 })
@ -113,20 +120,29 @@ export default class DhCharacter extends BaseDataActor {
damage: new fields.SchemaField({ damage: new fields.SchemaField({
all: new fields.NumberField({ integer: true, initial: 0 }), all: new fields.NumberField({ integer: true, initial: 0 }),
physical: new fields.NumberField({ integer: true, initial: 0 }), physical: new fields.NumberField({ integer: true, initial: 0 }),
magic: new fields.NumberField({ integer: true, initial: 0 }) magic: new fields.NumberField({ integer: true, initial: 0 }),
primaryWeapon: new fields.SchemaField({
bonus: new fields.NumberField({ integer: true }),
extraDice: new fields.NumberField({ integer: true })
})
}) })
}), }),
companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }), companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }),
rules: new fields.SchemaField({ rules: new fields.SchemaField({
maxArmorMarked: new fields.SchemaField({ damageReduction: new fields.SchemaField({
value: new fields.NumberField({ required: true, integer: true, initial: 1 }), maxArmorMarked: new fields.SchemaField({
bonus: new fields.NumberField({ required: true, integer: true, initial: 0 }), value: new fields.NumberField({ required: true, integer: true, initial: 1 }),
stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 }) bonus: new fields.NumberField({ required: true, integer: true, initial: 0 }),
}), stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 })
stressDamageReduction: new fields.SchemaField({ }),
severe: stressDamageReductionRule(), stressDamageReduction: new fields.SchemaField({
major: stressDamageReductionRule(), severe: stressDamageReductionRule(),
minor: stressDamageReductionRule() major: stressDamageReductionRule(),
minor: stressDamageReductionRule()
}),
increasePerArmorMark: new fields.NumberField({ integer: true, initial: 1 }),
magical: new fields.BooleanField({ initial: false }),
physical: new fields.BooleanField({ initial: false })
}), }),
strangePatterns: new fields.NumberField({ strangePatterns: new fields.NumberField({
integer: true, integer: true,
@ -135,6 +151,18 @@ export default class DhCharacter extends BaseDataActor {
nullable: true, nullable: true,
initial: null initial: null
}), }),
weapon: new fields.SchemaField({
/* Unimplemented
-> Should remove the lowest damage dice from weapon damage
-> Reflect this in the chat message somehow so players get feedback that their choice is helping them.
*/
dropLowestDamageDice: new fields.BooleanField({ initial: false }),
/* Unimplemented
-> Should flip any lowest possible dice rolls for weapon damage to highest
-> Reflect this in the chat message somehow so players get feedback that their choice is helping them.
*/
flipMinDiceValue: new fields.BooleanField({ intial: false })
}),
runeWard: new fields.BooleanField({ initial: false }) runeWard: new fields.BooleanField({ initial: false })
}) })
}; };
@ -282,6 +310,13 @@ export default class DhCharacter extends BaseDataActor {
); );
} }
get armorApplicableDamageTypes() {
return {
physical: !this.rules.damageReduction.magical,
magical: !this.rules.damageReduction.physical
};
}
static async unequipBeforeEquip(itemToEquip) { static async unequipBeforeEquip(itemToEquip) {
const primary = this.primaryWeapon, const primary = this.primaryWeapon,
secondary = this.secondaryWeapon; secondary = this.secondaryWeapon;
@ -348,6 +383,7 @@ export default class DhCharacter extends BaseDataActor {
} }
const armor = this.armor; const armor = this.armor;
this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0; // Bonuses to armorScore won't have been applied yet. Need to solve in documentPreparation somehow
this.damageThresholds = { this.damageThresholds = {
major: armor major: armor
? armor.system.baseThresholds.major + this.levelData.level.current ? armor.system.baseThresholds.major + this.levelData.level.current
@ -372,9 +408,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.rules.damageReduction.maxArmorMarked.total =
this.rules.damageReduction.maxArmorMarked.value + this.rules.damageReduction.maxArmorMarked.bonus;
this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0;
this.resources.hitPoints.maxTotal = (this.class.value?.system?.hitPoints ?? 0) + this.resources.hitPoints.bonus; this.resources.hitPoints.maxTotal = (this.class.value?.system?.hitPoints ?? 0) + 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;

View file

@ -22,7 +22,7 @@ export default class DHArmor extends BaseDataItem {
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 }), baseScore: new fields.NumberField({ integer: true, initial: 0 }),
features: new fields.ArrayField( armorFeatures: new fields.ArrayField(
new fields.SchemaField({ new fields.SchemaField({
value: new fields.StringField({ value: new fields.StringField({
required: true, required: true,
@ -44,25 +44,22 @@ export default class DHArmor extends BaseDataItem {
}; };
} }
get featureInfo() {
return this.feature ? CONFIG.DH.ITEM.armorFeatures[this.feature] : null;
}
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);
if (allowed === false) return false; if (allowed === false) return false;
if (changes.system.features) { if (changes.system.armorFeatures) {
const removed = this.features.filter(x => !changes.system.features.includes(x)); const removed = this.armorFeatures.filter(x => !changes.system.armorFeatures.includes(x));
const added = changes.system.features.filter(x => !this.features.includes(x)); const added = changes.system.armorFeatures.filter(x => !this.armorFeatures.includes(x));
const effectIds = [];
const actionIds = [];
for (var feature of removed) { for (var feature of removed) {
for (var effectId of feature.effectIds) { effectIds.push(...feature.effectIds);
await this.parent.effects.get(effectId).delete(); actionIds.push(...feature.actionIds);
}
changes.system.actions = this.actions.filter(x => !feature.actionIds.includes(x._id));
} }
await this.parent.deleteEmbeddedDocuments('ActiveEffect', effectIds);
changes.system.actions = this.actions.filter(x => !actionIds.includes(x._id));
for (var feature of added) { for (var feature of added) {
const featureData = armorFeatures[feature.value]; const featureData = armorFeatures[feature.value];

View file

@ -10,7 +10,7 @@ export default class DHWeapon extends BaseDataItem {
type: 'weapon', type: 'weapon',
hasDescription: true, hasDescription: true,
isQuantifiable: true, isQuantifiable: true,
isInventoryItem: true, isInventoryItem: true
// hasInitialAction: true // hasInitialAction: true
}); });
} }
@ -26,8 +26,7 @@ export default class DHWeapon extends BaseDataItem {
//SETTINGS //SETTINGS
secondary: new fields.BooleanField({ initial: false }), secondary: new fields.BooleanField({ initial: false }),
burden: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.burden, initial: 'oneHanded' }), burden: new fields.StringField({ required: true, choices: CONFIG.DH.GENERAL.burden, initial: 'oneHanded' }),
weaponFeatures: new fields.ArrayField(
features: new fields.ArrayField(
new fields.SchemaField({ new fields.SchemaField({
value: new fields.StringField({ value: new fields.StringField({
required: true, required: true,
@ -59,7 +58,7 @@ export default class DHWeapon extends BaseDataItem {
{ {
value: { value: {
multiplier: 'prof', multiplier: 'prof',
dice: "d8" dice: 'd8'
} }
} }
] ]
@ -78,18 +77,20 @@ export default class DHWeapon extends BaseDataItem {
const allowed = await super._preUpdate(changes, options, user); const allowed = await super._preUpdate(changes, options, user);
if (allowed === false) return false; if (allowed === false) return false;
if (changes.system?.features) { if (changes.system?.weaponFeatures) {
const removed = this.features.filter(x => !changes.system.features.includes(x)); const removed = this.weaponFeatures.filter(x => !changes.system.weaponFeatures.includes(x));
const added = changes.system.features.filter(x => !this.features.includes(x)); const added = changes.system.weaponFeatures.filter(x => !this.weaponFeatures.includes(x));
const removedEffectsUpdate = [];
const removedActionsUpdate = [];
for (let weaponFeature of removed) { for (let weaponFeature of removed) {
for (var effectId of weaponFeature.effectIds) { removedEffectsUpdate.push(...weaponFeature.effectIds);
await this.parent.effects.get(effectId).delete(); removedActionsUpdate.push(...weaponFeature.actionIds);
}
changes.system.actions = this.actions.filter(x => !weaponFeature.actionIds.includes(x._id));
} }
await this.parent.deleteEmbeddedDocuments('ActiveEffect', removedEffectsUpdate);
changes.system.actions = this.actions.filter(x => !removedActionsUpdate.includes(x._id));
for (let weaponFeature of added) { for (let weaponFeature of added) {
const featureData = CONFIG.DH.ITEM.weaponFeatures[weaponFeature.value]; const featureData = CONFIG.DH.ITEM.weaponFeatures[weaponFeature.value];
if (featureData.effects?.length > 0) { if (featureData.effects?.length > 0) {
@ -102,17 +103,37 @@ export default class DHWeapon extends BaseDataItem {
]); ]);
weaponFeature.effectIds = embeddedItems.map(x => x.id); weaponFeature.effectIds = embeddedItems.map(x => x.id);
} }
const newActions = [];
if (featureData.actions?.length > 0) { if (featureData.actions?.length > 0) {
const newActions = featureData.actions.map(action => { for (let action of featureData.actions) {
const cls = actionsTypes[action.type]; const embeddedEffects = await this.parent.createEmbeddedDocuments(
return new cls( 'ActiveEffect',
{ ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) }, (action.effects ?? []).map(effect => ({
{ parent: this } ...effect,
transfer: false,
name: game.i18n.localize(effect.name),
description: game.i18n.localize(effect.description)
}))
); );
}); const cls = actionsTypes[action.type];
changes.system.actions = [...this.actions, ...newActions]; newActions.push(
weaponFeature.actionIds = newActions.map(x => x._id); new cls(
{
...action,
_id: foundry.utils.randomID(),
name: game.i18n.localize(action.name),
description: game.i18n.localize(action.description),
effects: embeddedEffects.map(x => ({ _id: x.id }))
},
{ parent: this }
)
);
}
} }
changes.system.actions = [...this.actions, ...newActions];
weaponFeature.actionIds = newActions.map(x => x._id);
} }
} }
} }

View file

@ -25,7 +25,11 @@ export default class DhActiveEffect extends ActiveEffect {
} }
static applyField(model, change, field) { static applyField(model, change, field) {
change.value = Roll.safeEval(Roll.replaceFormulaData(change.value, change.effect.parent)); const isItemTarget = change.value.toLowerCase().startsWith('item.');
change.value = isItemTarget ? change.value.slice(5) : change.value;
change.value = Roll.safeEval(
Roll.replaceFormulaData(change.value, isItemTarget ? change.effect.parent : model)
);
super.applyField(model, change, field); super.applyField(model, change, field);
} }

View file

@ -3,6 +3,7 @@ import { emitAsGM, emitAsOwner, GMUpdateEvent, socketEvent } from '../systemRegi
import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.mjs'; import DamageReductionDialog from '../applications/dialogs/damageReductionDialog.mjs';
import { LevelOptionType } from '../data/levelTier.mjs'; import { LevelOptionType } from '../data/levelTier.mjs';
import DHFeature from '../data/item/feature.mjs'; import DHFeature from '../data/item/feature.mjs';
import { damageKeyToNumber, getDamageKey } from '../helpers/utils.mjs';
export default class DhpActor extends Actor { export default class DhpActor extends Actor {
/** /**
@ -455,14 +456,32 @@ export default class DhpActor extends Actor {
cls.create(msg.toObject()); cls.create(msg.toObject());
} }
async takeDamage(damage, type) { #canReduceDamage(hpDamage, type) {
if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, damage, type) === false) return null; const availableStress = this.system.resources.stress.maxTotal - this.system.resources.stress.value;
const canUseArmor =
this.system.armor &&
this.system.armor.system.marks.value < this.system.armorScore &&
this.system.armorApplicableDamageTypes[type];
const canUseStress = Object.keys(this.system.rules.damageReduction.stressDamageReduction).reduce((acc, x) => {
const rule = this.system.rules.damageReduction.stressDamageReduction[x];
if (damageKeyToNumber(x) <= hpDamage) return acc || (rule.enabled && availableStress >= rule.cost);
return acc;
}, false);
return canUseArmor || canUseStress;
}
async takeDamage(baseDamage, type) {
if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, baseDamage, type) === false) return null;
if (this.type === 'companion') { if (this.type === 'companion') {
await this.modifyResource([{ value: 1, type: 'stress' }]); await this.modifyResource([{ value: 1, type: 'stress' }]);
return; return;
} }
const flatReduction = this.system.bonuses.damageReduction[type];
const damage = Math.max(baseDamage - (flatReduction ?? 0), 0);
const hpDamage = this.convertDamageToThreshold(damage); const hpDamage = this.convertDamageToThreshold(damage);
if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null; if (Hooks.call(`${CONFIG.DH.id}.postDamageTreshold`, this, hpDamage, damage, type) === false) return null;
@ -471,12 +490,12 @@ export default class DhpActor extends Actor {
const updates = [{ value: hpDamage, type: 'hitPoints' }]; const updates = [{ value: hpDamage, type: 'hitPoints' }];
if ( if (this.type === 'character' && this.system.armor && this.#canReduceDamage(hpDamage, type)) {
this.type === 'character' && const armorStackResult = await this.owner.query('armorStack', {
this.system.armor && actorId: this.uuid,
this.system.armor.system.marks.value < this.system.armorScore damage: hpDamage,
) { type: type
const armorStackResult = await this.owner.query('armorStack', { actorId: this.uuid, damage: hpDamage }); });
if (armorStackResult) { if (armorStackResult) {
const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; const { modifiedDamage, armorSpent, stressSpent } = armorStackResult;
updates.find(u => u.type === 'hitPoints').value = modifiedDamage; updates.find(u => u.type === 'hitPoints').value = modifiedDamage;

View file

@ -90,10 +90,12 @@ export default class DHItem extends foundry.documents.Item {
ok: { ok: {
label: title, label: title,
callback: (event, button, dialog) => { callback: (event, button, dialog) => {
Object.defineProperty(prevEvent, "shiftKey", { Object.defineProperty(prevEvent, 'shiftKey', {
get() { return event.shiftKey; }, get() {
return event.shiftKey;
}
}); });
return this.system.actionsList.find(a => a._id === button.form.elements.actionId.value) return this.system.actionsList.find(a => a._id === button.form.elements.actionId.value);
} }
} }
}); });

View file

@ -159,7 +159,8 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) =>
return { return {
value: key, value: key,
name: game.i18n.localize(option.label), name: game.i18n.localize(option.label),
src: option.src src: option.src,
description: option.description
}; };
}), }),
maxTags: maxTags, maxTags: maxTags,
@ -173,11 +174,12 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) =>
}, },
templates: { templates: {
tag(tagData) { tag(tagData) {
return `<tag title="${tagData.title || tagData.value}" return `<tag
contenteditable='false' contenteditable='false'
spellcheck='false' spellcheck='false'
tabIndex="${this.settings.a11y.focusableTags ? 0 : -1}" tabIndex="${this.settings.a11y.focusableTags ? 0 : -1}"
class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ''}" class="${this.settings.classNames.tag} ${tagData.class ? tagData.class : ''}"
data-tooltip="${tagData.description || tagData.name}"
${this.getAttributes(tagData)}> ${this.getAttributes(tagData)}>
<x class="${this.settings.classNames.tagX}" role='button' aria-label='remove tag'></x> <x class="${this.settings.classNames.tagX}" role='button' aria-label='remove tag'></x>
<div> <div>
@ -190,6 +192,8 @@ export const tagifyElement = (element, options, onChange, tagifyOptions = {}) =>
}); });
tagifyElement.on('add', event => { tagifyElement.on('add', event => {
if (event.detail.data.__isValid === 'not allowed') return;
const input = event.detail.tagify.DOM.originalInput; const input = event.detail.tagify.DOM.originalInput;
const currentList = input.value ? JSON.parse(input.value) : []; const currentList = input.value ? JSON.parse(input.value) : [];
onChange([...currentList, event.detail.data], { option: event.detail.data.value, removed: false }, input); onChange([...currentList, event.detail.data], { option: event.detail.data.value, removed: false }, input);
@ -233,19 +237,23 @@ Roll.replaceFormulaData = function (formula, data = {}, { missing, warn = false
return nativeReplaceFormulaData(formula, data, { missing, warn }); return nativeReplaceFormulaData(formula, data, { missing, warn });
}; };
export const getDamageLabel = damage => { export const getDamageKey = damage => {
switch (damage) { switch (damage) {
case 3: case 3:
return game.i18n.localize('DAGGERHEART.GENERAL.Damage.severe'); return 'severe';
case 2: case 2:
return game.i18n.localize('DAGGERHEART.GENERAL.Damage.major'); return 'major';
case 1: case 1:
return game.i18n.localize('DAGGERHEART.GENERAL.Damage.minor'); return 'minor';
case 0: case 0:
return game.i18n.localize('DAGGERHEART.GENERAL.Damage.none'); return 'none';
} }
}; };
export const getDamageLabel = damage => {
return game.i18n.localize(`DAGGERHEART.GENERAL.Damage.${getDamageKey(damage)}`);
};
export const damageKeyToNumber = key => { export const damageKeyToNumber = key => {
switch (key) { switch (key) {
case 'severe': case 'severe':

View file

@ -45,7 +45,13 @@ export const registerSocketHooks = () => {
await game.settings.set( await game.settings.set(
CONFIG.DH.id, CONFIG.DH.id,
CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear,
Math.max(0, Math.min(game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear, data.update)) Math.max(
0,
Math.min(
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear,
data.update
)
)
); );
/* Hooks.callAll(socketEvent.DhpFearUpdate); /* Hooks.callAll(socketEvent.DhpFearUpdate);
await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.DhpFearUpdate }); */ await game.socket.emit(`system.${CONFIG.DH.id}`, { action: socketEvent.DhpFearUpdate }); */
@ -64,7 +70,7 @@ export const registerSocketHooks = () => {
}; };
export const emitAsGM = async (eventName, callback, update, uuid = null) => { export const emitAsGM = async (eventName, callback, update, uuid = null) => {
if(!game.user.isGM) { if (!game.user.isGM) {
return await game.socket.emit(`system.${CONFIG.DH.id}`, { return await game.socket.emit(`system.${CONFIG.DH.id}`, {
action: socketEvent.GMUpdate, action: socketEvent.GMUpdate,
data: { data: {
@ -74,11 +80,11 @@ export const emitAsGM = async (eventName, callback, update, uuid = null) => {
} }
}); });
} else return callback(update); } else return callback(update);
} };
export const emitAsOwner = (eventName, userId, args) => { export const emitAsOwner = (eventName, userId, args) => {
if(userId === game.user.id) return; if (userId === game.user.id) return;
if(!eventName || !userId) return false; if (!eventName || !userId) return false;
game.socket.emit(`system.${CONFIG.DH.id}`, { game.socket.emit(`system.${CONFIG.DH.id}`, {
action: eventName, action: eventName,
data: { data: {
@ -87,4 +93,4 @@ export const emitAsOwner = (eventName, userId, args) => {
} }
}); });
return false; return false;
} };

View file

@ -1,46 +1,46 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
.application.daggerheart.dh-style.views.beastform-selection { .application.daggerheart.dh-style.views.beastform-selection {
.beastforms-container { .beastforms-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
.beastforms-tier { .beastforms-tier {
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr 1fr;
gap: 4px; gap: 4px;
.beastform-container { .beastform-container {
position: relative; position: relative;
display: flex; display: flex;
justify-content: center; justify-content: center;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
cursor: pointer; cursor: pointer;
&.inactive { &.inactive {
opacity: 0.4; opacity: 0.4;
} }
img { img {
width: 100%; width: 100%;
border-radius: 6px; border-radius: 6px;
} }
.beastform-title { .beastform-title {
position: absolute; position: absolute;
top: 4px; top: 4px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
font-size: 16px; font-size: 16px;
margin: 0 4px; margin: 0 4px;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
color: light-dark(@beige, @dark); color: light-dark(@beige, @dark);
background-image: url('../assets/parchments/dh-parchment-light.png'); background-image: url('../assets/parchments/dh-parchment-light.png');
} }
} }
} }
} }
} }

View file

@ -1,21 +1,21 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
@import '../../utils/mixin.less'; @import '../../utils/mixin.less';
.appTheme({ .appTheme({
&.beastform-selection { &.beastform-selection {
.beastforms-container .beastforms-tier .beastform-container .beastform-title { .beastforms-container .beastforms-tier .beastform-container .beastform-title {
background-image: url('../assets/parchments/dh-parchment-dark.png'); background-image: url('../assets/parchments/dh-parchment-dark.png');
} }
} }
}, {}); }, {});
.application.daggerheart.dh-style.views.beastform-selection { .application.daggerheart.dh-style.views.beastform-selection {
footer { footer {
margin-top: 8px; margin-top: 8px;
display: flex; display: flex;
button { button {
flex: 1; flex: 1;
} }
} }
} }

View file

@ -1,13 +1,13 @@
.daggerheart.dh-style.dialog.character-creation { .daggerheart.dh-style.dialog.character-creation {
.creation-action-footer { .creation-action-footer {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 32px; gap: 32px;
button { button {
flex: 1; flex: 1;
height: 100%; height: 100%;
white-space: nowrap; white-space: nowrap;
} }
} }
} }

View file

@ -1,325 +1,325 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
.daggerheart.dh-style.dialog.character-creation { .daggerheart.dh-style.dialog.character-creation {
.main-selections-container { .main-selections-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
.selections-container { .selections-container {
width: 140px; width: 140px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
text-align: center; text-align: center;
.card-preview-container { .card-preview-container {
border-color: light-dark(@dark-blue, @golden); border-color: light-dark(@dark-blue, @golden);
} }
} }
.selections-outer-container { .selections-outer-container {
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-evenly;
height: 210px; height: 210px;
} }
.section-container { .section-container {
border-radius: 8px; border-radius: 8px;
border-color: light-dark(@dark-blue, @golden); border-color: light-dark(@dark-blue, @golden);
legend { legend {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
font-size: 28px; font-size: 28px;
font-weight: bold; font-weight: bold;
padding: 0 8px; padding: 0 8px;
} }
.section-inner-container { .section-inner-container {
position: relative; position: relative;
border-radius: 8px; border-radius: 8px;
border-color: light-dark(@dark-blue, @golden); border-color: light-dark(@dark-blue, @golden);
display: flex; display: flex;
justify-content: center; justify-content: center;
legend { legend {
font-size: 20px; font-size: 20px;
} }
.action-button { .action-button {
position: absolute; position: absolute;
bottom: -8px; bottom: -8px;
height: 16px; height: 16px;
width: 110px; width: 110px;
min-height: unset; min-height: unset;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
color: light-dark(@beige, @beige); color: light-dark(@beige, @beige);
background-color: light-dark(var(--color-warm-3), var(--color-warm-3)); background-color: light-dark(var(--color-warm-3), var(--color-warm-3));
&:hover { &:hover {
background-color: light-dark(var(--color-warm-2), var(--color-warm-2)); background-color: light-dark(var(--color-warm-2), var(--color-warm-2));
filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2))); filter: drop-shadow(0 0 3px light-dark(var(--color-warm-2), var(--color-warm-2)));
} }
} }
} }
} }
.traits-container { .traits-container {
text-align: center; text-align: center;
display: flex; display: flex;
gap: 16px; gap: 16px;
.suggested-traits-container { .suggested-traits-container {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
width: 176px; width: 176px;
gap: 4px; gap: 4px;
margin-bottom: 8px; margin-bottom: 8px;
.suggested-trait-container { .suggested-trait-container {
width: 56px; width: 56px;
white-space: nowrap; white-space: nowrap;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
color: light-dark(@beige, @dark); color: light-dark(@beige, @dark);
background-image: url('../assets/parchments/dh-parchment-light.png'); background-image: url('../assets/parchments/dh-parchment-light.png');
} }
} }
.traits-inner-container { .traits-inner-container {
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-evenly;
gap: 8px; gap: 8px;
.trait-container { .trait-container {
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
padding: 0 4px; padding: 0 4px;
} }
} }
} }
.experiences-inner-container { .experiences-inner-container {
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-evenly;
text-align: center; text-align: center;
.experience-container { .experience-container {
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
.experience-description { .experience-description {
border-color: light-dark(@dark-blue, @golden); border-color: light-dark(@dark-blue, @golden);
padding-right: 24px; padding-right: 24px;
} }
.experience-value { .experience-value {
position: absolute; position: absolute;
right: 0; right: 0;
width: 22px; width: 22px;
border-left: 1px solid light-dark(@dark-blue, @golden); border-left: 1px solid light-dark(@dark-blue, @golden);
height: 100%; height: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
} }
} }
.creation-action-footer { .creation-action-footer {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 32px; gap: 32px;
.footer-section { .footer-section {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 32px; gap: 32px;
nav { nav {
flex: 1; flex: 1;
gap: 8px; gap: 8px;
border: 0; border: 0;
a { a {
flex: 1; flex: 1;
text-align: center; text-align: center;
display: flex; display: flex;
justify-content: center; justify-content: center;
position: relative; position: relative;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
.nav-section-text { .nav-section-text {
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.finish-marker { .finish-marker {
position: absolute; position: absolute;
align-self: center; align-self: center;
top: -10px; top: -10px;
padding: 4px; padding: 4px;
border: 1px solid; border: 1px solid;
border-radius: 50%; border-radius: 50%;
height: 20px; height: 20px;
width: 20px; width: 20px;
font-size: 14px; font-size: 14px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: var(--color-cool-4); background-color: var(--color-cool-4);
content: ''; content: '';
&.finished { &.finished {
background-color: var(--color-warm-2); background-color: var(--color-warm-2);
} }
} }
.descriptor { .descriptor {
position: absolute; position: absolute;
bottom: -8px; bottom: -8px;
font-size: 12px; font-size: 12px;
border-radius: 8px; border-radius: 8px;
width: 56px; width: 56px;
text-align: center; text-align: center;
line-height: 1; line-height: 1;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
color: light-dark(@beige, @dark); color: light-dark(@beige, @dark);
background-image: url(../assets/parchments/dh-parchment-light.png); background-image: url(../assets/parchments/dh-parchment-light.png);
} }
} }
} }
button { button {
flex: 1; flex: 1;
height: 100%; height: 100%;
white-space: nowrap; white-space: nowrap;
} }
} }
} }
.main-equipment-selection { .main-equipment-selection {
display: grid; display: grid;
grid-template-columns: 1fr 2fr; grid-template-columns: 1fr 2fr;
gap: 16px; gap: 16px;
&.triple { &.triple {
grid-template-columns: 1fr 1fr 1fr; grid-template-columns: 1fr 1fr 1fr;
} }
} }
.equipment-selection { .equipment-selection {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
border: 2px solid light-dark(@dark-blue, @golden); border: 2px solid light-dark(@dark-blue, @golden);
border-radius: 8px; border-radius: 8px;
legend { legend {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
font-size: 28px; font-size: 28px;
font-weight: bold; font-weight: bold;
padding: 0 8px; padding: 0 8px;
white-space: nowrap; white-space: nowrap;
} }
.equipment-subsection { .equipment-subsection {
display: flex; display: flex;
align-items: start; align-items: start;
gap: 32px; gap: 32px;
} }
.equipment-wrapper { .equipment-wrapper {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
} }
.simple-equipment-container { .simple-equipment-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-evenly; justify-content: space-evenly;
gap: 8px; gap: 8px;
height: 100%; height: 100%;
.simple-equipment { .simple-equipment {
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 8px; border-radius: 8px;
position: relative; position: relative;
display: flex; display: flex;
justify-content: center; justify-content: center;
&.selectable { &.selectable {
cursor: pointer; cursor: pointer;
} }
&.inactive { &.inactive {
opacity: 0.4; opacity: 0.4;
} }
label { label {
position: absolute; position: absolute;
top: -8px; top: -8px;
font-size: 12px; font-size: 12px;
white-space: nowrap; white-space: nowrap;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
color: light-dark(@beige, @dark); color: light-dark(@beige, @dark);
background-image: url('../assets/parchments/dh-parchment-light.png'); background-image: url('../assets/parchments/dh-parchment-light.png');
padding: 0 2px; padding: 0 2px;
} }
img { img {
width: 60px; width: 60px;
height: 60px; height: 60px;
border-radius: 8px; border-radius: 8px;
} }
} }
} }
.suggestion-container { .suggestion-container {
position: relative; position: relative;
display: flex; display: flex;
justify-content: center; justify-content: center;
height: min-content; height: min-content;
border: 2px solid light-dark(@dark-blue, @golden); border: 2px solid light-dark(@dark-blue, @golden);
border-radius: 8px; border-radius: 8px;
legend { legend {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
font-size: 12px; font-size: 12px;
} }
.suggestion-inner-container { .suggestion-inner-container {
position: relative; position: relative;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 6px; padding: 6px;
cursor: grab; cursor: grab;
&.taken { &.taken {
opacity: 0.4; opacity: 0.4;
} }
label { label {
position: absolute; position: absolute;
top: -2px; top: -2px;
font-size: 12px; font-size: 12px;
} }
img { img {
width: 120px; width: 120px;
} }
} }
} }
} }
} }
} }

View file

@ -1,27 +1,27 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
@import '../../utils/mixin.less'; @import '../../utils/mixin.less';
.appTheme({ .appTheme({
.character-creation { .character-creation {
.tab-navigation nav a .descriptor { .tab-navigation nav a .descriptor {
background-image: url('../assets/parchments/dh-parchment-dark.png'); background-image: url('../assets/parchments/dh-parchment-dark.png');
} }
.main-selections-container { .main-selections-container {
.traits-container .suggested-traits-container .suggested-trait-container, .traits-container .suggested-traits-container .suggested-trait-container,
.creation-action-footer .footer-section nav a .descriptor, .creation-action-footer .footer-section nav a .descriptor,
.equipment-selection .simple-equipment-container .simple-equipment label { .equipment-selection .simple-equipment-container .simple-equipment label {
background-image: url('../assets/parchments/dh-parchment-dark.png'); background-image: url('../assets/parchments/dh-parchment-dark.png');
} }
} }
} }
}, {}); }, {});
.daggerheart.dh-style.dialog.character-creation { .daggerheart.dh-style.dialog.character-creation {
.window-content { .window-content {
gap: 16px; gap: 16px;
.tab { .tab {
overflow-y: auto; overflow-y: auto;
} }
} }
} }

View file

@ -1,62 +1,62 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
.daggerheart.dh-style.dialog.character-creation { .daggerheart.dh-style.dialog.character-creation {
.tab-navigation { .tab-navigation {
nav { nav {
flex: 1; flex: 1;
a { a {
flex: 1; flex: 1;
text-align: center; text-align: center;
display: flex; display: flex;
justify-content: center; justify-content: center;
position: relative; position: relative;
&.disabled { &.disabled {
opacity: 0.4; opacity: 0.4;
} }
.nav-section-text { .nav-section-text {
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.finish-marker { .finish-marker {
position: absolute; position: absolute;
align-self: center; align-self: center;
top: -8px; top: -8px;
padding: 4px; padding: 4px;
border: 1px solid; border: 1px solid;
border-radius: 50%; border-radius: 50%;
height: 16px; height: 16px;
width: 16px; width: 16px;
font-size: 12px; font-size: 12px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-color: var(--color-cool-4); background-color: var(--color-cool-4);
content: ''; content: '';
&.active { &.active {
background-color: var(--color-warm-2); background-color: var(--color-warm-2);
} }
} }
.descriptor { .descriptor {
position: absolute; position: absolute;
bottom: -8px; bottom: -8px;
font-size: 12px; font-size: 12px;
border-radius: 8px; border-radius: 8px;
width: 56px; width: 56px;
text-align: center; text-align: center;
line-height: 1; line-height: 1;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
color: light-dark(@beige, @dark); color: light-dark(@beige, @dark);
background-image: url(../assets/parchments/dh-parchment-light.png); background-image: url(../assets/parchments/dh-parchment-light.png);
} }
} }
} }
} }
} }

View file

@ -1,7 +1,7 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
.daggerheart.views.damage-reduction { .daggerheart.views.damage-reduction {
.window-content { .window-content {
padding: 8px 0; padding: 8px 0;
} }
} }

View file

@ -1,81 +1,81 @@
@import '../../utils/spacing.less'; @import '../../utils/spacing.less';
@import '../../utils/colors.less'; @import '../../utils/colors.less';
.daggerheart.views { .daggerheart.views {
.downtime-container { .downtime-container {
.downtime-header { .downtime-header {
margin: 0; margin: 0;
color: light-dark(@dark-blue, @golden); color: light-dark(@dark-blue, @golden);
text-align: center; text-align: center;
} }
.activity-container { .activity-container {
display: flex; display: flex;
align-items: center; align-items: center;
padding: 8px; padding: 8px;
.activity-title { .activity-title {
flex: 1; flex: 1;
display: flex; display: flex;
align-items: center; align-items: center;
.activity-title-text { .activity-title-text {
font-size: 24px; font-size: 24px;
font-weight: bold; font-weight: bold;
} }
.activity-image { .activity-image {
width: 80px; width: 80px;
position: relative; position: relative;
display: flex; display: flex;
justify-content: center; justify-content: center;
margin-right: 8px; margin-right: 8px;
border: 2px solid black; border: 2px solid black;
border-radius: 50%; border-radius: 50%;
cursor: pointer; cursor: pointer;
.activity-select-label { .activity-select-label {
position: absolute; position: absolute;
top: -9px; top: -9px;
font-size: 14px; font-size: 14px;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
color: light-dark(@beige, @dark); color: light-dark(@beige, @dark);
background-image: url(../assets/parchments/dh-parchment-light.png); background-image: url(../assets/parchments/dh-parchment-light.png);
padding: 0 8px; padding: 0 8px;
line-height: 1; line-height: 1;
font-weight: bold; font-weight: bold;
} }
img { img {
border-radius: 50%; border-radius: 50%;
} }
&:hover, &:hover,
&.selected { &.selected {
filter: drop-shadow(0 0 6px gold); filter: drop-shadow(0 0 6px gold);
} }
} }
.custom-name-input { .custom-name-input {
font-size: 24px; font-size: 24px;
font-weight: bold; font-weight: bold;
padding: 0; padding: 0;
background: transparent; background: transparent;
color: rgb(239, 230, 216); color: rgb(239, 230, 216);
} }
} }
.activity-body { .activity-body {
flex: 1; flex: 1;
font-style: italic; font-style: italic;
} }
} }
} }
&.downtime { &.downtime {
.activity-text-area { .activity-text-area {
resize: none; resize: none;
} }
} }
} }

View file

@ -1,19 +1,19 @@
@import './level-up/navigation-container.less'; @import './level-up/navigation-container.less';
@import './level-up/selections-container.less'; @import './level-up/selections-container.less';
@import './level-up/sheet.less'; @import './level-up/sheet.less';
@import './level-up/summary-container.less'; @import './level-up/summary-container.less';
@import './level-up/tiers-container.less'; @import './level-up/tiers-container.less';
@import './downtime/downtime-container.less'; @import './downtime/downtime-container.less';
@import './beastform/beastform-container.less'; @import './beastform/beastform-container.less';
@import './beastform/sheet.less'; @import './beastform/sheet.less';
@import './character-creation/creation-action-footer.less'; @import './character-creation/creation-action-footer.less';
@import './character-creation/selections-container.less'; @import './character-creation/selections-container.less';
@import './character-creation/sheet.less'; @import './character-creation/sheet.less';
@import './character-creation/tab-navigation.less'; @import './character-creation/tab-navigation.less';
@import './dice-roll/roll-selection.less'; @import './dice-roll/roll-selection.less';
@import './damage-reduction/damage-reduction-container.less'; @import './damage-reduction/damage-reduction-container.less';
@import './damage-reduction/sheets.less'; @import './damage-reduction/sheets.less';

View file

@ -1,30 +1,30 @@
.daggerheart.levelup { .daggerheart.levelup {
.levelup-navigation-container { .levelup-navigation-container {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 22px; gap: 22px;
height: 36px; height: 36px;
nav { nav {
flex: 1; flex: 1;
.levelup-tab-container { .levelup-tab-container {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
} }
} }
.levelup-navigation-actions { .levelup-navigation-actions {
width: 306px; width: 306px;
display: flex; display: flex;
justify-content: end; justify-content: end;
gap: 16px; gap: 16px;
margin-right: 4px; margin-right: 4px;
* { * {
width: calc(50% - 8px); width: calc(50% - 8px);
} }
} }
} }
} }

View file

@ -1,108 +1,108 @@
.daggerheart.levelup { .daggerheart.levelup {
.levelup-selections-container { .levelup-selections-container {
.achievement-experience-cards { .achievement-experience-cards {
display: flex; display: flex;
gap: 8px; gap: 8px;
.achievement-experience-card { .achievement-experience-card {
border: 1px solid; border: 1px solid;
border-radius: 4px; border-radius: 4px;
padding-right: 4px; padding-right: 4px;
font-size: 18px; font-size: 18px;
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
.achievement-experience-marker { .achievement-experience-marker {
border: 1px solid; border: 1px solid;
border-radius: 50%; border-radius: 50%;
height: 18px; height: 18px;
width: 18px; width: 18px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 12px; font-size: 12px;
} }
} }
} }
.levelup-card-selection { .levelup-card-selection {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 40px; gap: 40px;
.card-preview-container { .card-preview-container {
width: calc(100% * (1 / 5)); width: calc(100% * (1 / 5));
} }
.levelup-domains-selection-container { .levelup-domains-selection-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
.levelup-domain-selection-container { .levelup-domain-selection-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
flex: 1; flex: 1;
position: relative; position: relative;
cursor: pointer; cursor: pointer;
&.disabled { &.disabled {
pointer-events: none; pointer-events: none;
opacity: 0.4; opacity: 0.4;
} }
.levelup-domain-label { .levelup-domain-label {
position: absolute; position: absolute;
text-align: center; text-align: center;
top: 4px; top: 4px;
background: grey; background: grey;
padding: 0 12px; padding: 0 12px;
border-radius: 6px; border-radius: 6px;
} }
img { img {
height: 124px; height: 124px;
} }
.levelup-domain-selected { .levelup-domain-selected {
position: absolute; position: absolute;
height: 54px; height: 54px;
width: 54px; width: 54px;
border-radius: 50%; border-radius: 50%;
border: 2px solid; border: 2px solid;
font-size: 48px; font-size: 48px;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background-image: url(../assets/parchments/dh-parchment-light.png); background-image: url(../assets/parchments/dh-parchment-light.png);
color: var(--color-dark-5); color: var(--color-dark-5);
top: calc(50% - 29px); top: calc(50% - 29px);
i { i {
position: relative; position: relative;
right: 2px; right: 2px;
} }
} }
} }
} }
} }
.levelup-selections-title { .levelup-selections-title {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
} }
.levelup-radio-choices { .levelup-radio-choices {
display: flex; display: flex;
gap: 8px; gap: 8px;
label { label {
flex: 0; flex: 0;
} }
} }
} }
} }

View file

@ -1,37 +1,37 @@
@import '../../utils/mixin.less'; @import '../../utils/mixin.less';
.appTheme({}, { .appTheme({}, {
&.levelup { &.levelup {
.tiers-container { .tiers-container {
.tier-container { .tier-container {
background-image: url('../assets/parchments/dh-parchment-light.png'); background-image: url('../assets/parchments/dh-parchment-light.png');
} }
} }
} }
}); });
.daggerheart.levelup { .daggerheart.levelup {
.window-content { .window-content {
max-height: 960px; max-height: 960px;
overflow: auto; overflow: auto;
} }
div[data-application-part='form'] { div[data-application-part='form'] {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
} }
section { section {
.section-container { .section-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
margin-top: 8px; margin-top: 8px;
} }
} }
.levelup-footer { .levelup-footer {
display: flex; display: flex;
} }
} }

View file

@ -1,37 +1,37 @@
.daggerheart.levelup { .daggerheart.levelup {
.levelup-summary-container { .levelup-summary-container {
.level-achievements-container, .level-achievements-container,
.level-advancements-container { .level-advancements-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
h2, h2,
h3, h3,
h4, h4,
h5 { h5 {
margin: 0; margin: 0;
color: var(--color-text-secondary); color: var(--color-text-secondary);
} }
} }
.increase-container { .increase-container {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
font-size: 20px; font-size: 20px;
} }
.summary-selection-container { .summary-selection-container {
display: flex; display: flex;
gap: 8px; gap: 8px;
.summary-selection { .summary-selection {
border: 2px solid; border: 2px solid;
border-radius: 6px; border-radius: 6px;
padding: 0 4px; padding: 0 4px;
font-size: 18px; font-size: 18px;
} }
} }
} }
} }

View file

@ -1,65 +1,65 @@
.daggerheart.levelup { .daggerheart.levelup {
.tiers-container { .tiers-container {
display: flex; display: flex;
gap: 16px; gap: 16px;
.tier-container { .tier-container {
flex: 1; flex: 1;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
background-image: url('../assets/parchments/dh-parchment-dark.png'); background-image: url('../assets/parchments/dh-parchment-dark.png');
&.inactive { &.inactive {
opacity: 0.4; opacity: 0.4;
pointer-events: none; pointer-events: none;
} }
legend { legend {
margin-left: auto; margin-left: auto;
margin-right: auto; margin-right: auto;
font-size: 22px; font-size: 22px;
font-weight: bold; font-weight: bold;
padding: 0 12px; padding: 0 12px;
} }
.checkbox-group-container { .checkbox-group-container {
display: grid; display: grid;
grid-template-columns: 1fr 3fr; grid-template-columns: 1fr 3fr;
gap: 4px; gap: 4px;
.checkboxes-container { .checkboxes-container {
display: flex; display: flex;
justify-content: end; justify-content: end;
gap: 4px; gap: 4px;
.checkbox-grouping-coontainer { .checkbox-grouping-coontainer {
display: flex; display: flex;
height: min-content; height: min-content;
&.multi { &.multi {
border: 2px solid grey; border: 2px solid grey;
padding: 2.4px 2.5px 0; padding: 2.4px 2.5px 0;
border-radius: 4px; border-radius: 4px;
gap: 2px; gap: 2px;
.selection-checkbox { .selection-checkbox {
margin-left: 0; margin-left: 0;
margin-right: 0; margin-right: 0;
} }
} }
.selection-checkbox { .selection-checkbox {
margin: 0; margin: 0;
} }
} }
} }
.checkbox-group-label { .checkbox-group-label {
font-size: 14px; font-size: 14px;
font-style: italic; font-style: italic;
} }
} }
} }
} }
} }

View file

@ -1,14 +1,14 @@
@import './sheet.less'; @import './sheet.less';
@import './dialog.less'; @import './dialog.less';
@import './elements.less'; @import './elements.less';
@import './tab-navigation.less'; @import './tab-navigation.less';
@import './tab-form-footer.less'; @import './tab-form-footer.less';
@import './tab-actions.less'; @import './tab-actions.less';
@import './tab-features.less'; @import './tab-features.less';
@import './tab-effects.less'; @import './tab-effects.less';
@import './item-header.less'; @import './item-header.less';
@import './feature-section.less'; @import './feature-section.less';
@import './inventory-item.less'; @import './inventory-item.less';
@import './inventory-fieldset-items.less'; @import './inventory-fieldset-items.less';
@import './prose-mirror.less'; @import './prose-mirror.less';
@import './filter-menu.less'; @import './filter-menu.less';

View file

@ -1,28 +1,28 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
@import '../../utils/fonts.less'; @import '../../utils/fonts.less';
.application.daggerheart.dh-style.dialog { .application.daggerheart.dh-style.dialog {
.tab.experiences { .tab.experiences {
.add-experience-btn { .add-experience-btn {
width: 100%; width: 100%;
margin-bottom: 12px; margin-bottom: 12px;
} }
.experience-list { .experience-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
.experience-item { .experience-item {
display: grid; display: grid;
grid-template-columns: 3fr 1fr 30px; grid-template-columns: 3fr 1fr 30px;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
a { a {
text-align: center; text-align: center;
} }
} }
} }
} }
} }

View file

@ -1,18 +1,18 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
@import '../../utils/fonts.less'; @import '../../utils/fonts.less';
.application.daggerheart.dh-style.dialog { .application.daggerheart.dh-style.dialog {
.tab { .tab {
&.details.active, &.details.active,
&.attack.active { &.attack.active {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 16px; gap: 16px;
} }
.fieldsets-section { .fieldsets-section {
display: flex; display: flex;
gap: 16px; gap: 16px;
} }
} }
} }

View file

@ -1,50 +1,50 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
@import '../../utils/fonts.less'; @import '../../utils/fonts.less';
.application.daggerheart.dh-style.dialog { .application.daggerheart.dh-style.dialog {
.tab.adversaries { .tab.adversaries {
max-height: 450px; max-height: 450px;
overflow-y: auto; overflow-y: auto;
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: light-dark(@dark-blue, @golden) transparent; scrollbar-color: light-dark(@dark-blue, @golden) transparent;
.add-action-btn { .add-action-btn {
width: 100%; width: 100%;
margin-bottom: 12px; margin-bottom: 12px;
} }
.category-container { .category-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: start; align-items: start;
gap: 8px; gap: 8px;
.category-name { .category-name {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
width: 100%; width: 100%;
} }
.adversaries-container { .adversaries-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 6px; gap: 6px;
width: 100%; width: 100%;
} }
} }
.adversaries-dragger { .adversaries-dragger {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-sizing: border-box; box-sizing: border-box;
width: 100%; width: 100%;
height: 40px; height: 40px;
border: 1px dashed light-dark(@dark-blue-50, @beige-50); border: 1px dashed light-dark(@dark-blue-50, @beige-50);
border-radius: 3px; border-radius: 3px;
color: light-dark(@dark-blue-50, @beige-50); color: light-dark(@dark-blue-50, @beige-50);
font-family: @font-body; font-family: @font-body;
} }
} }
} }

View file

@ -1,20 +1,20 @@
@import '../utils/colors.less'; @import '../utils/colors.less';
@import '../utils/fonts.less'; @import '../utils/fonts.less';
.application.daggerheart.dh-style.dialog { .application.daggerheart.dh-style.dialog {
.window-content { .window-content {
.dialog-header { .dialog-header {
width: 100%; width: 100%;
padding-bottom: 16px; padding-bottom: 16px;
h1 { h1 {
font-family: @font-subtitle; font-family: @font-subtitle;
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
font-size: 24px; font-size: 24px;
margin: 0; margin: 0;
text-align: center; text-align: center;
color: light-dark(@dark-blue, @golden); color: light-dark(@dark-blue, @golden);
} }
} }
} }
} }

View file

@ -1,7 +1,7 @@
@import './header.less'; @import './header.less';
@import './adversary-settings/sheet.less'; @import './adversary-settings/sheet.less';
@import './adversary-settings/experiences.less'; @import './adversary-settings/experiences.less';
@import './adversary-settings/features.less'; @import './adversary-settings/features.less';
@import './environment-settings/features.less'; @import './environment-settings/features.less';
@import './environment-settings/adversaries.less'; @import './environment-settings/adversaries.less';

View file

@ -1,80 +1,80 @@
@import '../../../utils/colors.less'; @import '../../../utils/colors.less';
@import '../../../utils/fonts.less'; @import '../../../utils/fonts.less';
.application.sheet.daggerheart.actor.dh-style.adversary { .application.sheet.daggerheart.actor.dh-style.adversary {
.adversary-header-sheet { .adversary-header-sheet {
padding: 0 15px; padding: 0 15px;
padding-top: 36px; padding-top: 36px;
width: 100%; width: 100%;
.name-row { .name-row {
display: flex; display: flex;
gap: 5px; gap: 5px;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
padding: 0; padding: 0;
padding-top: 5px; padding-top: 5px;
padding-bottom: 8px; padding-bottom: 8px;
flex: 1; flex: 1;
input[type='text'] { input[type='text'] {
font-size: 32px; font-size: 32px;
height: 42px; height: 42px;
text-align: start; text-align: start;
border: 1px solid transparent; border: 1px solid transparent;
outline: 2px solid transparent; outline: 2px solid transparent;
transition: all 0.3s ease; transition: all 0.3s ease;
&:hover { &:hover {
outline: 2px solid light-dark(@dark, @golden); outline: 2px solid light-dark(@dark, @golden);
} }
} }
} }
.tags { .tags {
display: flex; display: flex;
gap: 10px; gap: 10px;
padding-bottom: 16px; padding-bottom: 16px;
.tag { .tag {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 3px 5px; padding: 3px 5px;
font-size: 12px; font-size: 12px;
font: @font-body; font: @font-body;
background: light-dark(@dark-15, @beige-15); background: light-dark(@dark-15, @beige-15);
border: 1px solid light-dark(@dark, @beige); border: 1px solid light-dark(@dark, @beige);
border-radius: 3px; border-radius: 3px;
} }
.label { .label {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size: 12px; font-size: 12px;
} }
} }
.adversary-info { .adversary-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px; gap: 12px;
padding: 16px 0; padding: 16px 0;
.description, .description,
.motives-and-tatics { .motives-and-tatics {
font-family: @font-body; font-family: @font-body;
} }
} }
.adversary-navigation { .adversary-navigation {
display: flex; display: flex;
gap: 8px; gap: 8px;
align-items: center; align-items: center;
} }
} }
} }

View file

@ -1,28 +1,28 @@
@import '../../../utils/colors.less'; @import '../../../utils/colors.less';
@import '../../../utils/fonts.less'; @import '../../../utils/fonts.less';
.application.sheet.daggerheart.actor.dh-style.adversary { .application.sheet.daggerheart.actor.dh-style.adversary {
.window-content { .window-content {
display: grid; display: grid;
grid-template-columns: 275px 1fr; grid-template-columns: 275px 1fr;
grid-template-rows: auto 1fr; grid-template-rows: auto 1fr;
gap: 15px 0; gap: 15px 0;
height: 100%; height: 100%;
width: 100%; width: 100%;
.adversary-sidebar-sheet { .adversary-sidebar-sheet {
grid-row: 1 / span 2; grid-row: 1 / span 2;
grid-column: 1; grid-column: 1;
} }
.adversary-header-sheet { .adversary-header-sheet {
grid-row: 1; grid-row: 1;
grid-column: 2; grid-column: 2;
} }
.tab { .tab {
grid-row: 2; grid-row: 2;
grid-column: 2; grid-column: 2;
} }
} }
} }

View file

@ -1,351 +1,351 @@
@import '../../../utils/colors.less'; @import '../../../utils/colors.less';
@import '../../../utils/fonts.less'; @import '../../../utils/fonts.less';
@import '../../../utils/mixin.less'; @import '../../../utils/mixin.less';
.appTheme({ .appTheme({
&.adversary { &.adversary {
.adversary-sidebar-sheet { .adversary-sidebar-sheet {
background-image: url('../assets/parchments/dh-parchment-dark.png'); background-image: url('../assets/parchments/dh-parchment-dark.png');
} }
} }
}, { }, {
&.adversary { &.adversary {
.adversary-sidebar-sheet { .adversary-sidebar-sheet {
background: transparent; background: transparent;
} }
} }
}); });
.application.sheet.daggerheart.actor.dh-style.adversary { .application.sheet.daggerheart.actor.dh-style.adversary {
.adversary-sidebar-sheet { .adversary-sidebar-sheet {
width: 275px; width: 275px;
min-width: 275px; min-width: 275px;
border-right: 1px solid light-dark(@dark-blue, @golden); border-right: 1px solid light-dark(@dark-blue, @golden);
.portrait { .portrait {
position: relative; position: relative;
border-bottom: 1px solid light-dark(@dark-blue, @golden); border-bottom: 1px solid light-dark(@dark-blue, @golden);
cursor: pointer; cursor: pointer;
img { img {
height: 235px; height: 235px;
width: 275px; width: 275px;
object-fit: cover; object-fit: cover;
} }
.death-roll-btn { .death-roll-btn {
display: none; display: none;
} }
&.death-roll { &.death-roll {
filter: grayscale(1); filter: grayscale(1);
.death-roll-btn { .death-roll-btn {
display: flex; display: flex;
position: absolute; position: absolute;
top: 30%; top: 30%;
right: 30%; right: 30%;
font-size: 6rem; font-size: 6rem;
color: @beige; color: @beige;
&:hover { &:hover {
text-shadow: 0 0 8px @beige; text-shadow: 0 0 8px @beige;
} }
} }
} }
} }
.threshold-section { .threshold-section {
position: relative; position: relative;
display: flex; display: flex;
gap: 10px; gap: 10px;
background-color: light-dark(transparent, @dark-blue); background-color: light-dark(transparent, @dark-blue);
color: light-dark(@dark-blue, @golden); color: light-dark(@dark-blue, @golden);
padding: 5px 10px; padding: 5px 10px;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
align-items: center; align-items: center;
width: fit-content; width: fit-content;
height: 30px; height: 30px;
margin-top: 16px; margin-top: 16px;
h4 { h4 {
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
text-transform: uppercase; text-transform: uppercase;
color: light-dark(@dark-blue, @golden); color: light-dark(@dark-blue, @golden);
&.threshold-value { &.threshold-value {
color: light-dark(@dark, @beige); color: light-dark(@dark, @beige);
} }
} }
.threshold-legend { .threshold-legend {
position: absolute; position: absolute;
bottom: -21px; bottom: -21px;
color: light-dark(@golden, @dark-blue); color: light-dark(@golden, @dark-blue);
background-color: light-dark(@dark-blue, @golden); background-color: light-dark(@dark-blue, @golden);
padding: 3px; padding: 3px;
justify-self: anchor-center; justify-self: anchor-center;
border-radius: 0 0 3px 3px; border-radius: 0 0 3px 3px;
text-transform: capitalize; text-transform: capitalize;
} }
.hope-value { .hope-value {
display: flex; display: flex;
cursor: pointer; cursor: pointer;
} }
} }
.info-section { .info-section {
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
top: -20px; top: -20px;
gap: 16px; gap: 16px;
margin-bottom: -10px; margin-bottom: -10px;
.resources-section { .resources-section {
display: flex; display: flex;
justify-content: space-evenly; justify-content: space-evenly;
.status-bar { .status-bar {
position: relative; position: relative;
width: 100px; width: 100px;
height: 40px; height: 40px;
justify-items: center; justify-items: center;
.status-label { .status-label {
position: relative; position: relative;
top: 40px; top: 40px;
height: 22px; height: 22px;
width: 79px; width: 79px;
clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z'); clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z');
background: light-dark(@dark-blue, @golden); background: light-dark(@dark-blue, @golden);
h4 { h4 {
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
line-height: 18px; line-height: 18px;
color: light-dark(@beige, @dark-blue); color: light-dark(@beige, @dark-blue);
} }
} }
.status-value { .status-value {
position: absolute; position: absolute;
display: flex; display: flex;
padding: 0 6px; padding: 0 6px;
font-size: 1.5rem; font-size: 1.5rem;
align-items: center; align-items: center;
width: 100px; width: 100px;
height: 40px; height: 40px;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
z-index: 2; z-index: 2;
color: @beige; color: @beige;
input[type='number'] { input[type='number'] {
background: transparent; background: transparent;
font-size: 1.5rem; font-size: 1.5rem;
width: 40px; width: 40px;
height: 30px; height: 30px;
text-align: center; text-align: center;
border: none; border: none;
outline: 2px solid transparent; outline: 2px solid transparent;
color: @beige; color: @beige;
&.bar-input { &.bar-input {
padding: 0; padding: 0;
color: @beige; color: @beige;
backdrop-filter: none; backdrop-filter: none;
background: transparent; background: transparent;
transition: all 0.3s ease; transition: all 0.3s ease;
&:hover, &:hover,
&:focus { &:focus {
background: @semi-transparent-dark-blue; background: @semi-transparent-dark-blue;
backdrop-filter: blur(9.5px); backdrop-filter: blur(9.5px);
} }
} }
} }
.bar-label { .bar-label {
width: 40px; width: 40px;
} }
} }
.progress-bar { .progress-bar {
position: absolute; position: absolute;
appearance: none; appearance: none;
width: 100px; width: 100px;
height: 40px; height: 40px;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-radius: 6px; border-radius: 6px;
z-index: 1; z-index: 1;
background: @dark-blue; background: @dark-blue;
&::-webkit-progress-bar { &::-webkit-progress-bar {
border: none; border: none;
background: @dark-blue; background: @dark-blue;
border-radius: 6px; border-radius: 6px;
} }
&::-webkit-progress-value { &::-webkit-progress-value {
background: @gradient-hp; background: @gradient-hp;
border-radius: 6px; border-radius: 6px;
} }
&.stress-color::-webkit-progress-value { &.stress-color::-webkit-progress-value {
background: @gradient-stress; background: @gradient-stress;
border-radius: 6px; border-radius: 6px;
} }
&::-moz-progress-bar { &::-moz-progress-bar {
background: @gradient-hp; background: @gradient-hp;
border-radius: 6px; border-radius: 6px;
} }
&.stress-color::-moz-progress-bar { &.stress-color::-moz-progress-bar {
background: @gradient-stress; background: @gradient-stress;
border-radius: 6px; border-radius: 6px;
} }
} }
} }
} }
.status-section { .status-section {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 10px; gap: 10px;
justify-content: center; justify-content: center;
.status-number { .status-number {
justify-items: center; justify-items: center;
.status-value { .status-value {
position: relative; position: relative;
display: flex; display: flex;
width: 50px; width: 50px;
height: 30px; height: 30px;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-bottom: none; border-bottom: none;
border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0;
padding: 0 6px; padding: 0 6px;
font-size: 1.2rem; font-size: 1.2rem;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: light-dark(transparent, @dark-blue); background: light-dark(transparent, @dark-blue);
z-index: 2; z-index: 2;
&.armor-slots { &.armor-slots {
width: 80px; width: 80px;
height: 30px; height: 30px;
} }
} }
.status-label { .status-label {
padding: 2px 10px; padding: 2px 10px;
width: 100%; width: 100%;
border-radius: 3px; border-radius: 3px;
background: light-dark(@dark-blue, @golden); background: light-dark(@dark-blue, @golden);
h4 { h4 {
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
line-height: 18px; line-height: 18px;
font-size: 12px; font-size: 12px;
color: light-dark(@beige, @dark-blue); color: light-dark(@beige, @dark-blue);
} }
} }
} }
} }
} }
.items-sidebar-list { .items-sidebar-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; gap: 5px;
.inventory-item { .inventory-item {
padding: 0 10px; padding: 0 10px;
} }
} }
.attack-section { .attack-section {
.title { .title {
display: flex; display: flex;
gap: 15px; gap: 15px;
align-items: center; align-items: center;
h3 { h3 {
font-size: 20px; font-size: 20px;
} }
} }
.items-list { .items-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 10px; gap: 10px;
align-items: center; align-items: center;
} }
} }
.experience-section { .experience-section {
margin-bottom: 20px; margin-bottom: 20px;
.title { .title {
display: flex; display: flex;
gap: 15px; gap: 15px;
align-items: center; align-items: center;
h3 { h3 {
font-size: 20px; font-size: 20px;
} }
} }
.experience-list { .experience-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 5px; gap: 5px;
width: 100%; width: 100%;
margin-top: 10px; margin-top: 10px;
align-items: center; align-items: center;
.experience-row { .experience-row {
display: flex; display: flex;
gap: 5px; gap: 5px;
width: 250px; width: 250px;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
.experience-name { .experience-name {
width: 180px; width: 180px;
text-align: start; text-align: start;
font-size: 14px; font-size: 14px;
font-family: @font-body; font-family: @font-body;
color: light-dark(@dark, @beige); color: light-dark(@dark, @beige);
} }
} }
.experience-value { .experience-value {
height: 25px; height: 25px;
width: 35px; width: 35px;
font-size: 14px; font-size: 14px;
font-family: @font-body; font-family: @font-body;
color: light-dark(@dark, @beige); color: light-dark(@dark, @beige);
align-content: center; align-content: center;
text-align: center; text-align: center;
background: url(../assets/svg/experience-shield.svg) no-repeat; background: url(../assets/svg/experience-shield.svg) no-repeat;
.theme-light & { .theme-light & {
background: url('../assets/svg/experience-shield-light.svg') no-repeat; background: url('../assets/svg/experience-shield-light.svg') no-repeat;
} }
} }
} }
} }
.reaction-section { .reaction-section {
display: flex; display: flex;
padding: 0 10px; padding: 0 10px;
margin-top: 20px; margin-top: 20px;
width: 100%; width: 100%;
button { button {
width: 100%; width: 100%;
} }
} }
} }
} }

View file

@ -1,140 +1,140 @@
@import '../../../utils/colors.less'; @import '../../../utils/colors.less';
@import '../../../utils/fonts.less'; @import '../../../utils/fonts.less';
.application.sheet.daggerheart.actor.dh-style.environment { .application.sheet.daggerheart.actor.dh-style.environment {
.environment-header-sheet { .environment-header-sheet {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: start; justify-content: start;
text-align: center; text-align: center;
.profile { .profile {
width: 100%; width: 100%;
height: 235px; height: 235px;
object-fit: cover; object-fit: cover;
mask-image: linear-gradient(0deg, transparent 0%, black 10%); mask-image: linear-gradient(0deg, transparent 0%, black 10%);
cursor: pointer; cursor: pointer;
} }
.item-container { .item-container {
display: flex; display: flex;
align-items: center; align-items: center;
position: relative; position: relative;
top: -45px; top: -45px;
gap: 20px; gap: 20px;
padding: 0 20px; padding: 0 20px;
margin-bottom: -30px; margin-bottom: -30px;
.item-info { .item-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 8px; gap: 8px;
.tags { .tags {
display: flex; display: flex;
gap: 10px; gap: 10px;
padding-bottom: 0; padding-bottom: 0;
.tag { .tag {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 3px 5px; padding: 3px 5px;
font-size: 12px; font-size: 12px;
font: @font-body; font: @font-body;
background: light-dark(@dark-15, @beige-15); background: light-dark(@dark-15, @beige-15);
border: 1px solid light-dark(@dark, @beige); border: 1px solid light-dark(@dark, @beige);
border-radius: 3px; border-radius: 3px;
} }
.label { .label {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size: 12px; font-size: 12px;
} }
} }
} }
.status-number { .status-number {
justify-items: center; justify-items: center;
.status-value { .status-value {
position: relative; position: relative;
display: flex; display: flex;
width: 50px; width: 50px;
height: 30px; height: 30px;
border: 1px solid light-dark(@dark-blue, @golden); border: 1px solid light-dark(@dark-blue, @golden);
border-bottom: none; border-bottom: none;
border-radius: 6px 6px 0 0; border-radius: 6px 6px 0 0;
padding: 0 6px; padding: 0 6px;
font-size: 1.2rem; font-size: 1.2rem;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
background: light-dark(transparent, @dark-blue); background: light-dark(transparent, @dark-blue);
z-index: 2; z-index: 2;
&.armor-slots { &.armor-slots {
width: 80px; width: 80px;
height: 30px; height: 30px;
} }
} }
.status-label { .status-label {
padding: 2px 10px; padding: 2px 10px;
width: 100%; width: 100%;
border-radius: 3px; border-radius: 3px;
background: light-dark(@dark-blue, @golden); background: light-dark(@dark-blue, @golden);
h4 { h4 {
font-weight: bold; font-weight: bold;
text-align: center; text-align: center;
line-height: 18px; line-height: 18px;
font-size: 12px; font-size: 12px;
color: light-dark(@beige, @dark-blue); color: light-dark(@beige, @dark-blue);
} }
} }
} }
.item-name { .item-name {
input[type='text'] { input[type='text'] {
font-size: 32px; font-size: 32px;
height: 42px; height: 42px;
text-align: start; text-align: start;
transition: all 0.3s ease; transition: all 0.3s ease;
outline: 2px solid transparent; outline: 2px solid transparent;
border: 1px solid transparent; border: 1px solid transparent;
&:hover[type='text'], &:hover[type='text'],
&:focus[type='text'] { &:focus[type='text'] {
box-shadow: none; box-shadow: none;
outline: 2px solid light-dark(@dark-blue, @golden); outline: 2px solid light-dark(@dark-blue, @golden);
} }
} }
} }
} }
.environment-info { .environment-info {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 12px; gap: 12px;
padding: 10px 20px; padding: 10px 20px;
.description, .description,
.impulses { .impulses {
text-align: start; text-align: start;
font-family: @font-body; font-family: @font-body;
} }
} }
.environment-navigation { .environment-navigation {
display: flex; display: flex;
gap: 20px; gap: 20px;
align-items: center; align-items: center;
padding: 0 20px; padding: 0 20px;
} }
} }
} }

View file

@ -1,23 +1,23 @@
@import './actors/adversary/actions.less'; @import './actors/adversary/actions.less';
@import './actors/adversary/header.less'; @import './actors/adversary/header.less';
@import './actors/adversary/sheet.less'; @import './actors/adversary/sheet.less';
@import './actors/adversary/sidebar.less'; @import './actors/adversary/sidebar.less';
@import './actors/character/biography.less'; @import './actors/character/biography.less';
@import './actors/character/features.less'; @import './actors/character/features.less';
@import './actors/character/header.less'; @import './actors/character/header.less';
@import './actors/character/inventory.less'; @import './actors/character/inventory.less';
@import './actors/character/loadout.less'; @import './actors/character/loadout.less';
@import './actors/character/sheet.less'; @import './actors/character/sheet.less';
@import './actors/character/sidebar.less'; @import './actors/character/sidebar.less';
@import './actors/companion/details.less'; @import './actors/companion/details.less';
@import './actors/companion/header.less'; @import './actors/companion/header.less';
@import './actors/companion/sheet.less'; @import './actors/companion/sheet.less';
@import './actors/environment/header.less'; @import './actors/environment/header.less';
@import './actors/environment/sheet.less'; @import './actors/environment/sheet.less';
@import './items/class.less'; @import './items/class.less';
@import './items/domain-card.less'; @import './items/domain-card.less';
@import './items/feature.less'; @import './items/feature.less';

View file

@ -1,33 +1,33 @@
.chat-message { .chat-message {
.duality-modifiers, .duality-modifiers,
.duality-result, .duality-result,
.dice-title { .dice-title {
display: none; display: none;
} }
} }
fieldset.daggerheart.chat { fieldset.daggerheart.chat {
padding: 0; padding: 0;
border-left-width: 0; border-left-width: 0;
border-right-width: 0; border-right-width: 0;
border-bottom-width: 0; border-bottom-width: 0;
legend { legend {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 5px; gap: 5px;
&:before, &:before,
&:after { &:after {
content: '\f0d8'; content: '\f0d8';
font-family: 'Font Awesome 6 Pro'; font-family: 'Font Awesome 6 Pro';
} }
} }
&.expanded { &.expanded {
legend:before, legend:before,
legend:after { legend:after {
content: '\f0d7'; content: '\f0d7';
} }
} }
.daggerheart.chat { .daggerheart.chat {
margin-top: 5px; margin-top: 5px;
} }
} }

View file

@ -1,193 +1,193 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
@import '../../utils/spacing.less'; @import '../../utils/spacing.less';
.theme-colorful { .theme-colorful {
.chat-message.duality { .chat-message.duality {
border-color: black; border-color: black;
padding: 8px 0 0 0; padding: 8px 0 0 0;
fieldset.daggerheart.chat { fieldset.daggerheart.chat {
border-top-width: 0; border-top-width: 0;
display: contents; display: contents;
legend { legend {
&:before, &:before,
&:after { &:after {
display: none; display: none;
} }
} }
} }
.message-header { .message-header {
color: var(--color-light-3); color: var(--color-light-3);
padding: 0 8px; padding: 0 8px;
} }
&.hope { &.hope {
background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6)); background: linear-gradient(0, rgba(165, 42, 42, 0.6) 40px, rgba(0, 0, 0, 0.6));
} }
&.fear { &.fear {
background: linear-gradient(0, @fearBackgroundEnd, @fearBackgroundStart); background: linear-gradient(0, @fearBackgroundEnd, @fearBackgroundStart);
} }
&.critical { &.critical {
background: linear-gradient(0, @criticalBackgroundEnd, @criticalBackgroundStart); background: linear-gradient(0, @criticalBackgroundEnd, @criticalBackgroundStart);
} }
.chat-message header { .chat-message header {
color: var(--color-light-3); color: var(--color-light-3);
} }
> * { > * {
padding: 0 8px; padding: 0 8px;
} }
.message-content { .message-content {
.duality-modifiers, .duality-modifiers,
.duality-result, .duality-result,
.dice-title { .dice-title {
display: flex; display: flex;
} }
.duality-modifiers { .duality-modifiers {
display: flex; display: flex;
gap: 2px; gap: 2px;
margin-bottom: 4px; margin-bottom: 4px;
.duality-modifier { .duality-modifier {
padding: 2px; padding: 2px;
border-radius: 6px; border-radius: 6px;
border: 1px solid; border: 1px solid;
background: var(--color-dark-6); background: var(--color-dark-6);
font-size: 12px; font-size: 12px;
} }
} }
.dice-flavor { .dice-flavor {
color: var(--color-light-1); color: var(--color-light-1);
text-shadow: 0 0 1px black; text-shadow: 0 0 1px black;
border-bottom: 1px solid; border-bottom: 1px solid;
display: flex; display: flex;
align-items: end; align-items: end;
justify-content: space-between; justify-content: space-between;
padding: 0 8px; padding: 0 8px;
margin: 0 -8px 2px; margin: 0 -8px 2px;
font-weight: unset; font-weight: unset;
} }
.dice-result { .dice-result {
.duality-modifiers { .duality-modifiers {
display: flex; // Default => display: none; display: flex; // Default => display: none;
gap: 2px; gap: 2px;
margin-bottom: 4px; margin-bottom: 4px;
.duality-modifier { .duality-modifier {
padding: 2px; padding: 2px;
border-radius: 6px; border-radius: 6px;
border: 1px solid; border: 1px solid;
background: var(--color-dark-6); background: var(--color-dark-6);
font-size: 12px; font-size: 12px;
} }
} }
.dice-formula, .dice-formula,
> .dice-total, > .dice-total,
.part-header { .part-header {
display: none; display: none;
} }
.dice-tooltip { .dice-tooltip {
grid-template-rows: 1fr; grid-template-rows: 1fr;
.wrapper { .wrapper {
.tooltip-part { .tooltip-part {
display: flex; display: flex;
align-items: end; align-items: end;
gap: 0.25rem; gap: 0.25rem;
.dice { .dice {
.dice-rolls { .dice-rolls {
margin-bottom: 0; margin-bottom: 0;
&.duality { &.duality {
li { li {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: relative; position: relative;
background: unset; background: unset;
line-height: unset; line-height: unset;
font-weight: unset; font-weight: unset;
} }
} }
} }
} }
.duality-modifier { .duality-modifier {
display: flex; display: flex;
margin-bottom: 6px; margin-bottom: 6px;
color: var(--color-light-1); color: var(--color-light-1);
text-shadow: 0 0 1px black; text-shadow: 0 0 1px black;
font-size: var(--font-size-16); font-size: var(--font-size-16);
} }
} }
} }
} }
.target-selection { .target-selection {
label { label {
color: var(--color-light-1); color: var(--color-light-1);
} }
} }
.target-section { .target-section {
margin: 4px 0; margin: 4px 0;
border: 2px solid; border: 2px solid;
margin-top: 5px; margin-top: 5px;
.dice-total { .dice-total {
box-shadow: unset; box-shadow: unset;
border: unset; border: unset;
border-radius: unset; border-radius: unset;
font-size: var(--font-size-18); font-size: var(--font-size-18);
} }
} }
.dice-actions { .dice-actions {
justify-content: space-between; justify-content: space-between;
&.duality-alone { &.duality-alone {
justify-content: end; justify-content: end;
margin-top: -20px; margin-top: -20px;
} }
> * { > * {
display: flex; display: flex;
color: var(--color-light-1); color: var(--color-light-1);
text-shadow: 0 0 1px black; text-shadow: 0 0 1px black;
font-weight: bold; font-weight: bold;
background: var(--color-dark-1); background: var(--color-dark-1);
padding: 4px; padding: 4px;
border-color: black; border-color: black;
min-height: unset; min-height: unset;
height: 26px; height: 26px;
flex: unset; flex: unset;
margin: 0; margin: 0;
} }
.duality-action { .duality-action {
border-radius: 0 6px 0 0; border-radius: 0 6px 0 0;
margin-left: -8px; margin-left: -8px;
&.duality-action-effect { &.duality-action-effect {
border-top-left-radius: 6px; border-top-left-radius: 6px;
margin-left: initial; margin-left: initial;
} }
} }
.duality-result { .duality-result {
border-radius: 6px 0 0 0; border-radius: 6px 0 0 0;
margin-right: -8px; margin-right: -8px;
} }
} }
.duality-result { .duality-result {
display: flex; display: flex;
color: var(--color-light-1); color: var(--color-light-1);
text-shadow: 0 0 1px black; text-shadow: 0 0 1px black;
font-weight: bold; font-weight: bold;
background: var(--color-dark-1); background: var(--color-dark-1);
padding: 4px; padding: 4px;
border-color: black; border-color: black;
min-height: unset; min-height: unset;
height: 26px; height: 26px;
flex: unset; flex: unset;
margin: 0; margin: 0;
margin-left: auto; margin-left: auto;
align-self: center; align-self: center;
border-radius: 6px; border-radius: 6px;
} }
} }
} }
button { button {
&.inner-button { &.inner-button {
color: var(--color-light-1); color: var(--color-light-1);
text-shadow: 0 0 1px black; text-shadow: 0 0 1px black;
font-weight: bold; font-weight: bold;
background: var(--color-dark-1); background: var(--color-dark-1);
border-color: black; border-color: black;
} }
} }
} }
} }

View file

@ -1,6 +1,6 @@
.combat-sidebar { .combat-sidebar {
h4 { h4 {
margin: 0; margin: 0;
text-align: center; text-align: center;
} }
} }

View file

@ -1,5 +1,5 @@
.combat-sidebar { .combat-sidebar {
.combatant-controls { .combatant-controls {
flex: 0; flex: 0;
} }
} }

View file

@ -1,48 +1,48 @@
.combat-sidebar { .combat-sidebar {
.encounter-controls.combat { .encounter-controls.combat {
justify-content: space-between; justify-content: space-between;
.encounter-fear-controls { .encounter-fear-controls {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
.encounter-fear-dice-container { .encounter-fear-dice-container {
display: flex; display: flex;
gap: 2px; gap: 2px;
.encounter-control-fear-container { .encounter-control-fear-container {
display: flex; display: flex;
position: relative; position: relative;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: black; color: black;
.dice { .dice {
height: 22px; height: 22px;
width: 22px; width: 22px;
} }
.encounter-control-fear { .encounter-control-fear {
position: absolute; position: absolute;
font-size: 16px; font-size: 16px;
} }
.encounter-control-counter { .encounter-control-counter {
position: absolute; position: absolute;
right: -10px; right: -10px;
color: var(--color-text-secondary); color: var(--color-text-secondary);
} }
} }
} }
.encounter-countdowns { .encounter-countdowns {
color: var(--content-link-icon-color); color: var(--content-link-icon-color);
} }
} }
.control-buttons { .control-buttons {
width: min-content; width: min-content;
} }
} }
} }

View file

@ -1,19 +1,19 @@
.combat-sidebar { .combat-sidebar {
.spotlight-control { .spotlight-control {
font-size: 26px; font-size: 26px;
&:focus { &:focus {
outline: none; outline: none;
box-shadow: none; box-shadow: none;
} }
&.discrete:hover { &.discrete:hover {
background: inherit; background: inherit;
} }
&.requesting { &.requesting {
filter: drop-shadow(0 0 3px gold); filter: drop-shadow(0 0 3px gold);
color: var(--button-hover-text-color); color: var(--button-hover-text-color);
} }
} }
} }

View file

@ -1,48 +1,48 @@
.combat-sidebar { .combat-sidebar {
.token-actions { .token-actions {
align-self: stretch; align-self: stretch;
display: flex; display: flex;
align-items: top; align-items: top;
justify-content: center; justify-content: center;
gap: 16px; gap: 16px;
.action-tokens { .action-tokens {
display: flex; display: flex;
gap: 4px; gap: 4px;
.action-token { .action-token {
height: 22px; height: 22px;
width: 22px; width: 22px;
border: 1px solid; border: 1px solid;
border-radius: 50%; border-radius: 50%;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 10px; font-size: 10px;
padding: 8px; padding: 8px;
--button-size: 0; --button-size: 0;
&.used { &.used {
opacity: 0.5; opacity: 0.5;
background: transparent; background: transparent;
} }
} }
} }
button { button {
font-size: 22px; font-size: 22px;
height: 24px; height: 24px;
width: 24px; width: 24px;
&.main { &.main {
background: var(--button-hover-background-color); background: var(--button-hover-background-color);
color: var(--button-hover-text-color); color: var(--button-hover-text-color);
border-color: var(--button-hover-border-color); border-color: var(--button-hover-border-color);
&:hover { &:hover {
filter: drop-shadow(0 0 3px var(--button-hover-text-color)); filter: drop-shadow(0 0 3px var(--button-hover-text-color));
} }
} }
} }
} }
} }

View file

@ -1,88 +1,88 @@
@import '../../utils/colors.less'; @import '../../utils/colors.less';
@import '../../utils/fonts.less'; @import '../../utils/fonts.less';
@import '../../utils/mixin.less'; @import '../../utils/mixin.less';
.appTheme({}, { .appTheme({}, {
&.countdown { &.countdown {
.minimized-view .mini-countdown-container { .minimized-view .mini-countdown-container {
background-image: url('../assets/parchments/dh-parchment-dark.png'); background-image: url('../assets/parchments/dh-parchment-dark.png');
} }
} }
}); });
.daggerheart.dh-style.countdown { .daggerheart.dh-style.countdown {
overflow: hidden; overflow: hidden;
.window-content { .window-content {
> div { > div {
height: 100%; height: 100%;
.expanded-view { .expanded-view {
height: 100%; height: 100%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
.countdowns-menu { .countdowns-menu {
display: flex; display: flex;
gap: 8px; gap: 8px;
.flex { .flex {
flex: 1; flex: 1;
} }
} }
.countdowns-container { .countdowns-container {
display: flex; display: flex;
gap: 8px; gap: 8px;
flex-wrap: wrap; flex-wrap: wrap;
overflow: auto; overflow: auto;
max-height: 100%; max-height: 100%;
.countdown-fieldset { .countdown-fieldset {
width: 340px; width: 340px;
height: min-content; height: min-content;
position: relative; position: relative;
.ownership-button { .ownership-button {
position: absolute; position: absolute;
top: 8px; top: 8px;
right: 8px; right: 8px;
font-size: 18px; font-size: 18px;
} }
.countdown-container { .countdown-container {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 16px; gap: 16px;
img { img {
width: 150px; width: 150px;
height: 150px; height: 150px;
cursor: pointer; cursor: pointer;
&.disabled { &.disabled {
cursor: initial; cursor: initial;
} }
} }
.countdown-inner-container { .countdown-inner-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
.countdown-value-container { .countdown-value-container {
display: flex; display: flex;
gap: 4px; gap: 4px;
input { input {
max-width: 80px; max-width: 80px;
} }
} }
} }
} }
} }
} }
} }
} }
} }
} }

View file

@ -1,18 +1,18 @@
@import './chat/chat.less'; @import './chat/chat.less';
@import './chat/sheet.less'; @import './chat/sheet.less';
@import './chat/theme-colorful.less'; @import './chat/theme-colorful.less';
@import './combat-sidebar/combat-sidebar.less'; @import './combat-sidebar/combat-sidebar.less';
@import './combat-sidebar/combatant-controls.less'; @import './combat-sidebar/combatant-controls.less';
@import './combat-sidebar/encounter-controls.less'; @import './combat-sidebar/encounter-controls.less';
@import './combat-sidebar/spotlight-control.less'; @import './combat-sidebar/spotlight-control.less';
@import './combat-sidebar/token-actions.less'; @import './combat-sidebar/token-actions.less';
@import './countdown/countdown.less'; @import './countdown/countdown.less';
@import './countdown/sheet.less'; @import './countdown/sheet.less';
@import './ownership-selection/ownership-selection.less'; @import './ownership-selection/ownership-selection.less';
@import './resources/resources.less'; @import './resources/resources.less';
@import './settings/settings.less'; @import './settings/settings.less';