changed character/party sheet displays to display in cr values
This commit is contained in:
+8
-1
@@ -22,5 +22,12 @@
|
|||||||
"path": "lang/en.json"
|
"path": "lang/en.json"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"scripts": ["scripts/update-compendium.js"]
|
"scripts": [
|
||||||
|
"scripts/sf2e-silver-to-credits.js",
|
||||||
|
"scripts/update-compendium.js",
|
||||||
|
"scripts/convert-prices-to-credits.js",
|
||||||
|
"scripts/add-coins-dialog.js",
|
||||||
|
"scripts/party-sheet-prices.js"
|
||||||
|
],
|
||||||
|
"styles": ["styles/sf2e-silver-to-credits.css"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
Hooks.on("renderDialog", (dialog, html, data) => {
|
||||||
|
// Check if this dialog contains currency inputs
|
||||||
|
if (
|
||||||
|
html.find('[name="pp"], [name="gp"], [name="sp"], [name="cp"]').length > 0
|
||||||
|
) {
|
||||||
|
console.log("Add Coins dialog detected, hiding currencies");
|
||||||
|
hideCurrenciesInAddCoinsDialog(html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also hook into the specific PF2e currency dialog
|
||||||
|
Hooks.on("renderCurrencyExchange", (dialog, html, data) => {
|
||||||
|
console.log("CurrencyExchange dialog detected");
|
||||||
|
hideCurrenciesInAddCoinsDialog(html);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fallback: use a MutationObserver to catch the dialog when it appears
|
||||||
|
const dialogObserver = new MutationObserver((mutations) => {
|
||||||
|
mutations.forEach((mutation) => {
|
||||||
|
if (mutation.addedNodes.length) {
|
||||||
|
mutation.addedNodes.forEach((node) => {
|
||||||
|
if (node.nodeType === 1) {
|
||||||
|
// Element node
|
||||||
|
const $node = $(node);
|
||||||
|
|
||||||
|
// Check if this node or its children contain currency inputs
|
||||||
|
if (
|
||||||
|
$node.find('[name="pp"], [name="gp"], [name="sp"], [name="cp"]')
|
||||||
|
.length > 0 ||
|
||||||
|
$node.is('[name="pp"], [name="gp"], [name="sp"], [name="cp"]')
|
||||||
|
) {
|
||||||
|
console.log("Currency dialog detected via MutationObserver");
|
||||||
|
hideCurrenciesInAddCoinsDialog($node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
dialogObserver.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
function hideCurrenciesInAddCoinsDialog(html) {
|
||||||
|
console.log("Attempting to hide currencies");
|
||||||
|
|
||||||
|
// Find all form groups
|
||||||
|
const formGroups = html.find(".form-group");
|
||||||
|
console.log("Found form groups:", formGroups.length);
|
||||||
|
|
||||||
|
formGroups.each(function () {
|
||||||
|
const $group = $(this);
|
||||||
|
const input = $group.find("input");
|
||||||
|
const inputName = input.attr("name");
|
||||||
|
const label = $group.find("label").text();
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
"Processing form group with input name:",
|
||||||
|
inputName,
|
||||||
|
"label:",
|
||||||
|
label,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Hide Platinum, Gold, and Copper form groups
|
||||||
|
if (inputName === "pp" || inputName === "gp" || inputName === "cp") {
|
||||||
|
console.log("Hiding:", inputName);
|
||||||
|
$group.css("display", "none");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rename Silver to Credits
|
||||||
|
if (inputName === "sp") {
|
||||||
|
console.log("Renaming Silver to Credits");
|
||||||
|
$group.find("label").text("Credits");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
Hooks.on("renderActorSheet", (app, html, data) => {
|
||||||
|
convertPricesToCredits(html);
|
||||||
|
});
|
||||||
|
|
||||||
|
Hooks.on("updateActor", (actor, data) => {
|
||||||
|
const sheets = actor.apps;
|
||||||
|
sheets.forEach((sheet) => {
|
||||||
|
if (sheet.element) {
|
||||||
|
convertPricesToCredits(sheet.element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function convertPricesToCredits(html) {
|
||||||
|
// Find all price displays in the sheet
|
||||||
|
const priceElements = html.find("[data-price]");
|
||||||
|
|
||||||
|
priceElements.each(function () {
|
||||||
|
const $element = $(this);
|
||||||
|
let priceText = $element.text();
|
||||||
|
|
||||||
|
// Convert pp to cr (1 pp = 100 cr)
|
||||||
|
priceText = priceText.replace(/(\d+(?:\.\d+)?)\s*pp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) * 100;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert gp to cr (1 gp = 10 cr)
|
||||||
|
priceText = priceText.replace(/(\d+(?:\.\d+)?)\s*gp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) * 10;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert cp to cr (1 cp = 0.1 cr)
|
||||||
|
priceText = priceText.replace(/(\d+(?:\.\d+)?)\s*cp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) / 10;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace sp with cr (no conversion needed, 1 sp = 1 cr)
|
||||||
|
priceText = priceText.replace(/(\d+(?:\.\d+)?)\s*sp/gi, "$1 cr");
|
||||||
|
|
||||||
|
$element.text(priceText);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also handle price text in tooltips and other text content
|
||||||
|
const allElements = html.find("*");
|
||||||
|
allElements.each(function () {
|
||||||
|
const $element = $(this);
|
||||||
|
|
||||||
|
// Skip elements that have child elements (to avoid processing parent containers)
|
||||||
|
if ($element.children().length === 0) {
|
||||||
|
let text = $element.text();
|
||||||
|
const originalText = text;
|
||||||
|
|
||||||
|
// Convert pp to cr (1 pp = 100 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*pp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) * 100;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert gp to cr (1 gp = 10 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*gp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) * 10;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert cp to cr (1 cp = 0.1 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*cp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) / 10;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace sp with cr (no conversion needed, 1 sp = 1 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*sp/gi, "$1 cr");
|
||||||
|
|
||||||
|
// Only update if text changed
|
||||||
|
if (text !== originalText) {
|
||||||
|
$element.text(text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
Hooks.on("renderPartySheet", (app, html, data) => {
|
||||||
|
convertPartySheetPricesToCredits(html);
|
||||||
|
});
|
||||||
|
|
||||||
|
Hooks.on("updateActor", (actor, data) => {
|
||||||
|
// Also update when actors are updated
|
||||||
|
const sheets = actor.apps;
|
||||||
|
sheets.forEach((sheet) => {
|
||||||
|
if (
|
||||||
|
sheet.constructor.name === "PartySheet" ||
|
||||||
|
sheet.element?.closest(".party-sheet")
|
||||||
|
) {
|
||||||
|
convertPartySheetPricesToCredits(sheet.element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Fallback: use MutationObserver to catch party sheet updates
|
||||||
|
const partySheetObserver = new MutationObserver((mutations) => {
|
||||||
|
mutations.forEach((mutation) => {
|
||||||
|
if (mutation.addedNodes.length || mutation.type === "characterData") {
|
||||||
|
mutation.addedNodes.forEach((node) => {
|
||||||
|
if (node.nodeType === 1) {
|
||||||
|
// Element node
|
||||||
|
const $node = $(node);
|
||||||
|
|
||||||
|
// Check if this contains party sheet value spans
|
||||||
|
if ($node.find(".value").length > 0 || $node.hasClass("value")) {
|
||||||
|
convertPartySheetPricesToCredits($node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
partySheetObserver.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
characterData: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
function convertPartySheetPricesToCredits(html) {
|
||||||
|
console.log("Converting party sheet prices to credits");
|
||||||
|
|
||||||
|
// Target the .value spans specifically
|
||||||
|
const valueSpans = html.find(".value");
|
||||||
|
|
||||||
|
valueSpans.each(function () {
|
||||||
|
const $span = $(this);
|
||||||
|
let text = $span.text();
|
||||||
|
const originalText = text;
|
||||||
|
|
||||||
|
// Convert pp to cr (1 pp = 100 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*pp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) * 100;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert gp to cr (1 gp = 10 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*gp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) * 10;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Convert cp to cr (1 cp = 0.1 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*cp/gi, (match, amount) => {
|
||||||
|
const creditAmount = parseFloat(amount) / 10;
|
||||||
|
return `${creditAmount} cr`;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Replace sp with cr (no conversion needed, 1 sp = 1 cr)
|
||||||
|
text = text.replace(/(\d+(?:\.\d+)?)\s*sp/gi, "$1 cr");
|
||||||
|
|
||||||
|
// Only update if text changed
|
||||||
|
if (text !== originalText) {
|
||||||
|
console.log("Converting:", originalText, "to:", text);
|
||||||
|
$span.text(text);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
Hooks.on("renderActorSheet", (app, html, data) => {
|
||||||
|
replaceSilverWithCredits(html);
|
||||||
|
});
|
||||||
|
|
||||||
|
Hooks.on("updateActor", (actor, data) => {
|
||||||
|
const sheets = actor.apps;
|
||||||
|
sheets.forEach((sheet) => {
|
||||||
|
if (sheet.element) {
|
||||||
|
replaceSilverWithCredits(sheet.element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function replaceSilverWithCredits(html) {
|
||||||
|
// Update tooltip for silver currency
|
||||||
|
const silverContainers = html.find('[data-unit="sp"]');
|
||||||
|
silverContainers.each(function () {
|
||||||
|
$(this).attr("data-tooltip", "Credits");
|
||||||
|
$(this).find(".currency-image").attr("data-tooltip", "Credits");
|
||||||
|
});
|
||||||
|
|
||||||
|
updateTooltips();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateTooltips() {
|
||||||
|
const tooltipObserver = new MutationObserver(() => {
|
||||||
|
const allTooltips = document.querySelectorAll(".tooltip, [role='tooltip']");
|
||||||
|
allTooltips.forEach((tooltip) => {
|
||||||
|
if (tooltip.textContent.trim() === "Silver") {
|
||||||
|
tooltip.textContent = "Credits";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tooltipObserver.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
subtree: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inject CSS rules with high specificity to override the PF2e system CSS
|
||||||
|
const styleSheet = document.createElement("style");
|
||||||
|
styleSheet.id = "sf2e-silver-to-credits-override";
|
||||||
|
styleSheet.textContent = `
|
||||||
|
/* Override silver currency background image globally */
|
||||||
|
[data-unit="sp"] .currency-image {
|
||||||
|
background-image: url('modules/sf2e-silver-to-credits/icons/equipment/treasure/currency/credits.webp') !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Catch it in any context */
|
||||||
|
.currency-image[data-tooltip*="Silver"],
|
||||||
|
[style*="silver-pieces.webp"] {
|
||||||
|
background-image: url('modules/sf2e-silver-to-credits/icons/equipment/treasure/currency/credits.webp') !important;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
document.head.appendChild(styleSheet);
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/* Hide Platinum, Gold, and Copper currencies on PF2e character sheet */
|
||||||
|
.pf2e.sheet.actor.character [data-unit="pp"],
|
||||||
|
.pf2e.sheet.actor.character [data-unit="gp"],
|
||||||
|
.pf2e.sheet.actor.character [data-unit="cp"],
|
||||||
|
.sheet.actor.character [data-unit="pp"],
|
||||||
|
.sheet.actor.character [data-unit="gp"],
|
||||||
|
.sheet.actor.character [data-unit="cp"],
|
||||||
|
.currency-pp,
|
||||||
|
.currency-gp,
|
||||||
|
.currency-cp,
|
||||||
|
.currency li.pp,
|
||||||
|
.currency li.gp,
|
||||||
|
.currency li.cp,
|
||||||
|
.coinage [data-unit="pp"],
|
||||||
|
.coinage [data-unit="gp"],
|
||||||
|
.coinage [data-unit="cp"],
|
||||||
|
.fa-coins.pp,
|
||||||
|
.fa-coins.gp,
|
||||||
|
.fa-coins.cp {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Override silver currency icon with EXTREME specificity */
|
||||||
|
[data-unit="sp"] .currency-image {
|
||||||
|
background-image: url("../icons/equipment/treasure/currency/credits.webp") !important;
|
||||||
|
background-size: cover !important;
|
||||||
|
background-repeat: no-repeat !important;
|
||||||
|
background-position: center !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Extra fallback for any silver piece reference */
|
||||||
|
[style*="silver-pieces.webp"] {
|
||||||
|
background-image: url("../icons/equipment/treasure/currency/credits.webp") !important;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user