diff --git a/assets/svg/experience-shield-light.svg b/assets/svg/experience-shield-light.svg
new file mode 100644
index 00000000..bede0e26
--- /dev/null
+++ b/assets/svg/experience-shield-light.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/assets/svg/experience-shield.svg b/assets/svg/experience-shield.svg
new file mode 100644
index 00000000..ffd897ab
--- /dev/null
+++ b/assets/svg/experience-shield.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/assets/svg/trait-shield-light.svg b/assets/svg/trait-shield-light.svg
new file mode 100644
index 00000000..dc6f77c3
--- /dev/null
+++ b/assets/svg/trait-shield-light.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/svg/trait-shield.svg b/assets/svg/trait-shield.svg
new file mode 100644
index 00000000..87c18dd7
--- /dev/null
+++ b/assets/svg/trait-shield.svg
@@ -0,0 +1,3 @@
+
diff --git a/daggerheart.mjs b/daggerheart.mjs
index 002b68f2..6b634ffc 100644
--- a/daggerheart.mjs
+++ b/daggerheart.mjs
@@ -16,7 +16,7 @@ import Resources from './module/applications/resources.mjs';
import { NarrativeCountdowns, registerCountdownApplicationHooks } from './module/applications/countdowns.mjs';
import DHDualityRoll from './module/data/chat-message/dualityRoll.mjs';
import { DualityRollColor } from './module/data/settings/Appearance.mjs';
-import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/applications/roll.mjs'
+import { DHRoll, DualityRoll, D20Roll, DamageRoll, DualityDie } from './module/applications/roll.mjs';
import { DhMeasuredTemplate } from './module/placeables/_module.mjs';
import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs';
import { renderMeasuredTemplate } from './module/enrichers/TemplateEnricher.mjs';
@@ -282,6 +282,11 @@ Hooks.on('renderJournalDirectory', async (tab, html, _, options) => {
const preloadHandlebarsTemplates = async function () {
return foundry.applications.handlebars.loadTemplates([
+ 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs',
+ 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs',
+ 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs',
+ 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs',
+
'systems/daggerheart/templates/sheets/parts/attributes.hbs',
'systems/daggerheart/templates/sheets/parts/defense.hbs',
'systems/daggerheart/templates/sheets/parts/armor.hbs',
diff --git a/lang/en.json b/lang/en.json
index be0bdd91..7297fa5d 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -280,17 +280,17 @@
"SpellcastingTrait": "Spellcasting Trait"
},
"Condition": {
- "Vulnerable": {
- "Name": "Vulnerable",
- "Description": "While a creature is Vulnerable, all rolls targeting them have advantage.\nA creature who is already Vulnerable can’t be made to take the condition again."
+ "vulnerable": {
+ "name": "Vulnerable",
+ "description": "While a creature is Vulnerable, all rolls targeting them have advantage.\nA creature who is already Vulnerable can’t be made to take the condition again."
},
- "Hidden": {
- "Name": "Hidden",
- "Description": "While Hidden, attacks cannot be made directly targeting them nd any rolls against them are at disadvantage.\nWhen a Hidden creature moves or attacks, they are no longer Hidden. However, if a creature is Hidden when they begin making an attack, the roll has advantage; the Hidden condition isn’t cleared until after the attack is resolved."
+ "hidden": {
+ "name": "Hidden",
+ "description": "While Hidden, attacks cannot be made directly targeting them nd any rolls against them are at disadvantage.\nWhen a Hidden creature moves or attacks, they are no longer Hidden. However, if a creature is Hidden when they begin making an attack, the roll has advantage; the Hidden condition isn’t cleared until after the attack is resolved."
},
- "Restrained": {
- "Name": "Restrained",
- "Description": "When an effect makes a creature Restrained, it means they cannot move until this condition is cleared.\nThey can still take actions from their current position."
+ "restrained": {
+ "name": "Restrained",
+ "description": "When an effect makes a creature Restrained, it means they cannot move until this condition is cleared.\nThey can still take actions from their current position."
}
},
"Tiers": {
@@ -1104,6 +1104,8 @@
"PC": {
"Name": "Name",
"Pronouns": "Pronouns",
+ "age": "Age",
+ "faith": "Faith",
"ShortRest": "Take a Short Rest",
"LongRest": "Take a Long Rest",
"Level": "Level",
@@ -1115,7 +1117,9 @@
"Loadout": "Loadout",
"Vault": "Vault",
"Heritage": "Heritage",
- "Story": "Story"
+ "Story": "Story",
+ "biography": "Biography",
+ "effects": "Effects"
},
"Armor": {
"Title": "Active Armor"
@@ -1194,6 +1198,7 @@
"BackgroundTitle": "Background",
"AppearanceTitle": "Appearance",
"ConnectionsTitle": "Connections",
+ "characteristics": "Characteristics",
"Scars": {
"Title": "Scars"
}
@@ -1353,7 +1358,9 @@
},
"Global": {
"Actions": "Actions",
- "Effects": "Effects"
+ "Effects": "Effects",
+ "activeEffects": "Active Effects",
+ "inativeEffects": "Inative Effects"
},
"DomainCard": {
"Type": "Type",
@@ -1444,6 +1451,10 @@
}
},
"Effects": {
+ "duration": {
+ "passive": "Passive",
+ "temporary": "Temporary"
+ },
"Types": {
"health": {
"Name": "Health"
@@ -1469,7 +1480,13 @@
},
"Tooltip": {
"openItemWorld": "Open Item World",
- "delete": "Delete"
+ "sendToChat": "Send to Chat",
+ "moreOptions": "More Options",
+ "equip": "Equip",
+ "unequip": "Unequip",
+ "delete": "Delete",
+ "sendToVault": "Send to Vault",
+ "sendToLoadout": "Send to Loadout"
},
"Actions": {
"Types": {
diff --git a/module/applications/costSelectionDialog.mjs b/module/applications/costSelectionDialog.mjs
index da8af9a2..c1c8e47a 100644
--- a/module/applications/costSelectionDialog.mjs
+++ b/module/applications/costSelectionDialog.mjs
@@ -1,9 +1,10 @@
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
export default class CostSelectionDialog extends HandlebarsApplicationMixin(ApplicationV2) {
- constructor(costs, action, resolve) {
+ constructor(costs, uses, action, resolve) {
super({});
this.costs = costs;
+ this.uses = uses;
this.action = action;
this.resolve = resolve;
}
@@ -41,21 +42,25 @@ export default class CostSelectionDialog extends HandlebarsApplicationMixin(Appl
}
async _prepareContext(_options) {
- const updatedCosts = this.action.calcCosts(this.costs);
+ const updatedCosts = this.action.calcCosts(this.costs),
+ updatedUses = this.action.calcUses(this.uses);
return {
costs: updatedCosts,
- canUse: this.action.getRealCosts(updatedCosts)?.hasCost
+ uses: updatedUses,
+ canUse: this.action.getRealCosts(updatedCosts)?.hasCost && this.action.hasUses(updatedUses)
};
}
static async updateForm(event, _, formData) {
- this.costs = foundry.utils.mergeObject(this.costs, foundry.utils.expandObject(formData.object).costs);
- this.render(true)
+ const data = foundry.utils.expandObject(formData.object);
+ this.costs = foundry.utils.mergeObject(this.costs, data.costs);
+ this.uses = foundry.utils.mergeObject(this.uses, data.uses);
+ this.render(true);
}
static sendCost(event) {
event.preventDefault();
- this.resolve(this.action.getRealCosts(this.costs));
+ this.resolve({ costs: this.action.getRealCosts(this.costs), uses: this.uses });
this.close();
}
-}
\ No newline at end of file
+}
diff --git a/module/applications/roll.mjs b/module/applications/roll.mjs
index c9e0ee5e..02e17be4 100644
--- a/module/applications/roll.mjs
+++ b/module/applications/roll.mjs
@@ -11,19 +11,19 @@ export class DHRoll extends Roll {
super(formula, data, options);
}
- static async build(config={}, message={}) {
+ static async build(config = {}, message = {}) {
const roll = await this.buildConfigure(config, message);
- if(!roll) return;
- await this.buildEvaluate(roll, config, message={});
- await this.buildPost(roll, config, message={});
+ if (!roll) return;
+ await this.buildEvaluate(roll, config, (message = {}));
+ await this.buildPost(roll, config, (message = {}));
return roll;
}
-
- static async buildConfigure(config={}, message={}) {
- config.hooks = [...(config.hooks ?? []), ""];
+
+ static async buildConfigure(config = {}, message = {}) {
+ config.hooks = [...(config.hooks ?? []), ''];
config.dialog ??= {};
- for ( const hook of config.hooks ) {
- if ( Hooks.call(`${SYSTEM.id}.preRoll${hook.capitalize()}`, config, message) === false ) return null;
+ for (const hook of config.hooks) {
+ if (Hooks.call(`${SYSTEM.id}.preRoll${hook.capitalize()}`, config, message) === false) return null;
}
this.applyKeybindings(config);
@@ -32,45 +32,44 @@ export class DHRoll extends Roll {
// if(config.dialog?.configure === false) {
// roll = new this('', config.actor, config);
// } else {
- if(config.dialog.configure !== false) {
+ if (config.dialog.configure !== false) {
// Open Roll Dialog
const DialogClass = config.dialog?.class ?? this.DefaultDialog;
config = await DialogClass.configure(config, message);
- if(!config) return;
+ if (!config) return;
}
let roll = new this(config.formula, config.actor, config);
- for ( const hook of config.hooks ) {
- if ( Hooks.call(`${SYSTEM.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false ) return [];
+ for (const hook of config.hooks) {
+ if (Hooks.call(`${SYSTEM.id}.post${hook.capitalize()}RollConfiguration`, roll, config, message) === false)
+ return [];
}
return roll;
}
-
- static async buildEvaluate(roll, config={}, message={}) {
- if(config.evaluate !== false) await roll.evaluate();
+
+ static async buildEvaluate(roll, config = {}, message = {}) {
+ if (config.evaluate !== false) await roll.evaluate();
this.postEvaluate(roll, config);
}
-
- static async buildPost(roll, config, message) {
- for ( const hook of config.hooks ) {
- if ( Hooks.call(`${SYSTEM.id}.postRoll${hook.capitalize()}`, config, message) === false ) return null;
- }
-
- // Create Chat Message
- if(message.data) {
+ static async buildPost(roll, config, message) {
+ for (const hook of config.hooks) {
+ if (Hooks.call(`${SYSTEM.id}.postRoll${hook.capitalize()}`, config, message) === false) return null;
+ }
+
+ // Create Chat Message
+ if (message.data) {
} else {
const messageData = {};
await this.toMessage(roll, config);
}
}
- static async postEvaluate(roll, config={}) {}
+ static async postEvaluate(roll, config = {}) {}
static async toMessage(roll, config) {
- console.log(config)
- const cls = getDocumentClass("ChatMessage"),
+ const cls = getDocumentClass('ChatMessage'),
msg = {
type: this.messageType,
user: game.user.id,
@@ -80,7 +79,6 @@ export class DHRoll extends Roll {
content: await this.messageTemplate(config),
rolls: [roll]
};
- console.log(msg)
await cls.create(msg);
}
@@ -95,13 +93,13 @@ export class DHRoll extends Roll {
// D20Die
export class DualityDie extends foundry.dice.terms.Die {
- constructor({ number=1, faces=12, ...args }={}) {
+ constructor({ number = 1, faces = 12, ...args } = {}) {
super({ number, faces, ...args });
}
}
export class D20Roll extends DHRoll {
- constructor(formula, data={}, options={}) {
+ constructor(formula, data = {}, options = {}) {
super(formula, data, options);
// console.log(data, options)
// this.options = this._prepareData(data);
@@ -122,21 +120,21 @@ export class D20Roll extends DHRoll {
// static messageTemplate = 'systems/daggerheart/templates/chat/adversary-roll.hbs';
- static messageTemplate = async (config) => {
+ static messageTemplate = async config => {
return 'systems/daggerheart/templates/chat/adversary-roll.hbs';
- }
+ };
static CRITICAL_TRESHOLD = 20;
static DefaultDialog = D20RollDialog;
get d20() {
- if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) this.createBaseDice();
+ if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
return this.terms[0];
}
set d20(faces) {
- if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) this.createBaseDice();
+ if (!(this.terms[0] instanceof foundry.dice.terms.Die)) this.createBaseDice();
this.terms[0].faces = faces;
}
@@ -145,7 +143,7 @@ export class D20Roll extends DHRoll {
}
get isCritical() {
- if ( !this.d20._evaluated ) return;
+ if (!this.d20._evaluated) return;
return this.d20.total >= this.constructor.CRITICAL_TRESHOLD;
}
@@ -163,66 +161,69 @@ export class D20Roll extends DHRoll {
advantage: config.event.altKey,
disadvantage: config.event.ctrlKey
};
-
+
// Should the roll configuration dialog be displayed?
config.dialog.configure ??= !Object.values(keys).some(k => k);
// Determine advantage mode
const advantage = config.advantage || keys.advantage;
const disadvantage = config.disadvantage || keys.disadvantage;
- if ( advantage && !disadvantage ) config.advantage = this.ADV_MODE.ADVANTAGE;
- else if ( !advantage && disadvantage ) config.advantage = this.ADV_MODE.DISADVANTAGE;
+ if (advantage && !disadvantage) config.advantage = this.ADV_MODE.ADVANTAGE;
+ else if (!advantage && disadvantage) config.advantage = this.ADV_MODE.DISADVANTAGE;
else config.advantage = this.ADV_MODE.NORMAL;
}
createBaseDice() {
- if ( this.terms[0] instanceof foundry.dice.terms.Die ) return;
+ if (this.terms[0] instanceof foundry.dice.terms.Die) return;
this.terms[0] = new foundry.dice.terms.Die({ faces: 20 });
}
applyAdvantage() {
- this.d20.modifiers.findSplice(m => ["kh", "kl"].includes(m));
- if ( !this.hasAdvantage && !this.hasAdvantage ) this.number = 1;
+ this.d20.modifiers.findSplice(m => ['kh', 'kl'].includes(m));
+ if (!this.hasAdvantage && !this.hasAdvantage) this.number = 1;
else {
this.d20.number = 2;
- this.d20.modifiers.push(this.hasAdvantage ? "kh" : "kl");
+ this.d20.modifiers.push(this.hasAdvantage ? 'kh' : 'kl');
}
}
// Trait bonus != Adversary
configureModifiers() {
-
this.applyAdvantage();
this.applyBaseBonus();
this.options.experiences?.forEach(m => {
- if(this.options.actor.experiences?.[m]) this.options.roll.modifiers.push(
- {
+ if (this.options.actor.experiences?.[m])
+ this.options.roll.modifiers.push({
label: this.options.actor.experiences[m].description,
value: this.options.actor.experiences[m].total
- }
- );
- })
+ });
+ });
this.options.roll.modifiers?.forEach(m => {
this.terms.push(...this.formatModifier(m.value));
- })
+ });
- if(this.options.extraFormula) this.terms.push(new foundry.dice.terms.OperatorTerm({operator: '+'}), ...this.constructor.parse(this.options.extraFormula, this.getRollData()));
+ if (this.options.extraFormula)
+ this.terms.push(
+ new foundry.dice.terms.OperatorTerm({ operator: '+' }),
+ ...this.constructor.parse(this.options.extraFormula, this.getRollData())
+ );
// this.resetFormula();
}
applyBaseBonus() {
// if(this.options.action) {
- if(this.options.type === "attack") this.terms.push(...this.formatModifier(this.options.actor.system.attack.modifier));
- /* this.options.roll.modifiers?.forEach(m => {
+ if (this.options.type === 'attack')
+ this.terms.push(...this.formatModifier(this.options.actor.system.attack.modifier));
+ /* this.options.roll.modifiers?.forEach(m => {
this.terms.push(...this.formatModifier(m));
}) */
// }
}
- static async postEvaluate(roll, config={}) {
+ static async postEvaluate(roll, config = {}) {
if (config.targets?.length) {
/* targets = config.targets.map(target => {
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
@@ -230,10 +231,10 @@ export class D20Roll extends DHRoll {
return target;
}); */
config.targets.forEach(target => {
- const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion
+ const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion;
target.hit = roll.total >= difficulty;
- })
- } else if(config.roll.difficulty) roll.success = roll.total >= config.roll.difficulty;
+ });
+ } else if (config.roll.difficulty) roll.success = roll.total >= config.roll.difficulty;
// config.roll.advantage = {
// dice: roll.dHope.faces,
// value: roll.dHope.total
@@ -244,8 +245,8 @@ export class D20Roll extends DHRoll {
type: config.advantage,
dice: roll.dAdvantage?.denomination,
value: roll.dAdvantage?.total
- }
- config.roll.modifierTotal = config.roll.modifiers.reduce((a,c) => a + c.value, 0);
+ };
+ config.roll.modifierTotal = config.roll.modifiers.reduce((a, c) => a + c.value, 0);
}
getRollData() {
@@ -254,51 +255,54 @@ export class D20Roll extends DHRoll {
formatModifier(modifier) {
const numTerm = modifier < 0 ? '-' : '+';
- return [new foundry.dice.terms.OperatorTerm({operator: numTerm}), new foundry.dice.terms.NumericTerm({number: Math.abs(modifier)})];
+ return [
+ new foundry.dice.terms.OperatorTerm({ operator: numTerm }),
+ new foundry.dice.terms.NumericTerm({ number: Math.abs(modifier) })
+ ];
}
resetFormula() {
- return this._formula = this.constructor.getFormula(this.terms);
+ return (this._formula = this.constructor.getFormula(this.terms));
}
}
export class DualityRoll extends D20Roll {
- constructor(formula, data={}, options={}) {
+ constructor(formula, data = {}, options = {}) {
super(formula, data, options);
}
static messageType = 'dualityRoll';
// static messageTemplate = 'systems/daggerheart/templates/chat/duality-roll.hbs';
-
- static messageTemplate = async (config) => {
+
+ static messageTemplate = async config => {
return 'systems/daggerheart/templates/chat/duality-roll.hbs';
- }
+ };
static DefaultDialog = D20RollDialog;
get dHope() {
// if ( !(this.terms[0] instanceof foundry.dice.terms.Die) ) return;
- if ( !(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie) ) this.createBaseDice();
+ if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
return this.dice[0];
// return this.#hopeDice;
}
set dHope(faces) {
- if ( !(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie) ) this.createBaseDice();
+ if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
this.terms[0].faces = faces;
// this.#hopeDice = `d${face}`;
}
get dFear() {
// if ( !(this.terms[1] instanceof foundry.dice.terms.Die) ) return;
- if ( !(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie) ) this.createBaseDice();
+ if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
return this.dice[1];
// return this.#fearDice;
}
set dFear(faces) {
- if ( !(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie) ) this.createBaseDice();
+ if (!(this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie)) this.createBaseDice();
this.dice[1].faces = faces;
// this.#fearDice = `d${face}`;
}
@@ -308,17 +312,17 @@ export class DualityRoll extends D20Roll {
}
get isCritical() {
- if ( !this.dHope._evaluated || !this.dFear._evaluated ) return;
+ if (!this.dHope._evaluated || !this.dFear._evaluated) return;
return this.dHope.total === this.dFear.total;
}
get withHope() {
- if(!this._evaluated) return;
+ if (!this._evaluated) return;
return this.dHope.total > this.dFear.total;
}
get withFear() {
- if(!this._evaluated) return;
+ if (!this._evaluated) return;
return this.dHope.total < this.dFear.total;
}
@@ -326,105 +330,110 @@ export class DualityRoll extends D20Roll {
return null;
}
-
-
get totalLabel() {
- const label =
- this.withHope
- ? 'DAGGERHEART.General.Hope'
- : this.withFear
- ? 'DAGGERHEART.General.Fear'
- : 'DAGGERHEART.General.CriticalSuccess';
+ const label = this.withHope
+ ? 'DAGGERHEART.General.Hope'
+ : this.withFear
+ ? 'DAGGERHEART.General.Fear'
+ : 'DAGGERHEART.General.CriticalSuccess';
return game.i18n.localize(label);
}
createBaseDice() {
- if ( this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie && this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie ) return;
- if ( !(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie) ) this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie();
- this.terms[1] = new foundry.dice.terms.OperatorTerm({operator:'+'});
- if ( !(this.dice[2] instanceof CONFIG.Dice.daggerheart.DualityDie) ) this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie();
+ if (
+ this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie &&
+ this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie
+ )
+ return;
+ if (!(this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie))
+ this.terms[0] = new CONFIG.Dice.daggerheart.DualityDie();
+ this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' });
+ if (!(this.dice[2] instanceof CONFIG.Dice.daggerheart.DualityDie))
+ this.terms[2] = new CONFIG.Dice.daggerheart.DualityDie();
}
applyAdvantage() {
const dieFaces = 6,
bardRallyFaces = this.hasBarRally,
- advDie = new foundry.dice.terms.Die({faces: dieFaces});
+ advDie = new foundry.dice.terms.Die({ faces: dieFaces });
// console.log(this.hasAdvantage, this.hasDisadvantage)
- if(this.hasAdvantage || this.hasDisadvantage || bardRallyFaces) this.terms.push(new foundry.dice.terms.OperatorTerm({operator:'+'}));
- if(bardRallyFaces) {
- const rallyDie = new foundry.dice.terms.Die({faces: bardRallyFaces});
- if(this.hasAdvantage) {
- this.terms.push(new foundry.dice.terms.PoolTerm({
- terms: [advDie.formula, rallyDie.formula],
- modifiers: ["kh"]
- }))
- } else if(this.hasDisadvantage){
- this.terms.push(advDie, new foundry.dice.terms.OperatorTerm({operator:'+'}), rallyDie);
+ if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces)
+ this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: '+' }));
+ if (bardRallyFaces) {
+ const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces });
+ if (this.hasAdvantage) {
+ this.terms.push(
+ new foundry.dice.terms.PoolTerm({
+ terms: [advDie.formula, rallyDie.formula],
+ modifiers: ['kh']
+ })
+ );
+ } else if (this.hasDisadvantage) {
+ this.terms.push(advDie, new foundry.dice.terms.OperatorTerm({ operator: '+' }), rallyDie);
}
- } else if(this.hasAdvantage || this.hasDisadvantage) this.terms.push(advDie);
+ } else if (this.hasAdvantage || this.hasDisadvantage) this.terms.push(advDie);
}
applyBaseBonus() {
// if(this.options.action) {
// console.log(this.options, this.options.actor.system.traits[this.options.roll.trait].bonus)
- // console.log(this.options.actor.system);
- /* if(this.options.roll?.trait) this.terms.push(...this.formatModifier(this.options.actor.traits[this.options.roll.trait].total)); */
- if(!this.options.roll.modifiers) this.options.roll.modifiers = [];
- if(this.options.roll?.trait) this.options.roll.modifiers.push(
- {
- label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
- value: this.options.actor.traits[this.options.roll.trait].total
- }
- );
- console.log(this.options)
+ // console.log(this.options.actor.system);
+ /* if(this.options.roll?.trait) this.terms.push(...this.formatModifier(this.options.actor.traits[this.options.roll.trait].total)); */
+ if (!this.options.roll.modifiers) this.options.roll.modifiers = [];
+ if (this.options.roll?.trait)
+ this.options.roll.modifiers.push({
+ label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
+ value: this.options.actor.traits[this.options.roll.trait].total
+ });
+ console.log(this.options);
// } else if(this.options.trait) this.terms.push(...this.formatModifier(this.options.actor.system.traits[this.options.roll.trait].total));
}
- static async postEvaluate(roll, config={}) {
- console.log(roll,config);
+ static async postEvaluate(roll, config = {}) {
+ console.log(roll, config);
super.postEvaluate(roll, config);
config.roll.hope = {
dice: roll.dHope.denomination,
value: roll.dHope.total
- }
+ };
config.roll.fear = {
dice: roll.dFear.denomination,
value: roll.dFear.total
- }
+ };
config.roll.result = {
duality: roll.withHope ? 1 : roll.withFear ? -1 : 0,
total: roll.dHope.total + roll.dFear.total,
label: roll.totalLabel
- }
+ };
}
}
export class DamageRoll extends DHRoll {
- constructor(formula, data={}, options={}) {
- super(formula, data, options)
+ constructor(formula, data = {}, options = {}) {
+ super(formula, data, options);
}
static messageType = 'damageRoll';
// static messageTemplate = 'systems/daggerheart/templates/chat/damage-roll.hbs';
- static messageTemplate = async (config) => {
+ static messageTemplate = async config => {
return await foundry.applications.handlebars.renderTemplate(
config.messageTemplate ?? 'systems/daggerheart/templates/chat/damage-roll.hbs',
config
- )
- }
+ );
+ };
static DefaultDialog = DamageDialog;
-
- static async postEvaluate(roll, config={}) {
- console.log(roll, config)
+
+ static async postEvaluate(roll, config = {}) {
+ console.log(roll, config);
config.roll = {
// formula : config.formula,
result: roll.total,
dice: roll.dice
- }
- if(roll.healing) config.roll.type = roll.healing.type
+ };
+ if (roll.healing) config.roll.type = roll.healing.type;
/* const dice = [];
const modifiers = [];
for (var i = 0; i < roll.terms.length; i++) {
@@ -444,4 +453,4 @@ export class DamageRoll extends DHRoll {
config.roll.dice = dice;
config.roll.modifiers = modifiers; */
}
-}
\ No newline at end of file
+}
diff --git a/module/applications/sheets/character.mjs b/module/applications/sheets/character.mjs
index 16d88b5b..d88017a7 100644
--- a/module/applications/sheets/character.mjs
+++ b/module/applications/sheets/character.mjs
@@ -16,8 +16,8 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
static DEFAULT_OPTIONS = {
tag: 'form',
- classes: ['daggerheart', 'sheet', 'pc'],
- position: { width: 810, height: 1080 },
+ classes: ['daggerheart', 'sheet', 'actor', 'dh-style', 'daggerheart', 'character'],
+ position: { width: 850, height: 800 },
actions: {
attributeRoll: this.rollAttribute,
toggleMarks: this.toggleMarks,
@@ -47,10 +47,10 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
useAdvancementCard: this.useAdvancementCard,
useAdvancementAbility: this.useAdvancementAbility,
toggleEquipItem: this.toggleEquipItem,
- levelup: this.openLevelUp
+ levelup: this.openLevelUp,
+ editImage: this._onEditImage
},
window: {
- minimizable: false,
resizable: true
},
form: {
@@ -66,9 +66,76 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
};
static PARTS = {
- form: {
- id: 'character',
- template: 'systems/daggerheart/templates/sheets/character/character.hbs'
+ sidebar: {
+ id: 'sidebar',
+ template: 'systems/daggerheart/templates/sheets/actors/character/sidebar.hbs'
+ },
+ header: {
+ id: 'header',
+ template: 'systems/daggerheart/templates/sheets/actors/character/header.hbs'
+ },
+ features: {
+ id: 'features',
+ template: 'systems/daggerheart/templates/sheets/actors/character/features.hbs'
+ },
+ loadout: {
+ id: 'loadout',
+ template: 'systems/daggerheart/templates/sheets/actors/character/loadout.hbs'
+ },
+ inventory: {
+ id: 'inventory',
+ template: 'systems/daggerheart/templates/sheets/actors/character/inventory.hbs'
+ },
+ biography: {
+ id: 'biography',
+ template: 'systems/daggerheart/templates/sheets/actors/character/biography.hbs'
+ },
+ effects: {
+ id: 'effects',
+ template: 'systems/daggerheart/templates/sheets/actors/character/effects.hbs'
+ }
+ };
+
+ static TABS = {
+ features: {
+ active: true,
+ cssClass: '',
+ group: 'primary',
+ id: 'features',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.PC.Tabs.Features'
+ },
+ loadout: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'loadout',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.PC.Tabs.Loadout'
+ },
+ inventory: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'inventory',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.PC.Tabs.Inventory'
+ },
+ biography: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'biography',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.PC.Tabs.biography'
+ },
+ effects: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'effects',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.PC.Tabs.effects'
}
};
@@ -150,17 +217,29 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
_attachPartListeners(partId, htmlElement, options) {
super._attachPartListeners(partId, htmlElement, options);
- htmlElement.querySelector('.level-value').addEventListener('change', this.onLevelChange.bind(this));
+ // htmlElement.querySelector('.level-value').addEventListener('change', this.onLevelChange.bind(this));
// To Remove when ContextMenu Handler is made
htmlElement
.querySelectorAll('[data-item-id]')
.forEach(element => element.addEventListener('contextmenu', this.editItem.bind(this)));
}
+ static _onEditImage() {
+ const fp = new FilePicker({
+ current: this.document.img,
+ type: 'image',
+ redirectToRoot: ['icons/svg/mystery-man.svg'],
+ callback: async path => this._updateImage.bind(this)(path),
+ top: this.position.top + 40,
+ left: this.position.left + 10
+ });
+ return fp.browse();
+ }
+
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
context.document = this.document;
- context.tabs = this._getTabs();
+ context.tabs = super._getTabs(this.constructor.TABS);
context.config = SYSTEM;
@@ -293,7 +372,7 @@ export default class CharacterSheet extends DaggerheartSheet(ActorSheetV2) {
trait: button.dataset.attribute
/* label: abilityLabel,
modifier: button.dataset.value */
- },
+ }
/* chatMessage: {
template: 'systems/daggerheart/templates/chat/duality-roll.hbs'
} */
diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs
index 81784d13..69f7105d 100644
--- a/module/config/generalConfig.mjs
+++ b/module/config/generalConfig.mjs
@@ -93,21 +93,21 @@ export const healingTypes = {
export const conditions = {
vulnerable: {
id: 'vulnerable',
- name: 'DAGGERHEART.Condition.Vulnerable.Name',
+ name: 'DAGGERHEART.Condition.vulnerable.name',
icon: 'icons/magic/control/silhouette-fall-slip-prone.webp',
- description: 'DAGGERHEART.Condition.Vulnerable.Description'
+ description: 'DAGGERHEART.Condition.vulnerable.description'
},
hidden: {
id: 'hidden',
- name: 'DAGGERHEART.Condition.Hidden.Name',
+ name: 'DAGGERHEART.Condition.hidden.name',
icon: 'icons/magic/perception/silhouette-stealth-shadow.webp',
- description: 'DAGGERHEART.Condition.Hidden.Description'
+ description: 'DAGGERHEART.Condition.hidden.description'
},
restrained: {
id: 'restrained',
- name: 'DAGGERHEART.Condition.Restrained.Name',
+ name: 'DAGGERHEART.Condition.restrained.name',
icon: 'icons/magic/control/debuff-chains-shackle-movement-red.webp',
- description: 'DAGGERHEART.Condition.Restrained.Description'
+ description: 'DAGGERHEART.Condition.restrained.description'
}
};
diff --git a/module/data/action/action.mjs b/module/data/action/action.mjs
index 3be1904c..4bbadee8 100644
--- a/module/data/action/action.mjs
+++ b/module/data/action/action.mjs
@@ -109,7 +109,8 @@ export class DHBaseAction extends foundry.abstract.DataModel {
type: new fields.StringField({
choices: SYSTEM.ACTIONS.targetTypes,
initial: SYSTEM.ACTIONS.targetTypes.any.id,
- nullable: true, initial: null
+ nullable: true,
+ initial: null
}),
amount: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 })
}),
@@ -130,8 +131,8 @@ export class DHBaseAction extends foundry.abstract.DataModel {
})
},
extraSchemas = {};
-
- this.extraSchemas.forEach(s => extraSchemas[s] = extraFields[s]);
+
+ this.extraSchemas.forEach(s => (extraSchemas[s] = extraFields[s]));
return extraSchemas;
}
@@ -170,8 +171,8 @@ export class DHBaseAction extends foundry.abstract.DataModel {
trait: parent.system.trait
};
}
- if(parent?.type === 'weapon' && !!this.schema.fields.damage) {
- updateSource['damage'] = {includeBase: true};
+ if (parent?.type === 'weapon' && !!this.schema.fields.damage) {
+ updateSource['damage'] = { includeBase: true };
}
if (parent?.system?.range) {
updateSource['range'] = parent?.system?.range;
@@ -185,9 +186,14 @@ export class DHBaseAction extends foundry.abstract.DataModel {
...actorData.toObject(),
prof: actorData.proficiency?.value ?? 1,
cast: actorData.spellcast?.value ?? 1,
- scale: this.cost.length ? this.cost.reduce((a,c) => {a[c.type] = c.value; return a},{}) : 1,
+ scale: this.cost.length
+ ? this.cost.reduce((a, c) => {
+ a[c.type] = c.value;
+ return a;
+ }, {})
+ : 1,
roll: {}
- }
+ };
}
async use(event, ...args) {
@@ -205,25 +211,30 @@ export class DHBaseAction extends foundry.abstract.DataModel {
};
// this.proceedChatDisplay(config);
-
+
// Filter selected targets based on Target parameters
config.targets = await this.getTarget(config);
- if(!config.targets) return ui.notifications.warn("Too many targets selected for that actions.");
-
+ if (!config.targets) return ui.notifications.warn('Too many targets selected for that actions.');
+
// Filter selected targets based on Range parameters
config.range = await this.checkRange(config);
- if(!config.range.hasRange) return ui.notifications.warn("No Target within range.");
+ if (!config.range.hasRange) return ui.notifications.warn('No Target within range.');
- // Display Costs Dialog & Check if Actor get enough resources
- config.costs = await this.getCost(config);
- if(!this.hasRoll() && !config.costs.hasCost) return ui.notifications.warn("You don't have the resources to use that action.");
+ // Display Uses/Costs Dialog & Check if Actor get enough resources
+ config = {
+ ...config,
+ ...(await this.getCost(config))
+ };
+ if (!this.hasRoll() && (!config.costs.hasCost || !this.hasUses(config.uses)))
+ return ui.notifications.warn("You don't have the resources to use that action.");
// Proceed with Roll
config = await this.proceedRoll(config);
- if(!config) return;
-
+ if (this.roll && !config.roll.result) return;
+
// Update Actor resources based on Action Cost configuration
this.spendCost(config.costs.values);
+ this.spendUses(config.uses);
// console.log(config)
@@ -238,36 +249,37 @@ export class DHBaseAction extends foundry.abstract.DataModel {
async proceedRoll(config) {
if (!this.hasRoll()) return config;
const modifierValue = this.actor.system.traits[this.roll.trait].value;
- config = {
- ...config,
- roll: {
- modifiers: [],
- trait: this.roll?.trait,
- label: game.i18n.localize(abilities[this.roll.trait].label),
- type: this.actionType,
- difficulty: this.roll?.difficulty
- }
+ config = {
+ ...config,
+ roll: {
+ modifiers: [],
+ trait: this.roll?.trait,
+ label: game.i18n.localize(abilities[this.roll.trait].label),
+ type: this.actionType,
+ difficulty: this.roll?.difficulty
}
- return await this.actor.diceRoll(config, this);
+ };
+ // config = await this.actor.diceRoll(config, this);
+ return this.actor.diceRoll(config, this);
}
/* ROLL */
/* COST */
async getCost(config) {
- if(!this.cost?.length || !this.actor) return {values: [], hasCost: true};
- let cost = foundry.utils.deepClone(this.cost);
+ let costs = this.cost?.length ? foundry.utils.deepClone(this.cost) : { values: [], hasCost: true };
+ let uses = this.getUses();
if (!config.event.shiftKey && !this.hasRoll()) {
const dialogClosed = new Promise((resolve, _) => {
- new CostSelectionDialog(cost, this, resolve).render(true);
+ new CostSelectionDialog(costs, uses, this, resolve).render(true);
});
- cost = await dialogClosed;
+ ({ costs, uses } = await dialogClosed);
}
- return cost;
+ return { costs, uses };
}
getRealCosts(costs) {
const realCosts = costs?.length ? costs.filter(c => c.enabled) : [];
- return {values: realCosts, hasCost: this.hasCost(realCosts)}
+ return { values: realCosts, hasCost: this.hasCost(realCosts) };
}
calcCosts(costs) {
@@ -276,44 +288,69 @@ export class DHBaseAction extends foundry.abstract.DataModel {
c.step = c.step ?? 1;
c.total = c.value * c.scale * c.step;
c.enabled = c.hasOwnProperty('enabled') ? c.enabled : true;
- return c
- })
+ return c;
+ });
}
hasCost(costs) {
- return costs.reduce((a, c) => a && this.actor.system.resources[c.type]?.value >= (c.total ?? c.value), true)
+ return costs.reduce((a, c) => a && this.actor.system.resources[c.type]?.value >= (c.total ?? c.value), true);
}
async spendCost(config) {
- if(!config.costs?.values?.length) return;
+ if (!config.costs?.values?.length) return;
return await this.actor.modifyResource(config.costs.values);
}
/* COST */
/* USES */
async spendUses(config) {
- if(!this.uses.max) return;
+ if (!this.uses.max || config.enabled === false) return;
+ const newActions = foundry.utils.getProperty(this.item.system, this.systemPath).map(x => x.toObject());
+ newActions[this.index].uses.value++;
+ await this.item.update({ [`system.${this.systemPath}`]: newActions });
+ }
+ getUses() {
+ if (!this.uses) return { hasUse: true };
+ const uses = foundry.utils.deepClone(this.uses);
+ if (!uses.value) uses.value = 0;
+ return uses;
+ }
+
+ calcUses(uses) {
+ return {
+ ...uses,
+ enabled: uses.hasOwnProperty('enabled') ? uses.enabled : true
+ };
+ }
+
+ hasUses(uses) {
+ return !uses.enabled || uses.value + 1 <= uses.max;
}
/* USES */
-
/* TARGET */
async getTarget(config) {
- if(this.target?.type === SYSTEM.ACTIONS.targetTypes.self.id) return this.formatTarget(this.actor.token ?? this.actor.prototypeToken);
+ if (this.target?.type === SYSTEM.ACTIONS.targetTypes.self.id)
+ return this.formatTarget(this.actor.token ?? this.actor.prototypeToken);
let targets = Array.from(game.user.targets);
// foundry.CONST.TOKEN_DISPOSITIONS.FRIENDLY
- if(this.target?.type && this.target.type !== SYSTEM.ACTIONS.targetTypes.any.id) {
+ if (this.target?.type && this.target.type !== SYSTEM.ACTIONS.targetTypes.any.id) {
targets = targets.filter(t => this.isTargetFriendly(t));
- if(this.target.amount && targets.length > this.target.amount) return false;
+ if (this.target.amount && targets.length > this.target.amount) return false;
}
return targets.map(t => this.formatTarget(t));
}
isTargetFriendly(target) {
- const actorDisposition = this.actor.token ? this.actor.token.disposition : this.actor.prototypeToken.disposition,
+ const actorDisposition = this.actor.token
+ ? this.actor.token.disposition
+ : this.actor.prototypeToken.disposition,
targetDisposition = target.document.disposition;
- return (this.target.type === SYSTEM.ACTIONS.targetTypes.friendly.id && actorDisposition === targetDisposition) || (this.target.type === SYSTEM.ACTIONS.targetTypes.hostile.id && (actorDisposition + targetDisposition === 0))
+ return (
+ (this.target.type === SYSTEM.ACTIONS.targetTypes.friendly.id && actorDisposition === targetDisposition) ||
+ (this.target.type === SYSTEM.ACTIONS.targetTypes.hostile.id && actorDisposition + targetDisposition === 0)
+ );
}
formatTarget(actor) {
@@ -323,57 +360,58 @@ export class DHBaseAction extends foundry.abstract.DataModel {
img: actor.actor.img,
difficulty: actor.actor.system.difficulty,
evasion: actor.actor.system.evasion?.value
- }
+ };
}
/* TARGET */
-
+
/* RANGE */
async checkRange(config) {
- if(!this.range || !this.actor) return true;
- return {values: [], hasRange: true};
+ if (!this.range || !this.actor) return true;
+ return { values: [], hasRange: true };
}
/* RANGE */
/* EFFECTS */
- async applyEffects(event, data, force=false) {
- if(!this.effects?.length || !data.system.targets.length) return;
- data.system.targets.forEach(async (token) => {
+ async applyEffects(event, data, force = false) {
+ if (!this.effects?.length || !data.system.targets.length) return;
+ data.system.targets.forEach(async token => {
// console.log(token, force)
- if(!token.hit && !force) return;
- this.effects.forEach(async (e) => {
+ if (!token.hit && !force) return;
+ this.effects.forEach(async e => {
const actor = canvas.tokens.get(token.id)?.actor,
effect = this.item.effects.get(e._id);
- if(!actor || !effect) return;
+ if (!actor || !effect) return;
await this.applyEffect(effect, actor);
- })
- })
-
+ });
+ });
}
async applyEffect(effect, actor) {
- // Enable an existing effect on the target if it originated from this effect
- const existingEffect = actor.effects.find(e => e.origin === origin.uuid);
- if ( existingEffect ) {
- return existingEffect.update(foundry.utils.mergeObject({
+ // Enable an existing effect on the target if it originated from this effect
+ const existingEffect = actor.effects.find(e => e.origin === origin.uuid);
+ if (existingEffect) {
+ return existingEffect.update(
+ foundry.utils.mergeObject({
...effect.constructor.getInitialDuration(),
disabled: false
- }));
- }
-
- // Otherwise, create a new effect on the target
- const effectData = foundry.utils.mergeObject({
- ...effect.toObject(),
- disabled: false,
- transfer: false,
- origin: origin.uuid
- });
- await ActiveEffect.implementation.create(effectData, { parent: actor });
+ })
+ );
+ }
+
+ // Otherwise, create a new effect on the target
+ const effectData = foundry.utils.mergeObject({
+ ...effect.toObject(),
+ disabled: false,
+ transfer: false,
+ origin: origin.uuid
+ });
+ await ActiveEffect.implementation.create(effectData, { parent: actor });
}
/* EFFECTS */
/* CHAT */
async proceedChatDisplay(config) {
- if(!this.chatDisplay) return;
+ if (!this.chatDisplay) return;
}
/* CHAT */
}
@@ -385,15 +423,14 @@ export class DHDamageAction extends DHBaseAction {
async use(event, ...args) {
const config = await super.use(event, args);
- if(['error', 'warning'].includes(config.type)) return;
- if(!this.directDamage) return;
+ if (!config || ['error', 'warning'].includes(config.type)) return;
+ if (!this.directDamage) return;
return await this.rollDamage(event, config);
}
async rollDamage(event, data) {
- console.log(event, data)
let formula = this.damage.parts.map(p => p.getFormula(this.actor)).join(' + ');
-
+
if (!formula || formula == '') return;
let roll = { formula: formula, total: formula },
bonusDamage = [];
@@ -401,10 +438,15 @@ export class DHDamageAction extends DHBaseAction {
const config = {
title: game.i18n.format('DAGGERHEART.Chat.DamageRoll.Title', { damage: this.name }),
formula,
- targets: (data.system?.targets ?? data.targets).map(x => ({ id: x.id, name: x.name, img: x.img, hit: true }))
- }
+ targets: (data.system?.targets ?? data.targets).map(x => ({
+ id: x.id,
+ name: x.name,
+ img: x.img,
+ hit: true
+ }))
+ };
- roll = CONFIG.Dice.daggerheart.DamageRoll.build(config)
+ roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
}
}
@@ -449,25 +491,32 @@ export class DHHealingAction extends DHBaseAction {
async use(event, ...args) {
const config = await super.use(event, args);
- if(['error', 'warning'].includes(config.type)) return;
- if(this.hasRoll()) return;
+ if (!config || ['error', 'warning'].includes(config.type)) return;
+ if (this.hasRoll()) return;
return await this.rollHealing(event, config);
}
async rollHealing(event, data) {
- console.log(event, data)
+ console.log(event, data);
let formula = this.healing.value.getFormula(this.actor);
-
+
if (!formula || formula == '') return;
let roll = { formula: formula, total: formula },
bonusDamage = [];
const config = {
- title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', { healing: game.i18n.localize(SYSTEM.GENERAL.healingTypes[this.healing.type].label) }),
+ title: game.i18n.format('DAGGERHEART.Chat.HealingRoll.Title', {
+ healing: game.i18n.localize(SYSTEM.GENERAL.healingTypes[this.healing.type].label)
+ }),
formula,
- targets: (data.system?.targets ?? data.targets).map(x => ({ id: x.id, name: x.name, img: x.img, hit: true })),
+ targets: (data.system?.targets ?? data.targets).map(x => ({
+ id: x.id,
+ name: x.name,
+ img: x.img,
+ hit: true
+ })),
messageTemplate: 'systems/daggerheart/templates/chat/healing-roll.hbs'
- }
+ };
roll = CONFIG.Dice.daggerheart.DamageRoll.build(config);
}
@@ -486,13 +535,12 @@ export class DHSummonAction extends DHBaseAction {
}
async use(event, ...args) {
- if ( !this.canSummon || !canvas.scene ) return;
+ if (!this.canSummon || !canvas.scene) return;
const config = await super.use(event, args);
-
}
get canSummon() {
- return game.user.can("TOKEN_CREATE");
+ return game.user.can('TOKEN_CREATE');
}
}
@@ -501,7 +549,7 @@ export class DHEffectAction extends DHBaseAction {
async use(event, ...args) {
const config = await super.use(event, args);
- if(['error', 'warning'].includes(config.type)) return;
+ if (['error', 'warning'].includes(config.type)) return;
return await this.chatApplyEffects(event, config);
}
@@ -545,7 +593,7 @@ export class DHMacroAction extends DHBaseAction {
async use(event, ...args) {
const config = await super.use(event, args);
- if(['error', 'warning'].includes(config.type)) return;
+ if (['error', 'warning'].includes(config.type)) return;
const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID,
macro = await fromUuid(fixUUID);
try {
diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs
index 13ded6a7..98c76c64 100644
--- a/module/data/actor/character.mjs
+++ b/module/data/actor/character.mjs
@@ -62,14 +62,21 @@ export default class DhCharacter extends BaseDataActor {
bags: new fields.NumberField({ initial: 0, integer: true }),
chests: new fields.NumberField({ initial: 0, integer: true })
}),
- pronouns: new fields.StringField({}),
scars: new fields.TypedObjectField(
new fields.SchemaField({
name: new fields.StringField({}),
description: new fields.HTMLField()
})
),
- story: new fields.HTMLField(),
+ biography: new fields.SchemaField({
+ background: new fields.HTMLField(),
+ connections: new fields.HTMLField(),
+ characteristics: new fields.SchemaField({
+ pronouns: new fields.StringField({}),
+ age: new fields.StringField({}),
+ faith: new fields.StringField({})
+ })
+ }),
class: new fields.SchemaField({
value: new ForeignDocumentUUIDField({ type: 'Item', nullable: true }),
subclass: new ForeignDocumentUUIDField({ type: 'Item', nullable: true })
diff --git a/module/dialogs/d20RollDialog.mjs b/module/dialogs/d20RollDialog.mjs
index d2e43e5e..c8485fd7 100644
--- a/module/dialogs/d20RollDialog.mjs
+++ b/module/dialogs/d20RollDialog.mjs
@@ -1,14 +1,16 @@
const { ApplicationV2, HandlebarsApplicationMixin } = foundry.applications.api;
export default class D20RollDialog extends HandlebarsApplicationMixin(ApplicationV2) {
- constructor(config={}, options={}) {
+ constructor(config = {}, options = {}) {
super(options);
this.config = config;
this.config.experiences = [];
-
- this.item = config.actor.parent.items.get(config.source.item);
- this.action = this.item.system.actions.find(a => a._id === config.source.action);
+
+ if (config.source?.action) {
+ this.item = config.actor.parent.items.get(config.source.item);
+ this.action = this.item.system.actions.find(a => a._id === config.source.action);
+ }
}
static DEFAULT_OPTIONS = {
@@ -45,23 +47,30 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
async _prepareContext(_options) {
const context = await super._prepareContext(_options);
- context.experiences = Object.keys(this.config.actor.experiences).map(id => ({ id, ...this.config.actor.experiences[id] }));
+ context.experiences = Object.keys(this.config.actor.experiences).map(id => ({
+ id,
+ ...this.config.actor.experiences[id]
+ }));
context.selectedExperiences = this.config.experiences;
context.advantage = this.config.advantage;
/* context.diceOptions = this.diceOptions; */
context.canRoll = true;
- if(this.config.costs?.length) {
+ if (this.config.costs?.length) {
const updatedCosts = this.action.calcCosts(this.config.costs);
- context.costs = updatedCosts
+ context.costs = updatedCosts;
context.canRoll = this.action.getRealCosts(updatedCosts)?.hasCost;
}
+ if (this.config.uses?.max) {
+ context.uses = this.action.calcUses(this.config.uses);
+ context.canRoll = context.canRoll && this.action.hasUses(context.uses);
+ }
return context;
}
static updateRollConfiguration(event, _, formData) {
const { ...rest } = foundry.utils.expandObject(formData.object);
- console.log(formData.object, rest)
- this.config.costs = foundry.utils.mergeObject(this.config.costs, rest.costs);
+ if (this.config.costs) this.config.costs = foundry.utils.mergeObject(this.config.costs, rest.costs);
+ if (this.config.uses) this.config.uses = foundry.utils.mergeObject(this.config.uses, rest.uses);
this.render();
}
@@ -81,19 +90,19 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio
}
static async submitRoll() {
- await this.close({ submitted: true });
+ await this.close({ submitted: true });
}
/** @override */
- _onClose(options={}) {
- if ( !options.submitted ) this.config = false;
+ _onClose(options = {}) {
+ if (!options.submitted) this.config = false;
}
- static async configure(config={}) {
+ static async configure(config = {}) {
return new Promise(resolve => {
const app = new this(config);
- app.addEventListener("close", () => resolve(app.config), { once: true });
+ app.addEventListener('close', () => resolve(app.config), { once: true });
app.render({ force: true });
});
}
-}
\ No newline at end of file
+}
diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs
index 02643c04..70772ec5 100644
--- a/module/documents/actor.mjs
+++ b/module/documents/actor.mjs
@@ -269,19 +269,11 @@ export default class DhpActor extends Actor {
// console.log(config)
config.source = { ...(config.source ?? {}), actor: this.id };
const newConfig = {
- // data: {
...config,
- /* action, */
- // actor: this.getRollData(),
actor: this.system
- // },
- // options: {
- // dialog: false,
- // },
- // event: config.event
};
- // console.log(this, newConfig)
- const roll = CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(newConfig);
+ const roll =
+ await CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'].build(newConfig);
return config;
/* let hopeDice = 'd12',
fearDice = 'd12',
diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs
index 25dd0e5e..6200b690 100644
--- a/module/helpers/handlebarsHelper.mjs
+++ b/module/helpers/handlebarsHelper.mjs
@@ -13,10 +13,43 @@ export default class RegisterHandlebarsHelpers {
signedNumber: this.signedNumber,
length: this.length,
switch: this.switch,
- case: this.case
+ case: this.case,
+ eq: this.eq,
+ ne: this.ne,
+ lt: this.lt,
+ gt: this.gt,
+ lte: this.lte,
+ gte: this.gte,
+ and: this.and,
+ or: this.or
});
}
+ static eq(v1, v2) {
+ return v1 === v2;
+ }
+ static ne(v1, v2) {
+ return v1 !== v2;
+ }
+ static lt(v1, v2) {
+ return v1 < v2;
+ }
+ static gt(v1, v2) {
+ return v1 > v2;
+ }
+ static lte(v1, v2) {
+ return v1 <= v2;
+ }
+ static gte(v1, v2) {
+ return v1 >= v2;
+ }
+ static and() {
+ return Array.prototype.every.call(arguments, Boolean);
+ }
+ static or() {
+ return Array.prototype.slice.call(arguments, 0, -1).some(Boolean);
+ }
+
static times(nr, block) {
var accum = '';
for (var i = 0; i < nr; ++i) accum += block.fn(i);
@@ -101,7 +134,7 @@ export default class RegisterHandlebarsHelpers {
}
static debug(a) {
- console.log(JSON.stringify(a));
+ console.log(a);
return a;
}
}
diff --git a/styles/daggerheart.css b/styles/daggerheart.css
index 387c7c75..359f0505 100755
--- a/styles/daggerheart.css
+++ b/styles/daggerheart.css
@@ -404,6 +404,8 @@
flex-direction: column;
align-items: flex-start;
border-radius: 6px;
+ height: 100px;
+ width: 100px;
}
.daggerheart.sheet.pc div[data-application-part] .sheet-body .left-main-container .legend {
margin-left: auto;
@@ -3523,6 +3525,553 @@ div.daggerheart.views.multiclass {
.daggerheart.dh-style.setting .trait-array-container .trait-array-item input {
text-align: center;
}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet {
+ padding: 0 15px;
+ padding-top: 36px;
+ width: 100%;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row {
+ display: flex;
+ gap: 20px;
+ align-items: baseline;
+ justify-content: space-between;
+ padding: 0;
+ padding-top: 5px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text'] {
+ font-size: 32px;
+ height: 42px;
+ width: 380px;
+ text-align: start;
+ border: 1px solid transparent;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row input[type='text']:hover {
+ outline: 2px solid light-dark(#222, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .name-row .level-div {
+ white-space: nowrap;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details {
+ display: flex;
+ justify-content: space-between;
+ padding: 5px 0;
+ margin-bottom: 10px;
+ font-size: 12px;
+ color: light-dark(#18162e, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span {
+ padding: 3px;
+ border-radius: 3px;
+ transition: all 0.3s ease;
+ cursor: pointer;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span:hover {
+ background: light-dark(#18162e40, #f3c26740);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-details span.dot {
+ background: transparent;
+ cursor: default;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row {
+ display: flex;
+ gap: 20px;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0;
+ margin-bottom: 15px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section,
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section {
+ position: relative;
+ display: flex;
+ gap: 10px;
+ background-color: light-dark(transparent, #18162e);
+ color: light-dark(#18162e, #f3c267);
+ padding: 5px 10px;
+ border: 1px solid light-dark(#18162e, #f3c267);
+ border-radius: 6px;
+ align-items: center;
+ width: fit-content;
+ height: 30px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4,
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4 {
+ font-size: 14px;
+ font-weight: bold;
+ text-transform: uppercase;
+ color: light-dark(#18162e, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section h4.threshold-value,
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section h4.threshold-value {
+ color: light-dark(#222, #efe6d8);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .threshold-legend,
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .threshold-legend {
+ position: absolute;
+ bottom: -21px;
+ color: light-dark(#f3c267, #18162e);
+ background-color: light-dark(#18162e, #f3c267);
+ padding: 3px;
+ justify-self: anchor-center;
+ border-radius: 0 0 3px 3px;
+ text-transform: capitalize;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .hope-section .hope-value,
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-row .threshold-section .hope-value {
+ display: flex;
+ cursor: pointer;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits {
+ display: flex;
+ justify-content: space-between;
+ padding: 0;
+ margin-bottom: 15px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait {
+ height: 60px;
+ width: 60px;
+ background: url(../assets/svg/trait-shield.svg) no-repeat;
+ cursor: pointer;
+}
+.theme-light .application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait {
+ background: url('../assets/svg/trait-shield-light.svg') no-repeat;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name {
+ display: flex;
+ padding-top: 5px;
+ color: light-dark(#18162e, #f3c267);
+ font-size: 14px;
+ font-weight: 600;
+ align-items: center;
+ justify-content: center;
+ gap: 3px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-name i {
+ line-height: 17px;
+ font-size: 10px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-header-sheet .character-traits .trait .trait-value {
+ font-family: 'Montserrat', sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 20px;
+ text-align: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet {
+ width: 275px;
+ min-width: 275px;
+ border-right: 1px solid light-dark(#18162e, #f3c267);
+ background-image: url('../assets/parchments/dh-parchment-dark.png');
+}
+.theme-light .application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet {
+ background: transparent;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet img {
+ height: 235px;
+ width: 275px;
+ border-bottom: 1px solid light-dark(#18162e, #f3c267);
+ cursor: pointer;
+ object-fit: cover;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ top: -20px;
+ gap: 30px;
+ margin-bottom: -10px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section {
+ display: flex;
+ justify-content: space-evenly;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar {
+ position: relative;
+ width: 100px;
+ height: 40px;
+ justify-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-label {
+ position: relative;
+ top: 40px;
+ height: 22px;
+ width: 79px;
+ clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z');
+ background: light-dark(#18162e, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-label h4 {
+ font-weight: bold;
+ text-align: center;
+ line-height: 18px;
+ color: light-dark(#efe6d8, #18162e);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-value {
+ position: absolute;
+ display: flex;
+ padding: 0 6px;
+ font-size: 1.5rem;
+ align-items: center;
+ width: 100px;
+ height: 40px;
+ justify-content: center;
+ text-align: center;
+ z-index: 2;
+ color: #efe6d8;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'] {
+ background: transparent;
+ font-size: 1.5rem;
+ width: 40px;
+ height: 30px;
+ text-align: center;
+ border: none;
+ outline: 2px solid transparent;
+ color: #efe6d8;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input {
+ padding: 0;
+ color: #efe6d8;
+ backdrop-filter: none;
+ background: transparent;
+ transition: all 0.3s ease;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:hover,
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-value input[type='number'].bar-input:focus {
+ background: rgba(24, 22, 46, 0.33);
+ backdrop-filter: blur(9.5px);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .status-value .bar-label {
+ width: 40px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar {
+ position: absolute;
+ appearance: none;
+ width: 100px;
+ height: 40px;
+ border: 1px solid light-dark(#18162e, #f3c267);
+ border-radius: 6px;
+ z-index: 1;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-bar {
+ border: none;
+ background: #18162e;
+ border-radius: 6px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-webkit-progress-value {
+ background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%);
+ border-radius: 6px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-webkit-progress-value {
+ background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%);
+ border-radius: 6px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-moz-progress-value,
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-moz-progress-bar {
+ border-radius: 6px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar::-moz-progress-bar {
+ background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .resources-section .status-bar .progress-bar.stress-color::-moz-progress-bar {
+ background: linear-gradient(15deg, #823b01 0%, #fc8e45 65%, #be0000 100%);
+ border-radius: 6px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .status-section {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 5px;
+ justify-content: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .status-section .status-number {
+ justify-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .status-section .status-number .status-value {
+ position: relative;
+ display: flex;
+ width: 50px;
+ height: 30px;
+ border: 1px solid light-dark(#18162e, #f3c267);
+ border-bottom: none;
+ border-radius: 6px 6px 0 0;
+ padding: 0 6px;
+ font-size: 1.2rem;
+ align-items: center;
+ justify-content: center;
+ background: light-dark(transparent, #18162e);
+ z-index: 2;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .status-section .status-number .status-value.armor-slots {
+ width: 80px;
+ height: 30px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .status-section .status-number .status-label {
+ padding: 2px 10px;
+ width: 100%;
+ border-radius: 3px;
+ background: light-dark(#18162e, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .info-section .status-section .status-number .status-label h4 {
+ font-weight: bold;
+ text-align: center;
+ line-height: 18px;
+ font-size: 12px;
+ color: light-dark(#efe6d8, #18162e);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .items-sidebar-list {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .items-sidebar-list .inventory-item {
+ padding: 0 10px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .equipment-section .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .equipment-section .title h3 {
+ font-size: 20px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .equipment-section .items-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .loadout-section .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .loadout-section .title h3 {
+ font-size: 20px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .title h3 {
+ font-size: 20px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .experience-list {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ width: 100%;
+ margin-top: 10px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .experience-list .experience-row {
+ display: flex;
+ gap: 5px;
+ width: 250px;
+ align-items: center;
+ justify-content: space-between;
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text'] {
+ height: 32px;
+ width: 180px;
+ border: 1px solid transparent;
+ outline: 2px solid transparent;
+ font-size: 14px;
+ font-family: 'Montserrat', sans-serif;
+ transition: all 0.3s ease;
+ color: light-dark(#222, #efe6d8);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .experience-list .experience-row input[type='text']:hover {
+ outline: 2px solid light-dark(#222, #efe6d8);
+}
+.application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .experience-list .experience-value {
+ height: 25px;
+ width: 35px;
+ font-size: 14px;
+ font-family: 'Montserrat', sans-serif;
+ color: light-dark(#222, #efe6d8);
+ align-content: center;
+ text-align: center;
+ background: url(../assets/svg/experience-shield.svg) no-repeat;
+}
+.theme-light .application.sheet.daggerheart.actor.dh-style.character .character-sidebar-sheet .experience-section .experience-list .experience-value {
+ background: url('../assets/svg/experience-shield-light.svg') no-repeat;
+}
+.application.sheet.daggerheart.actor.dh-style.character .window-content {
+ display: grid;
+ grid-template-columns: 275px 1fr;
+ grid-template-rows: 283px 1fr;
+ gap: 15px 0;
+ height: 100%;
+ width: 100%;
+}
+.application.sheet.daggerheart.actor.dh-style.character .window-content .character-sidebar-sheet {
+ grid-row: 1 / span 2;
+ grid-column: 1;
+}
+.application.sheet.daggerheart.actor.dh-style.character .window-content .character-header-sheet {
+ grid-row: 1;
+ grid-column: 2;
+}
+.application.sheet.daggerheart.actor.dh-style.character .window-content .tab {
+ grid-row: 2;
+ grid-column: 2;
+}
+.application.sheet.daggerheart.actor.dh-style.character .window-content .old-sheet {
+ width: 500px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar {
+ position: relative;
+ color: light-dark(#18162e50, #efe6d850);
+ width: 100%;
+ padding-top: 5px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input {
+ border-radius: 50px;
+ font-family: 'Montserrat', sans-serif;
+ background: light-dark(#18162e10, #f3c26710);
+ border: none;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+ padding: 0 20px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:hover {
+ outline: 2px solid light-dark(#222, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar input:placeholder {
+ color: light-dark(#18162e50, #efe6d850);
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .search-section .search-bar .icon {
+ align-content: center;
+ height: 32px;
+ position: absolute;
+ right: 20px;
+ font-size: 16px;
+ z-index: 1;
+ color: light-dark(#18162e50, #efe6d850);
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .items-section {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
+ padding: 20px 0;
+ height: 80%;
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(#18162e, #f3c267) transparent;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.inventory .currency-section {
+ display: flex;
+ gap: 10px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar {
+ position: relative;
+ color: light-dark(#18162e50, #efe6d850);
+ width: 80%;
+ padding-top: 5px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input {
+ border-radius: 50px;
+ font-family: 'Montserrat', sans-serif;
+ background: light-dark(#18162e10, #f3c26710);
+ border: none;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+ padding: 0 20px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:hover {
+ outline: 2px solid light-dark(#222, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar input:placeholder {
+ color: light-dark(#18162e50, #efe6d850);
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .search-bar .icon {
+ align-content: center;
+ height: 32px;
+ position: absolute;
+ right: 20px;
+ font-size: 16px;
+ z-index: 1;
+ color: light-dark(#18162e50, #efe6d850);
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toogle-view {
+ background: light-dark(#18162e10, #18162e);
+ border: 1px solid light-dark(#18162e, #f3c267);
+ border-radius: 15px;
+ padding: 0;
+ gap: 0;
+ width: 62px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toogle-view span {
+ margin: 1px;
+ width: 26px;
+ color: light-dark(#18162e, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toogle-view span.list-icon i {
+ margin-left: 3px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toogle-view span.grid-icon i {
+ margin-right: 3px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toogle-view span.list-active {
+ border-radius: 32px 3px 3px 32px;
+ background-color: light-dark(#18162e, #f3c267);
+ color: light-dark(#efe6d8, #18162e);
+ padding: 2px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .search-section .btn-toogle-view span.grid-active {
+ border-radius: 3px 32px 32px 3px;
+ background-color: light-dark(#18162e, #f3c267);
+ color: light-dark(#efe6d8, #18162e);
+ padding: 2px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.loadout .items-section {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ height: 100%;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%);
+ padding: 20px 0;
+ height: 90%;
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(#18162e, #f3c267) transparent;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.biography .items-section {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%);
+ padding-bottom: 40px;
+ height: 100%;
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(#18162e, #f3c267) transparent;
+}
+.application.sheet.daggerheart.actor.dh-style.character .tab.features .features-sections {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
+ padding: 20px 0;
+ padding-top: 10px;
+ height: 95%;
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(#18162e, #f3c267) transparent;
+}
.application.sheet.daggerheart.actor.dh-style.adversary .window-content {
overflow: auto;
}
@@ -3602,9 +4151,6 @@ div.daggerheart.views.multiclass {
justify-content: center;
gap: 10px;
}
-.application.sheet.daggerheart.dh-style.class .tab.settings .list-items .item-line .controls a {
- text-shadow: none;
-}
@font-face {
font-family: 'Cinzel';
font-style: normal;
@@ -3703,7 +4249,6 @@ div.daggerheart.views.multiclass {
transition: opacity 0.3s ease;
}
.application.sheet.dh-style.minimized .window-content {
- display: none;
opacity: 0;
transition: opacity 0.1s ease;
}
@@ -3711,26 +4256,38 @@ div.daggerheart.views.multiclass {
opacity: 1;
transition: opacity 0.3s ease;
}
-.application.sheet.dh-style .window-content {
- overflow: initial;
- backdrop-filter: none;
- padding: 0;
-}
.theme-dark .application.sheet.dh-style {
- backdrop-filter: blur(4px);
+ background: rgba(24, 22, 46, 0.33);
+ backdrop-filter: blur(9px);
}
.theme-light .application.sheet.dh-style {
background-image: url('../assets/parchments/dh-parchment-light.png');
background-repeat: no-repeat;
background-position: center;
}
+.application.sheet.daggerheart.dh-style {
+ border-radius: 10px;
+}
.application.sheet.daggerheart.dh-style .window-content {
+ padding: 0;
position: relative;
top: -36px;
+ min-height: -webkit-fill-available;
}
.application.sheet.daggerheart.dh-style .window-content .tab {
padding: 0 10px;
}
+.application.sheet.daggerheart.character.dh-style {
+ border-radius: 10px;
+}
+.application.sheet.daggerheart.character.dh-style .window-content {
+ position: absolute;
+ top: 0;
+}
+.application.sheet.daggerheart.character.dh-style .window-content .tab {
+ padding: 0 15px;
+ overflow-y: hidden;
+}
.application.sheet.dh-style {
border: 1px solid light-dark(#18162e, #f3c267);
}
@@ -3805,19 +4362,36 @@ div.daggerheart.views.multiclass {
.application.sheet.dh-style li {
margin: 0;
}
+.application.sheet.dh-style a:hover,
+.application.sheet.dh-style a.active {
+ text-shadow: 0 0 8px light-dark(#18162e, #f3c267);
+}
.application.sheet.dh-style fieldset {
align-items: center;
margin-top: 5px;
border-radius: 6px;
border-color: light-dark(#18162e, #f3c267);
}
+.application.sheet.dh-style fieldset.glassy {
+ background-color: light-dark(#18162e10, #f3c26710);
+ border-color: transparent;
+}
+.application.sheet.dh-style fieldset.glassy legend {
+ padding: 2px 12px;
+ border-radius: 3px;
+ background-color: light-dark(#18162e, #f3c267);
+ color: light-dark(#efe6d8, #18162e);
+}
+.application.sheet.dh-style fieldset.flex {
+ display: flex;
+ gap: 20px;
+}
.application.sheet.dh-style fieldset.one-column {
display: flex;
flex-direction: column;
align-items: start;
gap: 10px;
min-height: 64px;
- width: 100%;
}
.application.sheet.dh-style fieldset.two-columns {
display: grid;
@@ -3835,9 +4409,6 @@ div.daggerheart.views.multiclass {
font-weight: bold;
color: light-dark(#18162e, #f3c267);
}
-.application.sheet.dh-style fieldset legend a {
- text-shadow: none;
-}
.application.sheet.dh-style fieldset input[type='text'],
.application.sheet.dh-style fieldset input[type='number'] {
color: light-dark(#222, #efe6d8);
@@ -3876,6 +4447,16 @@ div.daggerheart.views.multiclass {
border-bottom: 1px solid light-dark(#18162e, #f3c267);
mask-image: linear-gradient(270deg, transparent 0%, black 50%, transparent 100%);
}
+.application.sheet.dh-style side-line-div {
+ display: block;
+ height: 1px;
+ width: 100%;
+ border-bottom: 1px solid light-dark(#18162e, #f3c267);
+ mask-image: linear-gradient(270deg, transparent 0%, black 100%);
+}
+.application.sheet.dh-style side-line-div.invert {
+ mask-image: linear-gradient(270deg, black 0%, transparent 100%);
+}
.application.sheet.dh-style .item-description {
opacity: 1;
transform: translateY(0);
@@ -4070,11 +4651,9 @@ div.daggerheart.views.multiclass {
}
.sheet.daggerheart.dh-style .tab-navigation .feature-tab {
border: none;
- gap: 5px;
}
.sheet.daggerheart.dh-style .tab-navigation .feature-tab a {
color: light-dark(#18162e, #f3c267);
- text-shadow: none;
font-family: 'Montserrat', sans-serif;
}
.sheet.daggerheart.dh-style .tab-form-footer {
@@ -4119,9 +4698,6 @@ div.daggerheart.views.multiclass {
justify-content: center;
gap: 10px;
}
-.sheet.daggerheart.dh-style .tab.actions .actions-list .action-item .controls a {
- text-shadow: none;
-}
.sheet.daggerheart.dh-style .tab.effects .effects-list {
display: flex;
flex-direction: column;
@@ -4154,9 +4730,6 @@ div.daggerheart.views.multiclass {
justify-content: center;
gap: 10px;
}
-.sheet.daggerheart.dh-style .tab.effects .effects-list .effect-item .controls a {
- text-shadow: none;
-}
.application.sheet.daggerheart.dh-style .item-sheet-header {
display: flex;
}
@@ -4329,12 +4902,129 @@ div.daggerheart.views.multiclass {
.sheet.daggerheart.dh-style.item .tab.features .feature-list .feature-item .feature-line .controls a {
text-shadow: none;
}
-#logo {
- content: url(../assets/DaggerheartLogo.webp);
- height: 50px;
- width: 50px;
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item {
+ display: grid;
+ grid-template-columns: 40px 1fr 60px;
+ gap: 10px;
+ width: 100%;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-img {
+ height: 40px;
+ width: 40px;
+ border-radius: 3px;
+ border: none;
+ cursor: pointer;
+ object-fit: cover;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label {
+ font-family: 'Montserrat', sans-serif;
+ align-self: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label .item-name {
+ font-size: 14px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label .item-tags,
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label .item-labels {
+ display: flex;
+ gap: 10px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label .item-tags .tag,
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label .item-labels .tag {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ padding: 3px 5px;
+ font-size: 12px;
+ background: light-dark(#22222215, #efe6d815);
+ border: 1px solid light-dark(#222, #efe6d8);
+ border-radius: 3px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label .item-tags .label,
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .item-label .item-labels .label {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ font-size: 12px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .controls {
+ display: flex;
+ align-items: center;
+ justify-content: end;
+ gap: 8px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .controls a {
+ text-align: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .inventory-item .controls a.unequipped {
+ opacity: 0.4;
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-item {
position: relative;
- left: 25px;
+ height: 120px;
+ width: 100px;
+ border: 1px solid light-dark(#18162e, #f3c267);
+ border-radius: 6px;
+ cursor: pointer;
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-item:hover .card-label {
+ padding-top: 15px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-item:hover .card-label .controls {
+ opacity: 1;
+ visibility: visible;
+ transition: all 0.3s ease;
+ max-height: 16px;
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-item .card-img {
+ height: 100%;
+ width: 100%;
+ object-fit: cover;
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-item .card-label {
+ display: flex;
+ flex-direction: column;
+ height: fit-content;
+ align-items: center;
+ gap: 5px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ width: 100%;
+ position: absolute;
+ background-color: #18162e;
+ bottom: 0;
+ mask-image: linear-gradient(180deg, transparent 0%, black 20%);
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-item .card-label .card-name {
+ font-family: 'Montserrat', sans-serif;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 15px;
+ color: #efe6d8;
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-item .card-label .controls {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+ max-height: 0px;
+ opacity: 0;
+ visibility: collapse;
+ transition: all 0.3s ease;
+ color: #efe6d8;
+}
+.application.sheet.daggerheart.actor.dh-style.character .items-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.character .card-list {
+ display: flex;
+ flex-direction: row;
+ gap: 10px;
+ align-items: center;
}
.daggerheart {
/* Flex */
diff --git a/styles/daggerheart.less b/styles/daggerheart.less
index 32317832..a19117da 100755
--- a/styles/daggerheart.less
+++ b/styles/daggerheart.less
@@ -17,7 +17,14 @@
@import './settings.less';
// new styles imports
-@import './less/actors/character.less';
+@import './less/actors/character/header.less';
+@import './less/actors/character/sidebar.less';
+@import './less/actors/character/sheet.less';
+@import './less/actors/character/inventory.less';
+@import './less/actors/character/loadout.less';
+@import './less/actors/character/biography.less';
+@import './less/actors/character/features.less';
+
@import './less/actors/adversary.less';
@import './less/actors/environment.less';
@@ -36,14 +43,8 @@
@import './less/global/tab-effects.less';
@import './less/global/item-header.less';
@import './less/global/feature-section.less';
-
-#logo {
- content: url(../assets/DaggerheartLogo.webp);
- height: 50px;
- width: 50px;
- position: relative;
- left: 25px;
-}
+@import './less/global/inventory-item.less';
+@import './less/global/inventory-fieldset-items.less';
.daggerheart {
.vertical-separator {
diff --git a/styles/less/actors/character.less b/styles/less/actors/character.less
index e69de29b..e3833e3b 100644
--- a/styles/less/actors/character.less
+++ b/styles/less/actors/character.less
@@ -0,0 +1,11 @@
+@import '../utils/colors.less';
+@import '../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .window-content {
+ display: flex;
+ flex-direction: row;
+ height: 100%;
+ width: 100%;
+ }
+}
diff --git a/styles/less/actors/character/biography.less b/styles/less/actors/character/biography.less
new file mode 100644
index 00000000..635cf8d5
--- /dev/null
+++ b/styles/less/actors/character/biography.less
@@ -0,0 +1,20 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .tab.biography {
+ .items-section {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ height: 100%;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%);
+ padding-bottom: 40px;
+ height: 100%;
+
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(@dark-blue, @golden) transparent;
+ }
+ }
+}
diff --git a/styles/less/actors/character/features.less b/styles/less/actors/character/features.less
new file mode 100644
index 00000000..6fc86ac3
--- /dev/null
+++ b/styles/less/actors/character/features.less
@@ -0,0 +1,20 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .tab.features {
+ .features-sections {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
+ padding: 20px 0;
+ padding-top: 10px;
+ height: 95%;
+
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(@dark-blue, @golden) transparent;
+ }
+ }
+}
diff --git a/styles/less/actors/character/header.less b/styles/less/actors/character/header.less
new file mode 100644
index 00000000..7d7403e5
--- /dev/null
+++ b/styles/less/actors/character/header.less
@@ -0,0 +1,157 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .character-header-sheet {
+ padding: 0 15px;
+ padding-top: 36px;
+ width: 100%;
+
+ .name-row {
+ display: flex;
+ gap: 20px;
+ align-items: baseline;
+ justify-content: space-between;
+ padding: 0;
+ padding-top: 5px;
+
+ input[type='text'] {
+ font-size: 32px;
+ height: 42px;
+ width: 380px;
+ text-align: start;
+ border: 1px solid transparent;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+
+ &:hover {
+ outline: 2px solid light-dark(@dark, @golden);
+ }
+ }
+
+ .level-div {
+ white-space: nowrap;
+ }
+ }
+
+ .character-details {
+ display: flex;
+ justify-content: space-between;
+ padding: 5px 0;
+ margin-bottom: 10px;
+ font-size: 12px;
+ color: light-dark(@dark-blue, @golden);
+
+ span {
+ padding: 3px;
+ border-radius: 3px;
+ transition: all 0.3s ease;
+ cursor: pointer;
+
+ &:hover {
+ background: light-dark(@dark-blue-40, @golden-40);
+ }
+
+ &.dot {
+ background: transparent;
+ cursor: default;
+ }
+ }
+ }
+
+ .character-row {
+ display: flex;
+ gap: 20px;
+ align-items: center;
+ justify-content: space-between;
+ padding: 0;
+ margin-bottom: 15px;
+
+ .hope-section,
+ .threshold-section {
+ position: relative;
+ display: flex;
+ gap: 10px;
+ background-color: light-dark(transparent, @dark-blue);
+ color: light-dark(@dark-blue, @golden);
+ padding: 5px 10px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ border-radius: 6px;
+ align-items: center;
+ width: fit-content;
+ height: 30px;
+
+ h4 {
+ font-size: 14px;
+ font-weight: bold;
+ text-transform: uppercase;
+ color: light-dark(@dark-blue, @golden);
+
+ &.threshold-value {
+ color: light-dark(@dark, @beige);
+ }
+ }
+
+ .threshold-legend {
+ position: absolute;
+ bottom: -21px;
+ color: light-dark(@golden, @dark-blue);
+ background-color: light-dark(@dark-blue, @golden);
+ padding: 3px;
+ justify-self: anchor-center;
+ border-radius: 0 0 3px 3px;
+ text-transform: capitalize;
+ }
+
+ .hope-value {
+ display: flex;
+ cursor: pointer;
+ }
+ }
+ }
+
+ .character-traits {
+ display: flex;
+ justify-content: space-between;
+ padding: 0;
+ margin-bottom: 15px;
+
+ .trait {
+ height: 60px;
+ width: 60px;
+ background: url(../assets/svg/trait-shield.svg) no-repeat;
+
+ cursor: pointer;
+
+ .theme-light & {
+ background: url('../assets/svg/trait-shield-light.svg') no-repeat;
+ }
+
+ .trait-name {
+ display: flex;
+ align-items: center;
+ padding-top: 5px;
+ color: light-dark(@dark-blue, @golden);
+ font-size: 14px;
+ font-weight: 600;
+ align-items: center;
+ justify-content: center;
+ gap: 3px;
+
+ i {
+ line-height: 17px;
+ font-size: 10px;
+ }
+ }
+
+ .trait-value {
+ font-family: @font-body;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 20px;
+ text-align: center;
+ }
+ }
+ }
+ }
+}
diff --git a/styles/less/actors/character/inventory.less b/styles/less/actors/character/inventory.less
new file mode 100644
index 00000000..a6caf22b
--- /dev/null
+++ b/styles/less/actors/character/inventory.less
@@ -0,0 +1,65 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .tab.inventory {
+ .search-section {
+ display: flex;
+ gap: 10px;
+ align-items: center;
+
+ .search-bar {
+ position: relative;
+ color: light-dark(@dark-blue-50, @beige-50);
+ width: 100%;
+ padding-top: 5px;
+
+ input {
+ border-radius: 50px;
+ font-family: @font-body;
+ background: light-dark(@dark-blue-10, @golden-10);
+ border: none;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+ padding: 0 20px;
+
+ &:hover {
+ outline: 2px solid light-dark(@dark, @golden);
+ }
+
+ &:placeholder {
+ color: light-dark(@dark-blue-50, @beige-50);
+ }
+ }
+
+ .icon {
+ align-content: center;
+ height: 32px;
+ position: absolute;
+ right: 20px;
+ font-size: 16px;
+ z-index: 1;
+ color: light-dark(@dark-blue-50, @beige-50);
+ }
+ }
+ }
+
+ .items-section {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 5%, black 95%, transparent 100%);
+ padding: 20px 0;
+ height: 80%;
+
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(@dark-blue, @golden) transparent;
+ }
+
+ .currency-section {
+ display: flex;
+ gap: 10px;
+ }
+ }
+}
diff --git a/styles/less/actors/character/loadout.less b/styles/less/actors/character/loadout.less
new file mode 100644
index 00000000..37ed56bd
--- /dev/null
+++ b/styles/less/actors/character/loadout.less
@@ -0,0 +1,101 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .tab.loadout {
+ .search-section {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ .search-bar {
+ position: relative;
+ color: light-dark(@dark-blue-50, @beige-50);
+ width: 80%;
+ padding-top: 5px;
+
+ input {
+ border-radius: 50px;
+ font-family: @font-body;
+ background: light-dark(@dark-blue-10, @golden-10);
+ border: none;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+ padding: 0 20px;
+
+ &:hover {
+ outline: 2px solid light-dark(@dark, @golden);
+ }
+
+ &:placeholder {
+ color: light-dark(@dark-blue-50, @beige-50);
+ }
+ }
+
+ .icon {
+ align-content: center;
+ height: 32px;
+ position: absolute;
+ right: 20px;
+ font-size: 16px;
+ z-index: 1;
+ color: light-dark(@dark-blue-50, @beige-50);
+ }
+ }
+
+ .btn-toogle-view {
+ background: light-dark(@dark-blue-10, @dark-blue);
+ border: 1px solid light-dark(@dark-blue, @golden);
+ border-radius: 15px;
+ padding: 0;
+ gap: 0;
+ width: 62px;
+
+ span {
+ margin: 1px;
+ width: 26px;
+ color: light-dark(@dark-blue, @golden);
+
+ &.list-icon {
+ i {
+ margin-left: 3px;
+ }
+ }
+ &.grid-icon {
+ i {
+ margin-right: 3px;
+ }
+ }
+
+ &.list-active {
+ border-radius: 32px 3px 3px 32px;
+ background-color: light-dark(@dark-blue, @golden);
+ color: light-dark(@beige, @dark-blue);
+ padding: 2px;
+ }
+
+ &.grid-active {
+ border-radius: 3px 32px 32px 3px;
+ background-color: light-dark(@dark-blue, @golden);
+ color: light-dark(@beige, @dark-blue);
+ padding: 2px;
+ }
+ }
+ }
+ }
+
+ .items-section {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ height: 100%;
+ overflow-y: auto;
+ mask-image: linear-gradient(0deg, transparent 0%, black 10%, black 98%, transparent 100%);
+ padding: 20px 0;
+ height: 90%;
+
+ scrollbar-width: thin;
+ scrollbar-color: light-dark(@dark-blue, @golden) transparent;
+ }
+ }
+}
diff --git a/styles/less/actors/character/sheet.less b/styles/less/actors/character/sheet.less
new file mode 100644
index 00000000..6ca1ca4f
--- /dev/null
+++ b/styles/less/actors/character/sheet.less
@@ -0,0 +1,32 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .window-content {
+ display: grid;
+ grid-template-columns: 275px 1fr;
+ grid-template-rows: 283px 1fr;
+ gap: 15px 0;
+ height: 100%;
+ width: 100%;
+
+ .character-sidebar-sheet {
+ grid-row: 1 / span 2;
+ grid-column: 1;
+ }
+
+ .character-header-sheet {
+ grid-row: 1;
+ grid-column: 2;
+ }
+
+ .tab {
+ grid-row: 2;
+ grid-column: 2;
+ }
+
+ .old-sheet {
+ width: 500px;
+ }
+ }
+}
diff --git a/styles/less/actors/character/sidebar.less b/styles/less/actors/character/sidebar.less
new file mode 100644
index 00000000..4f8a1f7e
--- /dev/null
+++ b/styles/less/actors/character/sidebar.less
@@ -0,0 +1,283 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .character-sidebar-sheet {
+ width: 275px;
+ min-width: 275px;
+ border-right: 1px solid light-dark(@dark-blue, @golden);
+ background-image: url('../assets/parchments/dh-parchment-dark.png');
+
+ .theme-light & {
+ background: transparent;
+ }
+
+ img {
+ height: 235px;
+ width: 275px;
+ border-bottom: 1px solid light-dark(@dark-blue, @golden);
+ cursor: pointer;
+ object-fit: cover;
+ }
+
+ .info-section {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ top: -20px;
+ gap: 30px;
+ margin-bottom: -10px;
+
+ .resources-section {
+ display: flex;
+ justify-content: space-evenly;
+
+ .status-bar {
+ position: relative;
+ width: 100px;
+ height: 40px;
+ justify-items: center;
+
+ .status-label {
+ position: relative;
+ top: 40px;
+ height: 22px;
+ width: 79px;
+ clip-path: path('M0 0H79L74 16.5L39 22L4 16.5L0 0Z');
+ background: light-dark(@dark-blue, @golden);
+
+ h4 {
+ font-weight: bold;
+ text-align: center;
+ line-height: 18px;
+ color: light-dark(@beige, @dark-blue);
+ }
+ }
+ .status-value {
+ position: absolute;
+ display: flex;
+ padding: 0 6px;
+ font-size: 1.5rem;
+ align-items: center;
+ width: 100px;
+ height: 40px;
+ justify-content: center;
+ text-align: center;
+ z-index: 2;
+ color: @beige;
+
+ input[type='number'] {
+ background: transparent;
+ font-size: 1.5rem;
+ width: 40px;
+ height: 30px;
+ text-align: center;
+ border: none;
+ outline: 2px solid transparent;
+ color: @beige;
+
+ &.bar-input {
+ padding: 0;
+ color: @beige;
+ backdrop-filter: none;
+ background: transparent;
+ transition: all 0.3s ease;
+
+ &:hover,
+ &:focus {
+ background: @semi-transparent-dark-blue;
+ backdrop-filter: blur(9.5px);
+ }
+ }
+ }
+
+ .bar-label {
+ width: 40px;
+ }
+ }
+ .progress-bar {
+ position: absolute;
+ appearance: none;
+ width: 100px;
+ height: 40px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ border-radius: 6px;
+ z-index: 1;
+
+ &::-webkit-progress-bar {
+ border: none;
+ background: @dark-blue;
+ border-radius: 6px;
+ }
+ &::-webkit-progress-value {
+ background: @gradient-hp;
+ border-radius: 6px;
+ }
+ &.stress-color::-webkit-progress-value {
+ background: @gradient-stress;
+ border-radius: 6px;
+ }
+ &::-moz-progress-value,
+ &::-moz-progress-bar {
+ border-radius: 6px;
+ }
+
+ &::-moz-progress-bar {
+ background: @gradient-hp;
+ }
+ &.stress-color::-moz-progress-bar {
+ background: @gradient-stress;
+ border-radius: 6px;
+ }
+ }
+ }
+ }
+
+ .status-section {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 5px;
+ justify-content: center;
+
+ .status-number {
+ justify-items: center;
+
+ .status-value {
+ position: relative;
+ display: flex;
+ width: 50px;
+ height: 30px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ border-bottom: none;
+ border-radius: 6px 6px 0 0;
+ padding: 0 6px;
+ font-size: 1.2rem;
+ align-items: center;
+ justify-content: center;
+ background: light-dark(transparent, @dark-blue);
+ z-index: 2;
+
+ &.armor-slots {
+ width: 80px;
+ height: 30px;
+ }
+ }
+
+ .status-label {
+ padding: 2px 10px;
+ width: 100%;
+ border-radius: 3px;
+ background: light-dark(@dark-blue, @golden);
+
+ h4 {
+ font-weight: bold;
+ text-align: center;
+ line-height: 18px;
+ font-size: 12px;
+ color: light-dark(@beige, @dark-blue);
+ }
+ }
+ }
+ }
+ }
+
+ .items-sidebar-list {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+
+ .inventory-item {
+ padding: 0 10px;
+ }
+ }
+
+ .equipment-section {
+ .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+
+ h3 {
+ font-size: 20px;
+ }
+ }
+ .items-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+ }
+ }
+
+ .loadout-section {
+ .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+
+ h3 {
+ font-size: 20px;
+ }
+ }
+ }
+
+ .experience-section {
+ .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+
+ h3 {
+ font-size: 20px;
+ }
+ }
+
+ .experience-list {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ width: 100%;
+ margin-top: 10px;
+ align-items: center;
+
+ .experience-row {
+ display: flex;
+ gap: 5px;
+ width: 250px;
+ align-items: center;
+ justify-content: space-between;
+
+ input[type='text'] {
+ height: 32px;
+ width: 180px;
+ border: 1px solid transparent;
+ outline: 2px solid transparent;
+ font-size: 14px;
+ font-family: @font-body;
+ transition: all 0.3s ease;
+ color: light-dark(@dark, @beige);
+
+ &:hover {
+ outline: 2px solid light-dark(@dark, @beige);
+ }
+ }
+ }
+
+ .experience-value {
+ height: 25px;
+ width: 35px;
+ font-size: 14px;
+ font-family: @font-body;
+ color: light-dark(@dark, @beige);
+ align-content: center;
+ text-align: center;
+ background: url(../assets/svg/experience-shield.svg) no-repeat;
+
+ .theme-light & {
+ background: url('../assets/svg/experience-shield-light.svg') no-repeat;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less
index 139d5c53..8137e7de 100755
--- a/styles/less/global/elements.less
+++ b/styles/less/global/elements.less
@@ -84,19 +84,40 @@
margin: 0;
}
+ a:hover,
+ a.active {
+ text-shadow: 0 0 8px light-dark(@dark-blue, @golden);
+ }
+
fieldset {
align-items: center;
margin-top: 5px;
border-radius: 6px;
border-color: light-dark(@dark-blue, @golden);
+ &.glassy {
+ background-color: light-dark(@dark-blue-10, @golden-10);
+ border-color: transparent;
+
+ legend {
+ padding: 2px 12px;
+ border-radius: 3px;
+ background-color: light-dark(@dark-blue, @golden);
+ color: light-dark(@beige, @dark-blue);
+ }
+ }
+
+ &.flex {
+ display: flex;
+ gap: 20px;
+ }
+
&.one-column {
display: flex;
flex-direction: column;
align-items: start;
gap: 10px;
min-height: 64px;
- width: 100%;
}
&.two-columns {
@@ -117,10 +138,6 @@
font-family: @font-body;
font-weight: bold;
color: light-dark(@dark-blue, @golden);
-
- a {
- text-shadow: none;
- }
}
input[type='text'],
@@ -169,6 +186,18 @@
mask-image: linear-gradient(270deg, transparent 0%, black 50%, transparent 100%);
}
+ side-line-div {
+ display: block;
+ height: 1px;
+ width: 100%;
+ border-bottom: 1px solid light-dark(@dark-blue, @golden);
+ mask-image: linear-gradient(270deg, transparent 0%, black 100%);
+
+ &.invert {
+ mask-image: linear-gradient(270deg, black 0%, transparent 100%);
+ }
+ }
+
.item-description {
opacity: 1;
transform: translateY(0);
diff --git a/styles/less/global/inventory-fieldset-items.less b/styles/less/global/inventory-fieldset-items.less
new file mode 100644
index 00000000..0c427bf7
--- /dev/null
+++ b/styles/less/global/inventory-fieldset-items.less
@@ -0,0 +1,17 @@
+@import '../utils/colors.less';
+@import '../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .items-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+ }
+ .card-list {
+ display: flex;
+ flex-direction: row;
+ gap: 10px;
+ align-items: center;
+ }
+}
diff --git a/styles/less/global/inventory-item.less b/styles/less/global/inventory-item.less
new file mode 100644
index 00000000..a14bd83e
--- /dev/null
+++ b/styles/less/global/inventory-item.less
@@ -0,0 +1,133 @@
+@import '../utils/colors.less';
+@import '../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.character {
+ .inventory-item {
+ display: grid;
+ grid-template-columns: 40px 1fr 60px;
+ gap: 10px;
+ width: 100%;
+
+ .item-img {
+ height: 40px;
+ width: 40px;
+ border-radius: 3px;
+ border: none;
+ cursor: pointer;
+ object-fit: cover;
+ }
+
+ .item-label {
+ font-family: @font-body;
+ align-self: center;
+
+ .item-name {
+ font-size: 14px;
+ }
+
+ .item-tags,
+ .item-labels {
+ display: flex;
+ gap: 10px;
+
+ .tag {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ padding: 3px 5px;
+ font-size: 12px;
+
+ background: light-dark(@dark-15, @beige-15);
+ border: 1px solid light-dark(@dark, @beige);
+ border-radius: 3px;
+ }
+
+ .label {
+ display: flex;
+ flex-direction: row;
+ justify-content: center;
+ align-items: center;
+ font-size: 12px;
+ }
+ }
+ }
+
+ .controls {
+ display: flex;
+ align-items: center;
+ justify-content: end;
+ gap: 8px;
+
+ a {
+ text-align: center;
+
+ &.unequipped {
+ opacity: 0.4;
+ }
+ }
+ }
+ }
+ .card-item {
+ position: relative;
+ height: 120px;
+ width: 100px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ border-radius: 6px;
+ cursor: pointer;
+
+ &:hover {
+ .card-label {
+ padding-top: 15px;
+ .controls {
+ opacity: 1;
+ visibility: visible;
+ transition: all 0.3s ease;
+ max-height: 16px;
+ }
+ }
+ }
+
+ .card-img {
+ height: 100%;
+ width: 100%;
+ object-fit: cover;
+ }
+
+ .card-label {
+ display: flex;
+ flex-direction: column;
+ height: fit-content;
+ align-items: center;
+ gap: 5px;
+ padding-top: 5px;
+ padding-bottom: 5px;
+ width: 100%;
+ position: absolute;
+ background-color: @dark-blue;
+ bottom: 0;
+ mask-image: linear-gradient(180deg, transparent 0%, black 20%);
+
+ .card-name {
+ font-family: @font-body;
+ font-style: normal;
+ font-weight: 400;
+ font-size: 12px;
+ line-height: 15px;
+
+ color: @beige;
+ }
+
+ .controls {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+ max-height: 0px;
+ opacity: 0;
+ visibility: collapse;
+ transition: all 0.3s ease;
+ color: @beige;
+ }
+ }
+ }
+}
diff --git a/styles/less/global/sheet.less b/styles/less/global/sheet.less
index 975841db..669b00ec 100755
--- a/styles/less/global/sheet.less
+++ b/styles/less/global/sheet.less
@@ -35,7 +35,6 @@
.application.sheet.dh-style.minimized {
.window-content {
- display: none;
opacity: 0;
transition: opacity 0.1s ease;
}
@@ -48,15 +47,10 @@
}
}
-.application.sheet.dh-style .window-content {
- overflow: initial;
- backdrop-filter: none;
- padding: 0;
-}
-
.theme-dark {
.application.sheet.dh-style {
- backdrop-filter: blur(4px);
+ background: @semi-transparent-dark-blue;
+ backdrop-filter: blur(9px);
}
}
@@ -69,12 +63,29 @@
}
.application.sheet.daggerheart.dh-style {
+ border-radius: 10px;
+
.window-content {
+ padding: 0;
position: relative;
top: -36px;
+ min-height: -webkit-fill-available;
.tab {
padding: 0 10px;
}
}
}
+
+.application.sheet.daggerheart.character.dh-style {
+ border-radius: 10px;
+
+ .window-content {
+ position: absolute;
+ top: 0;
+ .tab {
+ padding: 0 15px;
+ overflow-y: hidden;
+ }
+ }
+}
diff --git a/styles/less/global/tab-actions.less b/styles/less/global/tab-actions.less
index 7279688d..7b225d4a 100644
--- a/styles/less/global/tab-actions.less
+++ b/styles/less/global/tab-actions.less
@@ -36,9 +36,6 @@
display: flex;
justify-content: center;
gap: 10px;
- a {
- text-shadow: none;
- }
}
}
}
diff --git a/styles/less/global/tab-effects.less b/styles/less/global/tab-effects.less
index c926f5d1..0c34a3ea 100644
--- a/styles/less/global/tab-effects.less
+++ b/styles/less/global/tab-effects.less
@@ -36,9 +36,6 @@
display: flex;
justify-content: center;
gap: 10px;
- a {
- text-shadow: none;
- }
}
}
}
diff --git a/styles/less/global/tab-navigation.less b/styles/less/global/tab-navigation.less
index 4e167e20..a13c7ea2 100755
--- a/styles/less/global/tab-navigation.less
+++ b/styles/less/global/tab-navigation.less
@@ -1,20 +1,18 @@
-@import '../utils/colors.less';
-@import '../utils/fonts.less';
-
-.sheet.daggerheart.dh-style {
- .tab-navigation {
- margin: 5px 0;
- height: 40px;
-
- .feature-tab {
- border: none;
- gap: 5px;
-
- a {
- color: light-dark(@dark-blue, @golden);
- text-shadow: none;
- font-family: @font-body;
- }
- }
- }
-}
+@import '../utils/colors.less';
+@import '../utils/fonts.less';
+
+.sheet.daggerheart.dh-style {
+ .tab-navigation {
+ margin: 5px 0;
+ height: 40px;
+
+ .feature-tab {
+ border: none;
+
+ a {
+ color: light-dark(@dark-blue, @golden);
+ font-family: @font-body;
+ }
+ }
+ }
+}
diff --git a/styles/less/items/class.less b/styles/less/items/class.less
index 61974778..a70b56d4 100644
--- a/styles/less/items/class.less
+++ b/styles/less/items/class.less
@@ -36,9 +36,6 @@
display: flex;
justify-content: center;
gap: 10px;
- a {
- text-shadow: none;
- }
}
}
}
diff --git a/styles/less/utils/colors.less b/styles/less/utils/colors.less
index 7e2ed6ca..eefff4a2 100755
--- a/styles/less/utils/colors.less
+++ b/styles/less/utils/colors.less
@@ -1,22 +1,21 @@
-@primary-blue: #1488cc;
-@secondary-blue: #2b32b2;
-@golden: #f3c267;
-@dark-blue: #18162e;
-@deep-black: #0e0d15;
-@beige: #efe6d8;
-@beige-60-opacity: #efe6d860;
-@dark-blue: rgb(24, 22, 46);
-@semi-transparent-dark-blue: rgba(24, 22, 46, 0.33);
-@dark: #222;
-@light-black: rgba(0, 0, 0, 0.3);
-@soft-shadow: rgba(0, 0, 0, 0.05);
-@gradient-hp: linear-gradient(15deg, rgb(70, 20, 10) 0%, rgb(190, 0, 0) 42%, rgb(252, 176, 69) 100%);
-@gradient-stress: linear-gradient(15deg, rgb(130, 59, 1) 0%, rgb(252, 142, 69) 65%, rgb(190, 0, 0) 100%);
-
-.theme-dark {
- @primary-color: @golden;
-}
-
-.theme-light {
- @primary-color: @dark-blue;
-}
+@primary-blue: #1488cc;
+@secondary-blue: #2b32b2;
+@golden: #f3c267;
+@golden-40: #f3c26740;
+@dark-blue-40: #18162e40;
+@golden-10: #f3c26710;
+@dark-blue-10: #18162e10;
+@dark-blue-50: #18162e50;
+@dark-blue: #18162e;
+@deep-black: #0e0d15;
+@beige: #efe6d8;
+@beige-15: #efe6d815;
+@beige-50: #efe6d850;
+@dark-blue: rgb(24, 22, 46);
+@semi-transparent-dark-blue: rgba(24, 22, 46, 0.33);
+@dark: #222;
+@dark-15: #22222215;
+@light-black: rgba(0, 0, 0, 0.3);
+@soft-shadow: rgba(0, 0, 0, 0.05);
+@gradient-hp: linear-gradient(15deg, rgb(70, 20, 10) 0%, rgb(190, 0, 0) 42%, rgb(252, 176, 69) 100%);
+@gradient-stress: linear-gradient(15deg, rgb(130, 59, 1) 0%, rgb(252, 142, 69) 65%, rgb(190, 0, 0) 100%);
diff --git a/styles/pc.less b/styles/pc.less
index 07a91411..c9abd821 100644
--- a/styles/pc.less
+++ b/styles/pc.less
@@ -1,3 +1,6 @@
+@import 'variables/values.less';
+@import 'variables/colors.less';
+
.daggerheart.sheet.pc {
width: 810px !important; // Form won't apply height for some reason
@@ -457,6 +460,9 @@
align-items: flex-start;
border-radius: @normalRadius;
+ height: 100px;
+ width: 100px;
+
.legend {
margin-left: auto;
margin-right: auto;
diff --git a/templates/sheets/actors/character/biography.hbs b/templates/sheets/actors/character/biography.hbs
new file mode 100644
index 00000000..c0bf55a9
--- /dev/null
+++ b/templates/sheets/actors/character/biography.hbs
@@ -0,0 +1,36 @@
+
+
+
+
+
+ {{localize 'DAGGERHEART.Sheets.PC.Level'}}
+ {{document.system.levelData.level.current}}
+
+ {{localize "DAGGERHEART.General.Hope"}}
+ {{#times document.system.resources.hope.max}}
+
+ {{#if (gte ../document.system.resources.hope.value this)}}
+
+ {{else}}
+
+ {{/if}}
+
+ {{/times}}
+ {{localize "DAGGERHEART.Sheets.PC.Health.Minor"}}
+ {{document.system.damageThresholds.major}}
+ {{localize "DAGGERHEART.Sheets.PC.Health.Major"}}
+ {{document.system.damageThresholds.severe}}
+ {{localize "DAGGERHEART.Sheets.PC.Health.Severe"}}
+