diff --git a/lang/en.json b/lang/en.json
index 7867265d..d466b0fc 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -1312,7 +1312,8 @@
}
},
"Experiences": "Experiences",
- "Level": "Level"
+ "Level": "Level",
+ "noPartner": "No Partner selected"
},
"Adversary": {
"FIELDS": {
diff --git a/module/applications/_module.mjs b/module/applications/_module.mjs
index 1ee7f37a..c5eb45d9 100644
--- a/module/applications/_module.mjs
+++ b/module/applications/_module.mjs
@@ -1,6 +1,6 @@
export { default as DhCharacterSheet } from './sheets/actors/character.mjs';
export { default as DhpAdversarySheet } from './sheets/actors/adversary.mjs';
-export { default as DhCompanionSheet } from './sheets/companion.mjs';
+export { default as DhCompanionSheet } from './sheets/actors/companion.mjs';
export { default as DhpClassSheet } from './sheets/items/class.mjs';
export { default as DhpSubclass } from './sheets/items/subclass.mjs';
export { default as DhpFeatureSheet } from './sheets/items/feature.mjs';
diff --git a/module/applications/sheets/actors/companion.mjs b/module/applications/sheets/actors/companion.mjs
new file mode 100644
index 00000000..89939e9a
--- /dev/null
+++ b/module/applications/sheets/actors/companion.mjs
@@ -0,0 +1,108 @@
+import DaggerheartSheet from '../daggerheart-sheet.mjs';
+import DHCompanionSettings from '../applications/companion-settings.mjs';
+
+const { ActorSheetV2 } = foundry.applications.sheets;
+export default class DhCompanionSheet extends DaggerheartSheet(ActorSheetV2) {
+ static DEFAULT_OPTIONS = {
+ tag: 'form',
+ classes: ['daggerheart', 'sheet', 'actor', 'dh-style', 'companion'],
+ position: { width: 300 },
+ actions: {
+ viewActor: this.viewActor,
+ openSettings: this.openSettings,
+ useItem: this.useItem,
+ toChat: this.toChat
+ },
+ form: {
+ handler: this.updateForm,
+ submitOnChange: true,
+ closeOnSubmit: false
+ }
+ };
+
+ static PARTS = {
+ header: { template: 'systems/daggerheart/templates/sheets/actors/companion/header.hbs' },
+ details: { template: 'systems/daggerheart/templates/sheets/actors/companion/details.hbs' },
+ effects: { template: 'systems/daggerheart/templates/sheets/actors/companion/effects.hbs' }
+ };
+
+ static TABS = {
+ details: {
+ active: true,
+ cssClass: '',
+ group: 'primary',
+ id: 'details',
+ icon: null,
+ label: 'DAGGERHEART.General.tabs.details'
+ },
+ effects: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'effects',
+ icon: null,
+ label: 'DAGGERHEART.Sheets.PC.Tabs.effects'
+ }
+ };
+
+ async _prepareContext(_options) {
+ const context = await super._prepareContext(_options);
+ context.document = this.document;
+ context.tabs = super._getTabs(this.constructor.TABS);
+
+ return context;
+ }
+
+ static async updateForm(event, _, formData) {
+ await this.document.update(formData.object);
+ this.render();
+ }
+
+ static async viewActor(_, button) {
+ const target = button.closest('[data-item-uuid]');
+ const actor = await foundry.utils.fromUuid(target.dataset.itemUuid);
+ if (!actor) return;
+
+ actor.sheet.render(true);
+ }
+
+ getAction(element) {
+ const itemId = (element.target ?? element).closest('[data-item-id]').dataset.itemId,
+ item = this.document.system.actions.find(x => x.id === itemId);
+ return item;
+ }
+
+ static async useItem(event) {
+ const action = this.getAction(event) ?? this.actor.system.attack;
+ action.use(event);
+ }
+
+ static async toChat(event, button) {
+ if (button?.dataset?.type === 'experience') {
+ const experience = this.document.system.experiences[button.dataset.uuid];
+ const cls = getDocumentClass('ChatMessage');
+ const systemData = {
+ name: game.i18n.localize('DAGGERHEART.General.Experience.Single'),
+ description: `${experience.name} ${experience.total < 0 ? experience.total : `+${experience.total}`}`
+ };
+ const msg = new cls({
+ type: 'abilityUse',
+ user: game.user.id,
+ system: systemData,
+ content: await foundry.applications.handlebars.renderTemplate(
+ 'systems/daggerheart/templates/chat/ability-use.hbs',
+ systemData
+ )
+ });
+
+ cls.create(msg.toObject());
+ } else {
+ const item = this.getAction(event) ?? this.document.system.attack;
+ item.toChat(this.document.id);
+ }
+ }
+
+ static async openSettings() {
+ await new DHCompanionSettings(this.document).render(true);
+ }
+}
diff --git a/module/applications/sheets/applications/companion-settings.mjs b/module/applications/sheets/applications/companion-settings.mjs
new file mode 100644
index 00000000..89d20a07
--- /dev/null
+++ b/module/applications/sheets/applications/companion-settings.mjs
@@ -0,0 +1,160 @@
+import { GMUpdateEvent, socketEvent } from '../../../helpers/socket.mjs';
+import DhCompanionlevelUp from '../../levelup/companionLevelup.mjs';
+
+const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
+
+export default class DHCompanionSettings extends HandlebarsApplicationMixin(ApplicationV2) {
+ constructor(actor) {
+ super({});
+
+ this.actor = actor;
+ }
+
+ get title() {
+ return `${game.i18n.localize('DAGGERHEART.Sheets.TABS.settings')}`;
+ }
+
+ static DEFAULT_OPTIONS = {
+ tag: 'form',
+ classes: ['daggerheart', 'dh-style', 'dialog', 'companion-settings'],
+ window: {
+ icon: 'fa-solid fa-wrench',
+ resizable: false
+ },
+ position: { width: 455, height: 'auto' },
+ actions: {
+ levelUp: this.levelUp
+ },
+ form: {
+ handler: this.updateForm,
+ submitOnChange: true,
+ closeOnSubmit: false
+ }
+ };
+
+ static PARTS = {
+ header: {
+ id: 'header',
+ template: 'systems/daggerheart/templates/sheets/applications/companion-settings/header.hbs'
+ },
+ tabs: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-navigation.hbs' },
+ details: {
+ id: 'details',
+ template: 'systems/daggerheart/templates/sheets/applications/companion-settings/details.hbs'
+ },
+ experiences: {
+ id: 'experiences',
+ template: 'systems/daggerheart/templates/sheets/applications/companion-settings/experiences.hbs'
+ },
+ attack: {
+ id: 'attack',
+ template: 'systems/daggerheart/templates/sheets/applications/companion-settings/attack.hbs'
+ }
+ };
+
+ static TABS = {
+ details: {
+ active: true,
+ cssClass: '',
+ group: 'primary',
+ id: 'details',
+ icon: null,
+ label: 'DAGGERHEART.General.tabs.details'
+ },
+ experiences: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'experiences',
+ icon: null,
+ label: 'DAGGERHEART.General.tabs.experiences'
+ },
+ attack: {
+ active: false,
+ cssClass: '',
+ group: 'primary',
+ id: 'attack',
+ icon: null,
+ label: 'DAGGERHEART.General.tabs.attack'
+ }
+ };
+
+ _attachPartListeners(partId, htmlElement, options) {
+ super._attachPartListeners(partId, htmlElement, options);
+
+ htmlElement.querySelector('.partner-value')?.addEventListener('change', this.onPartnerChange.bind(this));
+ }
+
+ async _prepareContext(_options) {
+ const context = await super._prepareContext(_options);
+ context.document = this.actor;
+ context.tabs = this._getTabs(this.constructor.TABS);
+ context.systemFields = this.actor.system.schema.fields;
+ context.systemFields.attack.fields = this.actor.system.attack.schema.fields;
+ context.isNPC = true;
+ context.playerCharacters = game.actors
+ .filter(
+ x =>
+ x.type === 'character' &&
+ (x.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER) ||
+ this.document.system.partner?.uuid === x.uuid)
+ )
+ .map(x => ({ key: x.uuid, name: x.name }));
+
+ return context;
+ }
+
+ _getTabs(tabs) {
+ for (const v of Object.values(tabs)) {
+ v.active = this.tabGroups[v.group] ? this.tabGroups[v.group] === v.id : v.active;
+ v.cssClass = v.active ? 'active' : '';
+ }
+
+ return tabs;
+ }
+
+ async onPartnerChange(event) {
+ const partnerDocument = event.target.value
+ ? await foundry.utils.fromUuid(event.target.value)
+ : this.actor.system.partner;
+ const partnerUpdate = { 'system.companion': event.target.value ? this.actor.uuid : null };
+
+ if (!partnerDocument.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
+ await game.socket.emit(`system.${SYSTEM.id}`, {
+ action: socketEvent.GMUpdate,
+ data: {
+ action: GMUpdateEvent.UpdateDocument,
+ uuid: partnerDocument.uuid,
+ update: update
+ }
+ });
+ } else {
+ await partnerDocument.update(partnerUpdate);
+ }
+
+ await this.actor.update({ 'system.partner': event.target.value });
+
+ if (!event.target.value) {
+ await this.actor.updateLevel(1);
+ }
+
+ this.render();
+ }
+
+ async viewActor(_, button) {
+ const target = button.closest('[data-item-uuid]');
+ const actor = await foundry.utils.fromUuid(target.dataset.itemUuid);
+ if (!actor) return;
+
+ actor.sheet.render(true);
+ }
+
+ static async levelUp() {
+ new DhCompanionlevelUp(this.actor).render(true);
+ }
+
+ static async updateForm(event, _, formData) {
+ await this.actor.update(formData.object);
+ this.render();
+ }
+}
diff --git a/module/applications/sheets/companion.mjs b/module/applications/sheets/companion.mjs
deleted file mode 100644
index 46080814..00000000
--- a/module/applications/sheets/companion.mjs
+++ /dev/null
@@ -1,86 +0,0 @@
-import { GMUpdateEvent, socketEvent } from '../../helpers/socket.mjs';
-import DhCompanionlevelUp from '../levelup/companionLevelup.mjs';
-import DaggerheartSheet from './daggerheart-sheet.mjs';
-
-const { ActorSheetV2 } = foundry.applications.sheets;
-export default class DhCompanionSheet extends DaggerheartSheet(ActorSheetV2) {
- static DEFAULT_OPTIONS = {
- tag: 'form',
- classes: ['daggerheart', 'sheet', 'actor', 'dh-style', 'companion'],
- position: { width: 700, height: 1000 },
- actions: {
- attackRoll: this.attackRoll,
- levelUp: this.levelUp
- },
- form: {
- handler: this.updateForm,
- submitOnChange: true,
- closeOnSubmit: false
- }
- };
-
- static PARTS = {
- sidebar: { template: 'systems/daggerheart/templates/sheets/actors/companion/tempMain.hbs' }
- };
-
- _attachPartListeners(partId, htmlElement, options) {
- super._attachPartListeners(partId, htmlElement, options);
-
- htmlElement.querySelector('.partner-value')?.addEventListener('change', this.onPartnerChange.bind(this));
- }
-
- async _prepareContext(_options) {
- const context = await super._prepareContext(_options);
- context.document = this.document;
- context.playerCharacters = game.actors
- .filter(
- x =>
- x.type === 'character' &&
- (x.ownership.default === 3 ||
- x.ownership[game.user.id] === 3 ||
- this.document.system.partner?.uuid === x.uuid)
- )
- .map(x => ({ key: x.uuid, name: x.name }));
-
- return context;
- }
-
- static async updateForm(event, _, formData) {
- await this.document.update(formData.object);
- this.render();
- }
-
- async onPartnerChange(event) {
- const partnerDocument = event.target.value
- ? await foundry.utils.fromUuid(event.target.value)
- : this.document.system.partner;
- const partnerUpdate = { 'system.companion': event.target.value ? this.document.uuid : null };
-
- if (!partnerDocument.testUserPermission(game.user, CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER)) {
- await game.socket.emit(`system.${SYSTEM.id}`, {
- action: socketEvent.GMUpdate,
- data: {
- action: GMUpdateEvent.UpdateDocument,
- uuid: partnerDocument.uuid,
- update: update
- }
- });
- } else {
- await partnerDocument.update(partnerUpdate);
- }
-
- await this.document.update({ 'system.partner': event.target.value });
-
- if (!event.target.value) {
- await this.document.updateLevel(1);
- }
- }
-
- static async attackRoll(event) {
- this.actor.system.attack.use(event);
- }
-
- static async levelUp() {
- new DhCompanionlevelUp(this.document).render(true);
- }
-}
diff --git a/module/data/actor/companion.mjs b/module/data/actor/companion.mjs
index abc38e93..b1254f87 100644
--- a/module/data/actor/companion.mjs
+++ b/module/data/actor/companion.mjs
@@ -47,6 +47,7 @@ export default class DhCompanion extends BaseDataActor {
attack: new ActionField({
initial: {
name: 'Attack',
+ img: 'icons/creatures/claws/claw-bear-paw-swipe-brown.webp',
_id: foundry.utils.randomID(),
systemPath: 'attack',
type: 'attack',
@@ -57,7 +58,8 @@ export default class DhCompanion extends BaseDataActor {
},
roll: {
type: 'weapon',
- bonus: 0
+ bonus: 0,
+ trait: 'instinct'
},
damage: {
parts: [
@@ -77,8 +79,10 @@ export default class DhCompanion extends BaseDataActor {
};
}
- get attackBonus() {
- return this.attack.roll.bonus ?? 0;
+ get traits() {
+ return {
+ instinct: { total: this.attack.roll.bonus }
+ };
}
prepareBaseData() {
diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs
index 541b76d0..2bb4084f 100644
--- a/module/documents/actor.mjs
+++ b/module/documents/actor.mjs
@@ -126,6 +126,7 @@ export default class DhpActor extends Actor {
}
}
});
+ this.sheet.render();
if (this.system.companion) {
this.system.companion.updateLevel(newLevel);
@@ -307,6 +308,7 @@ export default class DhpActor extends Actor {
}
}
});
+ this.sheet.render();
if (this.system.companion) {
this.system.companion.updateLevel(this.system.levelData.level.changed);
@@ -338,7 +340,7 @@ export default class DhpActor extends Actor {
}
get rollClass() {
- return CONFIG.Dice.daggerheart[this.type === 'character' ? 'DualityRoll' : 'D20Roll'];
+ return CONFIG.Dice.daggerheart[['character', 'companion'].includes(this.type) ? 'DualityRoll' : 'D20Roll'];
}
getRollData() {
diff --git a/styles/daggerheart.css b/styles/daggerheart.css
index 763b7e7d..cc6854ca 100755
--- a/styles/daggerheart.css
+++ b/styles/daggerheart.css
@@ -4989,13 +4989,248 @@ div.daggerheart.views.multiclass {
color: light-dark(#18162e50, #efe6d850);
font-family: 'Montserrat', sans-serif;
}
-.application.sheet.daggerheart.actor.dh-style.companion .profile {
- height: 80px;
- width: 80px;
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
}
-.application.sheet.daggerheart.actor.dh-style.companion .temp-container {
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .profile {
+ height: 235px;
+ width: 100%;
+ object-fit: cover;
+ cursor: pointer;
+ mask-image: linear-gradient(0deg, transparent 0%, black 10%);
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .actor-name {
+ display: flex;
+ align-items: center;
position: relative;
- top: 32px;
+ top: -30px;
+ gap: 20px;
+ padding: 0 20px;
+ margin-bottom: -30px;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .actor-name input[type='text'] {
+ font-size: 24px;
+ height: 32px;
+ text-align: center;
+ border: 1px solid transparent;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .actor-name input[type='text']:hover {
+ outline: 2px solid light-dark(#222, #f3c267);
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section {
+ display: flex;
+ gap: 5px;
+ justify-content: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number {
+ justify-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number .status-value {
+ position: relative;
+ display: flex;
+ width: 50px;
+ height: 40px;
+ border: 1px solid light-dark(#18162e, #f3c267);
+ border-bottom: none;
+ border-radius: 6px 6px 0 0;
+ padding: 0 6px;
+ font-size: 1.5rem;
+ align-items: center;
+ justify-content: center;
+ background: light-dark(transparent, #18162e);
+ z-index: 2;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-number .status-value.armor-slots {
+ width: 80px;
+ height: 30px;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .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.companion .companion-header-sheet .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.companion .companion-header-sheet .status-section .status-bar {
+ position: relative;
+ width: 100px;
+ height: 40px;
+ justify-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-section .status-bar .status-value input[type='number'].bar-input:hover,
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-section .status-bar .status-value .bar-label {
+ width: 40px;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-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;
+ background: #18162e;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-section .status-bar .progress-bar::-webkit-progress-bar {
+ border: none;
+ background: #18162e;
+ border-radius: 6px;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-section .status-bar .progress-bar::-moz-progress-bar {
+ background: linear-gradient(15deg, #46140a 0%, #be0000 42%, #fcb045 100%);
+ border-radius: 6px;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .status-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.companion .companion-header-sheet .status-section .level-up-label {
+ font-size: 24px;
+ padding-top: 8px;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .companion-header-sheet .companion-navigation {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ width: 100%;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .partner-section,
+.application.sheet.daggerheart.actor.dh-style.companion .attack-section {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title,
+.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .partner-section .title h3,
+.application.sheet.daggerheart.actor.dh-style.companion .attack-section .title h3 {
+ font-size: 20px;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .partner-section .items-list,
+.application.sheet.daggerheart.actor.dh-style.companion .attack-section .items-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .partner-placeholder {
+ display: flex;
+ opacity: 0.6;
+ text-align: center;
+ font-style: italic;
+ justify-content: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .experience-list {
+ display: flex;
+ flex-direction: column;
+ gap: 5px;
+ width: 100%;
+ margin-top: 10px;
+ align-items: center;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row {
+ display: flex;
+ gap: 5px;
+ width: 250px;
+ align-items: center;
+ justify-content: space-between;
+}
+.application.sheet.daggerheart.actor.dh-style.companion .experience-list .experience-row .experience-name {
+ width: 180px;
+ text-align: start;
+ font-size: 14px;
+ font-family: 'Montserrat', sans-serif;
+ color: light-dark(#222, #efe6d8);
+}
+.application.sheet.daggerheart.actor.dh-style.companion .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.companion .experience-list .experience-value {
+ background: url('../assets/svg/experience-shield-light.svg') no-repeat;
+}
+.theme-light .application.sheet.daggerheart.actor.dh-style.companion {
+ background: url('../assets/parchments/dh-parchment-light.png');
+}
+.theme-dark .application.sheet.daggerheart.actor.dh-style.companion {
+ background-image: url('../assets/parchments/dh-parchment-dark.png');
}
.application.sheet.daggerheart.actor.dh-style.adversary .window-content {
overflow: auto;
@@ -5290,6 +5525,19 @@ div.daggerheart.views.multiclass {
box-shadow: none;
outline: 2px solid light-dark(#222, #efe6d8);
}
+.application.dh-style input[type='text']:disabled[type='text'],
+.application.dh-style input[type='number']:disabled[type='text'],
+.application.dh-style input[type='text']:disabled[type='number'],
+.application.dh-style input[type='number']:disabled[type='number'] {
+ outline: 2px solid transparent;
+ cursor: not-allowed;
+}
+.application.dh-style input[type='text']:disabled[type='text']:hover,
+.application.dh-style input[type='number']:disabled[type='text']:hover,
+.application.dh-style input[type='text']:disabled[type='number']:hover,
+.application.dh-style input[type='number']:disabled[type='number']:hover {
+ background: transparent;
+}
.application.dh-style input[type='checkbox']:checked::after {
color: light-dark(#222, #f3c267);
}
@@ -5313,6 +5561,16 @@ div.daggerheart.views.multiclass {
.application.dh-style button.glow {
animation: glow 0.75s infinite alternate;
}
+.application.dh-style button:disabled {
+ background: light-dark(transparent, #f3c267);
+ color: light-dark(#18162e, #18162e);
+ opacity: 0.6;
+ cursor: not-allowed;
+}
+.application.dh-style button:disabled:hover {
+ background: light-dark(transparent, #f3c267);
+ color: light-dark(#18162e, #18162e);
+}
.application.dh-style select {
background: light-dark(transparent, transparent);
color: light-dark(#222, #efe6d8);
diff --git a/styles/daggerheart.less b/styles/daggerheart.less
index 8903dcf0..49c66916 100755
--- a/styles/daggerheart.less
+++ b/styles/daggerheart.less
@@ -40,6 +40,8 @@
@import './less/applications/environment-settings/actions.less';
@import './less/applications/environment-settings/adversaries.less';
+@import './less/actors/companion/header.less';
+@import './less/actors/companion/details.less';
@import './less/actors/companion/sheet.less';
@import './less/actors/adversary.less';
diff --git a/styles/less/actors/companion/details.less b/styles/less/actors/companion/details.less
new file mode 100644
index 00000000..4da8d126
--- /dev/null
+++ b/styles/less/actors/companion/details.less
@@ -0,0 +1,75 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.companion {
+ .partner-section,
+ .attack-section {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+
+ .title {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+
+ h3 {
+ font-size: 20px;
+ }
+ }
+ .items-list {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+ }
+ }
+
+ .partner-placeholder {
+ display: flex;
+ opacity: 0.6;
+ text-align: center;
+ font-style: italic;
+ justify-content: center;
+ }
+
+ .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;
+
+ .experience-name {
+ width: 180px;
+ text-align: start;
+ font-size: 14px;
+ font-family: @font-body;
+ color: 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/actors/companion/header.less b/styles/less/actors/companion/header.less
new file mode 100644
index 00000000..df68747b
--- /dev/null
+++ b/styles/less/actors/companion/header.less
@@ -0,0 +1,197 @@
+@import '../../utils/colors.less';
+@import '../../utils/fonts.less';
+
+.application.sheet.daggerheart.actor.dh-style.companion {
+ .companion-header-sheet {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 8px;
+
+ .profile {
+ height: 235px;
+ width: 100%;
+ object-fit: cover;
+ cursor: pointer;
+ mask-image: linear-gradient(0deg, transparent 0%, black 10%);
+ }
+
+ .actor-name {
+ display: flex;
+ align-items: center;
+ position: relative;
+ top: -30px;
+ gap: 20px;
+ padding: 0 20px;
+ margin-bottom: -30px;
+
+ input[type='text'] {
+ font-size: 24px;
+ height: 32px;
+ text-align: center;
+ border: 1px solid transparent;
+ outline: 2px solid transparent;
+ transition: all 0.3s ease;
+
+ &:hover {
+ outline: 2px solid light-dark(@dark, @golden);
+ }
+ }
+ }
+
+ .status-section {
+ display: flex;
+ gap: 5px;
+ justify-content: center;
+
+ .status-number {
+ justify-items: center;
+
+ .status-value {
+ position: relative;
+ display: flex;
+ width: 50px;
+ height: 40px;
+ border: 1px solid light-dark(@dark-blue, @golden);
+ border-bottom: none;
+ border-radius: 6px 6px 0 0;
+ padding: 0 6px;
+ font-size: 1.5rem;
+ 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);
+ }
+ }
+ }
+
+ .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;
+ background: @dark-blue;
+
+ &::-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-bar {
+ background: @gradient-hp;
+ border-radius: 6px;
+ }
+ &.stress-color::-moz-progress-bar {
+ background: @gradient-stress;
+ border-radius: 6px;
+ }
+ }
+ }
+
+ .level-up-label {
+ font-size: 24px;
+ padding-top: 8px;
+ }
+ }
+
+ .companion-navigation {
+ display: flex;
+ gap: 8px;
+ align-items: center;
+ width: 100%;
+ }
+ }
+}
diff --git a/styles/less/actors/companion/sheet.less b/styles/less/actors/companion/sheet.less
index 1beb28a7..db221597 100644
--- a/styles/less/actors/companion/sheet.less
+++ b/styles/less/actors/companion/sheet.less
@@ -1,11 +1,18 @@
.application.sheet.daggerheart.actor.dh-style.companion {
- .profile {
- height: 80px;
- width: 80px;
+ .theme-light & {
+ background: url('../assets/parchments/dh-parchment-light.png');
+ }
+ .theme-dark & {
+ background-image: url('../assets/parchments/dh-parchment-dark.png');
}
- .temp-container {
- position: relative;
- top: 32px;
- }
+ // .profile {
+ // height: 80px;
+ // width: 80px;
+ // }
+
+ // .temp-container {
+ // position: relative;
+ // top: 32px;
+ // }
}
diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less
index 1f6e5988..fcf9d353 100755
--- a/styles/less/global/elements.less
+++ b/styles/less/global/elements.less
@@ -23,6 +23,16 @@
box-shadow: none;
outline: 2px solid light-dark(@dark, @beige);
}
+
+ &:disabled[type='text'],
+ &:disabled[type='number'] {
+ outline: 2px solid transparent;
+ cursor: not-allowed;
+
+ &:hover {
+ background: transparent;
+ }
+ }
}
input[type='checkbox'] {
@@ -52,6 +62,18 @@
&.glow {
animation: glow 0.75s infinite alternate;
}
+
+ &:disabled {
+ background: light-dark(transparent, @golden);
+ color: light-dark(@dark-blue, @dark-blue);
+ opacity: 0.6;
+ cursor: not-allowed;
+
+ &:hover {
+ background: light-dark(transparent, @golden);
+ color: light-dark(@dark-blue, @dark-blue);
+ }
+ }
}
select {
diff --git a/templates/sheets/actors/companion/details.hbs b/templates/sheets/actors/companion/details.hbs
new file mode 100644
index 00000000..f337d009
--- /dev/null
+++ b/templates/sheets/actors/companion/details.hbs
@@ -0,0 +1,43 @@
+ {{document.system.evasion.total}}Partner
+
+ {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=document.system.partner type='actor' isSidebar=true isActor=true noTooltip=true}}
+
+ {{else}}
+ {{localize "DAGGERHEART.Sheets.Companion.noPartner"}}
+ {{/if}}
+ Attack
+
+ {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=source.system.attack type=source.system.attack.systemPath isSidebar=true isCompanion=true noTooltip=true}}
+
+
+
+
+
+ Evasion
+
+ {{localize "DAGGERHEART.Sheets.Companion.Level"}}
+ {{source.system.levelData.level.changed}}
+
+ {{document.name}}
+