Compare commits
3 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c64a788d62 | |||
| a28825f5b8 | |||
| 2bea5df640 |
4 changed files with 244 additions and 8 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "dh-hotbar-cardview",
|
"id": "dh-hotbar-cardview",
|
||||||
"title": "Daggerheart Hotbar Card View",
|
"title": "Daggerheart Hotbar Card View",
|
||||||
"description": "Replaces the hover-tooltips on the hotbar icons with a full card view of the item for Daggerheart.",
|
"description": "Replaces the hover-tooltips on the hotbar icons with a full card view of the item for Daggerheart.",
|
||||||
"version": "1.0.0",
|
"version": "1.1.0",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "14",
|
"minimum": "14",
|
||||||
"verified": "14"
|
"verified": "14"
|
||||||
|
|
@ -34,5 +34,5 @@
|
||||||
],
|
],
|
||||||
"url": "https://git.geeks.gay/cosmo/dh-hotbar-cardview",
|
"url": "https://git.geeks.gay/cosmo/dh-hotbar-cardview",
|
||||||
"manifest": "https://git.geeks.gay/cosmo/dh-hotbar-cardview/raw/branch/main/module.json",
|
"manifest": "https://git.geeks.gay/cosmo/dh-hotbar-cardview/raw/branch/main/module.json",
|
||||||
"download": "https://git.geeks.gay/cosmo/dh-hotbar-cardview/releases/latest/download/dh-hotbar-cardview.zip"
|
"download": "https://git.geeks.gay/cosmo/dh-hotbar-cardview/releases/download/1.1.0/dh-hotbar-cardview.zip"
|
||||||
}
|
}
|
||||||
118
scripts/main.js
118
scripts/main.js
|
|
@ -1,4 +1,87 @@
|
||||||
Hooks.once('init', () => {
|
Hooks.once('init', () => {
|
||||||
|
// Register Module Settings
|
||||||
|
game.settings.register('dh-hotbar-cardview', 'showTagsAll', {
|
||||||
|
name: 'Show Tags on Tooltips',
|
||||||
|
hint: 'Master toggle to display item tags (damage, properties, etc.) on hotbar card tooltips.',
|
||||||
|
scope: 'client',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
});
|
||||||
|
game.settings.register('dh-hotbar-cardview', 'showTagsWeapons', {
|
||||||
|
name: 'Show Tags: Weapons',
|
||||||
|
scope: 'client',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
});
|
||||||
|
game.settings.register('dh-hotbar-cardview', 'showTagsArmor', {
|
||||||
|
name: 'Show Tags: Armor',
|
||||||
|
scope: 'client',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
});
|
||||||
|
game.settings.register('dh-hotbar-cardview', 'showTagsConsumables', {
|
||||||
|
name: 'Show Tags: Consumables',
|
||||||
|
scope: 'client',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
});
|
||||||
|
game.settings.register('dh-hotbar-cardview', 'showTagsFeatures', {
|
||||||
|
name: 'Show Tags: Features',
|
||||||
|
scope: 'client',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
});
|
||||||
|
game.settings.register('dh-hotbar-cardview', 'showTagsDomains', {
|
||||||
|
name: 'Show Tags: Domain Cards',
|
||||||
|
scope: 'client',
|
||||||
|
config: true,
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
});
|
||||||
|
|
||||||
|
// Hook to dynamically hide/show sub-settings based on the master toggle
|
||||||
|
Hooks.on('renderSettingsConfig', (app, html) => {
|
||||||
|
// Use a timeout to ensure the DOM is fully rendered and attached,
|
||||||
|
// and to run after Foundry's own initial display/search logic.
|
||||||
|
setTimeout(() => {
|
||||||
|
// Find the master checkbox
|
||||||
|
const showTagsAllCheckbox = document.querySelector('input[name="dh-hotbar-cardview.showTagsAll"]');
|
||||||
|
if (!showTagsAllCheckbox) return;
|
||||||
|
|
||||||
|
const subSettings = ['Weapons', 'Armor', 'Consumables', 'Features', 'Domains'];
|
||||||
|
|
||||||
|
function toggleSubSettings() {
|
||||||
|
const isChecked = showTagsAllCheckbox.checked;
|
||||||
|
subSettings.forEach(setting => {
|
||||||
|
const input = document.querySelector(`input[name="dh-hotbar-cardview.showTags${setting}"]`);
|
||||||
|
if (input) {
|
||||||
|
const row = input.closest('.form-group');
|
||||||
|
if (row) {
|
||||||
|
if (isChecked) {
|
||||||
|
// Remove inline display style to let CSS handle it (usually flex)
|
||||||
|
row.style.display = '';
|
||||||
|
} else {
|
||||||
|
// Use !important to prevent Foundry's search or tab logic from overriding it
|
||||||
|
row.style.setProperty('display', 'none', 'important');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run once to set initial state
|
||||||
|
toggleSubSettings();
|
||||||
|
|
||||||
|
// Listen for changes
|
||||||
|
showTagsAllCheckbox.addEventListener('change', toggleSubSettings);
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
const originalActivate = CONFIG.ux.TooltipManager.prototype.activate;
|
const originalActivate = CONFIG.ux.TooltipManager.prototype.activate;
|
||||||
|
|
||||||
CONFIG.ux.TooltipManager.prototype.activate = async function(element, options = {}) {
|
CONFIG.ux.TooltipManager.prototype.activate = async function(element, options = {}) {
|
||||||
|
|
@ -11,11 +94,44 @@ Hooks.once('init', () => {
|
||||||
await this.enrichText(item);
|
await this.enrichText(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Calculate Feature Source Category
|
||||||
|
let featureSource = null;
|
||||||
|
if (item.type === 'feature' && item.system?.originItemType) {
|
||||||
|
const originType = item.system.originItemType;
|
||||||
|
// Attempt to get the localized string for the origin type (e.g., "Ancestry")
|
||||||
|
let originTypeString = game.i18n.localize(`TYPES.Item.${originType}`);
|
||||||
|
// Fallback just in case
|
||||||
|
if (originTypeString === `TYPES.Item.${originType}`) {
|
||||||
|
originTypeString = originType.charAt(0).toUpperCase() + originType.slice(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.parent && item.parent.items) {
|
||||||
|
const sourceItem = item.parent.items.find(i => i.type === originType);
|
||||||
|
if (sourceItem) {
|
||||||
|
featureSource = `${originTypeString} - ${sourceItem.name}`;
|
||||||
|
} else {
|
||||||
|
featureSource = originTypeString;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
featureSource = originTypeString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const showTagsAll = game.settings.get('dh-hotbar-cardview', 'showTagsAll');
|
||||||
|
|
||||||
options.html = await renderTemplate('modules/dh-hotbar-cardview/templates/cardview.hbs', {
|
options.html = await renderTemplate('modules/dh-hotbar-cardview/templates/cardview.hbs', {
|
||||||
item: item,
|
item: item,
|
||||||
description: item.system?.enrichedDescription ?? item.enrichedDescription ?? item.system?.description,
|
description: item.system?.enrichedDescription ?? item.enrichedDescription ?? item.system?.description,
|
||||||
config: CONFIG.DH,
|
config: CONFIG.DH,
|
||||||
allDomains: CONFIG.DH.DOMAIN?.allDomains ? CONFIG.DH.DOMAIN.allDomains() : {}
|
allDomains: CONFIG.DH.DOMAIN?.allDomains ? CONFIG.DH.DOMAIN.allDomains() : {},
|
||||||
|
featureSource: featureSource,
|
||||||
|
settings: {
|
||||||
|
weapon: showTagsAll && game.settings.get('dh-hotbar-cardview', 'showTagsWeapons'),
|
||||||
|
armor: showTagsAll && game.settings.get('dh-hotbar-cardview', 'showTagsArmor'),
|
||||||
|
consumable: showTagsAll && game.settings.get('dh-hotbar-cardview', 'showTagsConsumables'),
|
||||||
|
feature: showTagsAll && game.settings.get('dh-hotbar-cardview', 'showTagsFeatures'),
|
||||||
|
domain: showTagsAll && game.settings.get('dh-hotbar-cardview', 'showTagsDomains')
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
options.direction = this.constructor.TOOLTIP_DIRECTIONS.UP;
|
options.direction = this.constructor.TOOLTIP_DIRECTIONS.UP;
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@
|
||||||
.dh-hotbar-card .card-art-container {
|
.dh-hotbar-card .card-art-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 180px;
|
height: 260px;
|
||||||
border-bottom: 4px solid #f2cf5b; /* Gold line */
|
border-bottom: 4px solid #f2cf5b; /* Gold line */
|
||||||
background: #333;
|
background: #333;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -126,24 +126,43 @@
|
||||||
bottom: -14px;
|
bottom: -14px;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
background: #1a1a1a;
|
background: #f2cf5b;
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
padding: 4px 24px;
|
padding: 6px 26px;
|
||||||
clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 10px 100%, 0 50%);
|
clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 10px 100%, 0 50%);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dh-hotbar-card .card-type-banner::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 2px;
|
||||||
|
left: 2px;
|
||||||
|
right: 2px;
|
||||||
|
bottom: 2px;
|
||||||
|
background: #1a1a1a;
|
||||||
|
clip-path: polygon(8px 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 8px 100%, 0 50%);
|
||||||
|
z-index: -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dh-hotbar-card .card-type-banner.ancestry {
|
.dh-hotbar-card .card-type-banner.ancestry {
|
||||||
left: auto;
|
left: auto;
|
||||||
right: 20px;
|
right: 20px;
|
||||||
transform: none;
|
transform: none;
|
||||||
background: #f2cf5b;
|
background: var(--dh-card-banner-border);
|
||||||
color: #000;
|
color: #000;
|
||||||
border: 2px solid var(--dh-card-banner-border);
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dh-hotbar-card .card-type-banner.ancestry::before {
|
||||||
|
background: #f2cf5b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust layout so content doesn't collide with the banner */
|
/* Adjust layout so content doesn't collide with the banner */
|
||||||
|
|
@ -170,6 +189,35 @@
|
||||||
color: var(--dh-card-text);
|
color: var(--dh-card-text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dh-hotbar-card .card-tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dh-hotbar-card .card-tags .tag {
|
||||||
|
background: #1a1a1a;
|
||||||
|
border: 1px solid var(--dh-card-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #ddd;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dh-hotbar-card .card-tags .tag.damage-tag {
|
||||||
|
background: #441a1a;
|
||||||
|
border-color: #f2cf5b;
|
||||||
|
color: #f2cf5b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dh-hotbar-card .card-tags .tag i {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
.dh-hotbar-card .card-description p {
|
.dh-hotbar-card .card-description p {
|
||||||
margin: 0 0 8px 0;
|
margin: 0 0 8px 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,78 @@
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<h2 class="card-title">{{item.name}}</h2>
|
<h2 class="card-title">{{item.name}}</h2>
|
||||||
|
|
||||||
|
{{#if (and (eq item.type "weapon") settings.weapon)}}
|
||||||
|
<div class="card-tags">
|
||||||
|
<div class="tag">
|
||||||
|
<span>{{#if item.system.secondary}}{{localize "DAGGERHEART.ITEMS.Weapon.secondaryWeapon.full"}}{{else}}{{localize "DAGGERHEART.ITEMS.Weapon.primaryWeapon.full"}}{{/if}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tag">
|
||||||
|
{{#with (lookup config.GENERAL.burden item.system.burden) as | burden |}}
|
||||||
|
<span>{{localize burden.label}}</span>
|
||||||
|
{{/with}}
|
||||||
|
</div>
|
||||||
|
{{#if item.system.attack.roll.trait}}
|
||||||
|
<div class="tag">
|
||||||
|
{{#with (lookup config.ACTOR.abilities item.system.attack.roll.trait) as | trait |}}
|
||||||
|
<span>{{localize trait.label}}</span>
|
||||||
|
{{/with}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="tag">
|
||||||
|
{{#with (lookup config.GENERAL.range item.system.attack.range) as | range |}}
|
||||||
|
<span>{{localize range.label}}</span>
|
||||||
|
{{/with}}
|
||||||
|
</div>
|
||||||
|
<div class="tag damage-tag">
|
||||||
|
<span>{{{damageFormula item.system.attack}}} {{{damageSymbols item.system.attack.damage.parts}}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (and (eq item.type "armor") settings.armor)}}
|
||||||
|
<div class="card-tags">
|
||||||
|
<div class="tag">
|
||||||
|
<span>{{localize "DAGGERHEART.ITEMS.Armor.baseScore"}} {{item.system.baseScore}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tag">
|
||||||
|
<span>{{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.major"}} {{item.system.baseThresholds.major}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="tag">
|
||||||
|
<span>{{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.severe"}} {{item.system.baseThresholds.severe}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (and (eq item.type "consumable") settings.consumable)}}
|
||||||
|
<div class="card-tags">
|
||||||
|
<div class="tag">
|
||||||
|
<span>{{localize "DAGGERHEART.GENERAL.quantity"}} {{item.system.quantity}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (and (eq item.type "feature") settings.feature)}}
|
||||||
|
<div class="card-tags">
|
||||||
|
<div class="tag">
|
||||||
|
<span>{{#if featureSource}}{{featureSource}}{{else}}{{localize "TYPES.Item.feature"}}{{/if}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (and (eq item.type "domainCard") settings.domain)}}
|
||||||
|
<div class="card-tags">
|
||||||
|
<div class="tag">
|
||||||
|
{{#with (lookup config.DOMAIN.cardTypes item.system.type) as | type |}}
|
||||||
|
<span>{{localize type.label}}</span>
|
||||||
|
{{/with}}
|
||||||
|
</div>
|
||||||
|
<div class="tag">
|
||||||
|
<span>{{localize 'DAGGERHEART.GENERAL.levelShort'}} {{ item.system.level }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<div class="card-description">{{{description}}}</div>
|
<div class="card-description">{{{description}}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue