Skip to content

Commit

Permalink
Merge pull request #53 from PwQt/50-feature-dnd-30-compatibility
Browse files Browse the repository at this point in the history
DND 3.0 compatibility
  • Loading branch information
PwQt authored Feb 12, 2024
2 parents 2e33b50 + f1555d5 commit 53758d1
Show file tree
Hide file tree
Showing 10 changed files with 385 additions and 20 deletions.
6 changes: 5 additions & 1 deletion src/languages/en.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"MAGICITEMS.SettingTabNames": "Magic Items",
"MAGICITEMS.SettingIdentifiedOnly": "Only identified",
"MAGICITEMS.SettingIdentifiedOnlyHint": "Show Magic powers only for identified items",
"MAGICITEMS.SettingHideFromPlayers": "Hide Settings Tab From Players",
Expand All @@ -10,6 +11,7 @@

"MAGICITEMS.SheetTot": "tot",
"MAGICITEMS.SheetActives": "actives",
"MAGICITEMS.SheetUses": "Uses",

"MAGICITEMS.RechargeUnitDaily": "Daily",
"MAGICITEMS.RechargeUnitDawn": "At Dawn",
Expand Down Expand Up @@ -109,5 +111,7 @@

"MAGICITEMS.WarnNoActor": "You have no controlled actor, select an actor and retry.",
"MAGICITEMS.WarnNoMagicItem": "Your controlled Actor does not have an item named ",
"MAGICITEMS.WarnNoMagicItemSpell": "Your controlled Actor does not have a spell/feat named "
"MAGICITEMS.WarnNoMagicItemSpell": "Your controlled Actor does not have a spell/feat named ",

"MAGICITEMS.RandomResult": "Random Result"
}
3 changes: 1 addition & 2 deletions src/module.json
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,7 @@
"type": "system",
"manifest": "https://raw.githubusercontent.com/foundryvtt/dnd5e/master/system.json",
"compatibility": {
"verified": "2.3.1",
"maximum": "2.9.99"
"verified": "3.0.1"
}
}
],
Expand Down
9 changes: 8 additions & 1 deletion src/scripts/magic-item-entry/MagicItemTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ export class MagicItemTable extends AbstractMagicItemEntry {
}

serializeData() {
return {};
return {
consumption: this.consumption,
id: this.id,
uuid: this.uuid,
img: this.img,
name: this.name,
pack: this.pack,
};
}
}
4 changes: 4 additions & 0 deletions src/scripts/magic-item-helpers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { isRealNumber } from "./lib/lib";

export class MagicItemHelpers {
static isUsingNew5eSheet(sheet) {
return sheet?.constructor?.name === "ActorSheet5eCharacter2";
}

static numeric = function (value, fallback) {
// if ($.isNumeric(value)) {
// return parseInt(value);
Expand Down
6 changes: 5 additions & 1 deletion src/scripts/magic-item/MagicItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export class MagicItem {

serializeEntries(entries, trash) {
let data = {};
entries.forEach((spell, idx) => (data["" + idx] = spell.serializeData()));
entries.forEach((entry, idx) => (data["" + idx] = entry.serializeData()));
trash.forEach((index) => (data["-=" + index] = null));
return data;
}
Expand Down Expand Up @@ -318,6 +318,10 @@ export class MagicItem {
return this.items.filter((item) => item.id === itemId)[0];
}

get sheetEditable() {
return $(this.actor.sheet.form).hasClass("editable");
}

async renderSheet(itemId) {
let item = this.findByUuid(itemId);
if (!item) {
Expand Down
8 changes: 8 additions & 0 deletions src/scripts/magicitemactor.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class MagicItemActor {
this.listening = true;
this.instrument();
this.buildItems();
this.isUsingNew5eSheet = this.actor?.sheet && MagicItemHelpers.isUsingNew5eSheet(this.actor.sheet);
}

/**
Expand Down Expand Up @@ -66,6 +67,13 @@ export class MagicItemActor {
this.actor.longRest = this.longRest(this.actor.longRest, this);
}

/**
* Updates the property isUsingNew5eSheet with correct values.
*/
updateItemSheetOnActor() {
this.isUsingNew5eSheet = this.actor?.sheet && MagicItemHelpers.isUsingNew5eSheet(this.actor.sheet);
}

/**
*
* @param original
Expand Down
85 changes: 70 additions & 15 deletions src/scripts/magicitemsheet.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MAGICITEMS } from "./config.js";
import CONSTANTS from "./constants/constants.js";
import Logger from "./lib/Logger.js";
import { MagicItemHelpers } from "./magic-item-helpers.js";
import { MagicItemActor } from "./magicitemactor.js";

Expand Down Expand Up @@ -51,24 +52,57 @@ export class MagicItemSheet {
}

/**
*
* Render the sheet
* @returns {Promise<void>}
*/
async render() {
if (this.actor.hasItemsFeats()) {
await this.renderTemplate("magic-item-feat-sheet", "magic-items-feats-content", "features");
}
if (this.actor.hasItemsSpells()) {
await this.renderTemplate("magic-item-spell-sheet", "magic-items-spells-content", "spellbook");
Logger.log(`IsUsingNew5eSheet: ${this.actor.isUsingNew5eSheet}`);
this.actor.updateItemSheetOnActor();
if (!this.actor.isUsingNew5eSheet) {
if (this.actor.hasItemsFeats()) {
await this.renderTemplate(
"magic-item-feat-sheet.html",
"magic-items-feats-content",
"features",
"inventory-list"
);
}
if (this.actor.hasItemsSpells()) {
await this.renderTemplate(
"magic-item-spell-sheet.html",
"magic-items-spells-content",
"spellbook",
"inventory-list"
);
}
} else {
if (this.actor.hasItemsFeats()) {
await this.renderTemplate(
"magic-item-feat-sheet-v2.hbs",
"magic-items-feats-content",
"features",
"features-list"
);
this.html.find(".item-tooltip").each((idx, el) => this.addToolTips(el));
}
if (this.actor.hasItemsSpells()) {
await this.renderTemplate(
"magic-item-spell-sheet-v2.hbs",
"magic-items-spells-content",
"spells",
"spells-list"
);
this.html.find(".item-tooltip").each((idx, el) => this.addToolTips(el));
}
}

this.actor.items
.filter((item) => item.visible)
.forEach((item) => {
let itemEl = this.html.find(`.inventory-list .item-list .item[data-item-id="${item.id}"]`);
let h4 = itemEl.find("h4");
if (!h4.find("i.fa-magic").length) {
h4.append(CONSTANTS.HTML.MAGIC_ITEM_ICON);
let itemName = this.actor.isUsingNew5eSheet ? itemEl.find(".name .subtitle") : itemEl.find("h4");
if (!itemName.find("i.fa-magic").length) {
itemName.append(CONSTANTS.HTML.MAGIC_ITEM_ICON);
}
});

Expand All @@ -78,27 +112,48 @@ export class MagicItemSheet {
/**
* Utility functions, render or replace the template by name in the passed tab.
*
* @param name
* @param filename
* @param cls
* @param tab
* @returns {Promise<void>}
*/
async renderTemplate(name, cls, tab) {
let template = await renderTemplate(`modules/${CONSTANTS.MODULE_ID}/templates/${name}.html`, this.actor);
async renderTemplate(filename, cls, tab, listName) {
let template = await renderTemplate(`modules/${CONSTANTS.MODULE_ID}/templates/${filename}`, this.actor);
let el = this.html.find(`.${cls}`);
if (el.length) {
el.replaceWith(template);
} else {
this.html.find(`.${tab} .inventory-list`).append(template);
this.html.find(`.${tab} .${listName}`).append(template);
}
}

/**
* Adds spell tooltips to magic items on spells tab
*
* @param {*} element
*/
addToolTips(element) {
if ("tooltip" in element.dataset) return;
const target = element.closest("[data-item-id], [data-uuid]");
const uuid = target.dataset?.itemUuid;
if (!uuid) return;
element.dataset.tooltip = `
<section class="loading" data-uuid="${uuid}"><i class="fas fa-spinner fa-spin-pulse"></i></section>
`;
element.dataset.tooltipClass = "dnd5e2 dnd5e-tooltip item-tooltip";
element.dataset.tooltipDirection ??= "LEFT";
}

/**
*
*/
static handleEvents(html, actor) {
html.find(".item div.magic-item-image").click((evt) => MagicItemSheet.onItemRoll(evt, actor));
html.find(".item h4.spell-name").click((evt) => MagicItemSheet.onItemShow(evt));
if (!actor.isUsingNew5eSheet) {
html.find(".item div.magic-item-image").click((evt) => MagicItemSheet.onItemRoll(evt, actor));
html.find(".item h4.spell-name").click((evt) => MagicItemSheet.onItemShow(evt));
} else {
html.find(".item.magic-item .item-name").click((evt) => MagicItemSheet.onItemRoll(evt, actor));
}
MagicItemSheet.handleActorItemUsesChangeEvents(html, actor);
MagicItemSheet.handleMagicItemDragStart(html, actor);
}
Expand Down
45 changes: 45 additions & 0 deletions src/styles/magicitems.css
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,48 @@
border-color: var(--t5e-primary-font-color);
border-color: var(--t5ek-primary-font-color);
}

.dnd5e2 .items-section .items-header .spell-slots,
.dnd5e2 .items-section .item .spell-slots {
width: 50px;
}

.dnd5e2 .editable .items-section .items-header .spell-slots input {
color: white;
width: 50%;
}

.dnd5e2 .items-section .items-header .spell-rechargeable,
.dnd5e2 .items-section .item .spell-rechargeable {
width: 150px;
display: flex;
gap: 0.1875rem;
align-self: center;
align-items: baseline;
}

.dnd5e2 .items-section .items-header .spell-level,
.dnd5e2 .items-section .item .spell-level {
width: 40px;
}

.dnd5e2 .items-section .items-header .spell-consumption,
.dnd5e2 .items-section .item .spell-consumption {
width: 60px;
}

.dnd5e2 .items-section .items-header .spell-upcast,
.dnd5e2 .items-section .item .spell-upcast {
width: 50px;
justify-content: center;
padding: 0;
position: relative;
}

.dnd5e2 .items-section .items-header .feat-consumption,
.dnd5e2 .items-section .item .feat-consumption {
width: 70px;
justify-content: center;
padding: 0;
position: relative;
}
118 changes: 118 additions & 0 deletions src/templates/magic-item-feat-sheet-v2.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
{{#if hasVisibleItems}}
<div class="magic-items-feats-content">
<div class="inventory-filters spellbook-filters magic-items-head">
<label>
<h3>
{{localize "MAGICITEMS.SettingTabNames"}} - {{localize "MAGICITEMS.SheetTot"}}: {{magicItemsCount}}, {{localize "MAGICITEMS.SheetActives"}}:
{{magicItemsActiveCount}}
</h3>
</label>
</div>
{{#each items as |item i|}} {{#if (and visible active hasFeats)}}
<div class="items-section card" data-type="spell">
<div class="items-header header">
<h3 class="item-name spell-header" draggable="true">{{name}}</h3>
{{#if chargesOnWholeItem}}
<div class="item-header spell-slots">
{{#if sheetEditable}}
<input data-item-id="magicitems.{{id}}.uses" type="text" value="{{uses}}" placeholder="0" />
<span class="sep"> / {{charges}}</span>
{{else}}
{{uses}} / {{charges}}
{{/if}}
</div>
{{/if}}
{{#if chargesPerSpell}}
<div class="item-header spell-slots">
{{localize "MAGICITEMS.SheetUses"}}
</div>
{{/if}}
<div class="item-header spell-rechargeable">{{rechargeableLabel}}</div>
<div class="item-header feat-consumption">{{localize "MAGICITEMS.SheetFeatOnUsage"}}</div>
</div>
<ol class="item-list unlist">
<!-- FEATURES INTEGRATION -->
{{#each feats as |feat|}}
<li
class="item magic-item"
data-magic-item-id="{{../id}}"
data-item-id="{{feat.id}}"
data-item-uuid="{{feat.uuid}}"
data-entry-id="{{../id}}"
draggable="true"
>
<div class="item-name item-action item-tooltip rollable" role="button" aria-label="{{feat.displayName}}">
<img class="item-image gold-icon magic-item-image" src="{{feat.img}}" alt="{{feat.name}}">
<div class="name name-stacked">
<span class="title">{{ feat.displayName }}</span>
<span class="subtitle"></span>
</div>
<div class="tags"></div>
</div>
{{#if ../chargesPerSpell}}
<div class="item-detail spell-slots">
{{#if ../sheetEditable}}
<input
data-item-id="magicitems.{{../id}}.{{feat.id}}.uses"
type="text"
value="{{feat.uses}}"
placeholder="0"
/>
<span class="sep"> / </span>
<input type="text" value="{{../charges}}" placeholder="0" />
{{else}}
{{feat.uses}} / {{../charges}}
{{/if}}
</div>
<div class="item-detail spell-rechargeable">-</div>
{{/if}}
<div class="item-detail feat-consumption">
<span class="condensed">{{feat.consumptionLabel}}</span>
</div>
</li>
{{/each}}
<!-- ROLLTABLES INTEGRATION -->
{{#if hasTableAsFeats}} {{#each tableAsFeats as |table|}}
<li
class="item magic-item"
data-magic-item-id="{{../id}}"
data-item-id="{{table.id}}"
data-item-id="{{table.uuid}}"
data-entry-id="{{../id}}"
draggable="true"
>
<div class="item-name item-action item-tooltip rollable" role="button" aria-label="{{table.displayName}}">
<img class="item-image gold-icon magic-item-image" src="{{table.img}}" alt="{{table.name}}">
<div class="name name-stacked">
<span class="title">{{ table.displayName }}</span>
<span class="subtitle"></span>
</div>
<div class="tags"></div>
</div>
{{#if ../chargesPerSpell}}
<div class="item-detail spell-slots">
{{#if ../sheetEditable}}
<input
data-item-id="magicitems.{{../id}}.{{table.id}}.uses"
type="text"
value="{{table.uses}}"
placeholder="0"
/>
<span class="sep"> / </span>
<input type="text" value="{{../charges}}" placeholder="0" />
{{else}}
{{feats.uses}} / {{../charges}}
{{/if}}
</div>
<div class="item-detail spell-rechargeable">-</div>
{{/if}}
<div class="item-detail feat-consumption">
<span class="condensed">{{table.consumption}}</span>
</div>
</li>
{{/each}} {{/if}}
</ol>
</div>
{{/if}} {{/each}}
</div>
{{/if}}
Loading

0 comments on commit 53758d1

Please sign in to comment.