zischenstand

This commit is contained in:
centron\schwoerer
2025-11-14 14:52:43 +01:00
parent 30aa03c6db
commit f054a31b20
8733 changed files with 900639 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
.pfledger-table, .pfledger-td {
border: 1px solid #000000;
border-collapse: collapse;
width: 98%;
align-content: center;
text-align: center;
font-size: 11px;
font-style: oblique;
font-family: serif;
padding: 4px;
}
.pfledger-th{
font-style: normal;
font-size: 10px
}
.pfledger-desc-box
{
min-width: 457px;
content: "\f58e";
font-weight: 900;
font-family: "Font Awesome 5 Free";
font-size: 12px;
font-variant: small-caps;
color: #4b4a44;
margin: 0;
}
.pfledger-button
{
font-size: 12px;
line-height: 12px;
height: auto;
width: auto;
margin: 0, 8px;
content: "\f58e";
font-weight: 900;
font-family: "Font Awesome 5 Free";
}
.pfledger-spacer
{
margin: 0 8px;
flex: 0 0 20px;
}

View File

@@ -0,0 +1,36 @@
{
"title": "Pathfinder Ledger",
"description": "A simple module which records money in and out.",
"version": "1.0.7",
"authors": [
{
"name": "Lee 'Almighty_gir' Devonald",
"url": "https://github.com/Almightygir/PFLedger",
"discord": "Almighty_gir#6379",
"flags": {}
}
],
"scripts": [
"scripts/ledger.js"
],
"styles": [
"css/ledger.css"
],
"url": "https://github.com/Almightygir/PFLedger",
"manifest": "https://github.com/Almightygir/PFLedger/releases/latest/download/module.json",
"download": "https://github.com/Almightygir/PFLedger/releases/download/v1.0.7/module.zip",
"id": "PFLedger",
"relationships": {
"systems": [
{
"id": "pf1",
"type": "system",
"compatibility": {}
}
]
},
"compatibility": {
"minimum": "0.7.9",
"verified": "9"
}
}

View File

@@ -0,0 +1,326 @@
console.log('Ledger ! Im running!');
//Main class
class Ledger
{
static ID = 'PFLedger';
static FLAGS = { LEDGERS: 'ledgers' }
static TEMPLATES = { LEDGERLIST: `modules/${this.ID}/templates/ledger.hbs` }
static log(force, ...args)
{
const shouldLog = force || game.modules.get('_dev-mode')?.api?.getPackageDebugValue(this.ID);
if (shouldLog)
{
console.log(this.ID, '|', ...args);
}
}
}
//data class
class LedgerData
{
//get all ledgers in the game
static get allLegers() {}
//get ledger for a giver nuser
static getLedgerForActor(actor)
{
return actor.getFlag(Ledger.ID, Ledger.FLAGS.LEDGERS);
}
//creates a new entry for the ledger
static addLedgerEntry(actor, userId, inCurrency, inAltCurrency, inCurrencyDiff, inAltCurrencyDiff, inLedgerLog)
{
//generate new random id for this ledger entry and populate the userID
const actorId = actor.id;
const newLedgerEntry =
{
Log: inLedgerLog,
currency: inCurrency,
altCurrency: inAltCurrency,
currencyDiff: inCurrencyDiff,
altCurrencyDiff: inAltCurrencyDiff,
Character: actor.name,
UserName: game.users.get(userId).name,
id: foundry.utils.randomID(16),
ActorId: actorId,
}
const newEntries = { [newLedgerEntry.id]: newLedgerEntry }
return game.actors.get(actorId)?.setFlag(Ledger.ID, Ledger.FLAGS.LEDGERS, newEntries);
}
static getActorLedgerLastEntry(actor)
{
const ledgerEntries = this.getLedgerForActor(actor);
if(ledgerEntries)
{
let actorEntries = new Array();
for(const ledgerEntry of Object.values(ledgerEntries))
{
if(ledgerEntry)
{
if(ledgerEntry.ActorId === actor.id)
{
actorEntries.push(ledgerEntry);
}
}
}
if(actorEntries.length > 0)
{
return actorEntries[actorEntries.length-1];
}
}
return null;
}
}
//useful stuff
class CashConverter
{
static convertCurrencyToCP(currency)
{
let CP = currency.cp;
CP += currency.sp * 10;
CP += currency.gp * 100;
CP += currency.pp * 1000;
return CP;
}
static convertToCP(inCP, inSP, inGP, inPP)
{
let CP = inCP;
CP += inSP * 10;
CP += inGP * 100;
CP += inPP * 1000;
return CP;
}
static currencyCheck(inCurrencyA, inCurrencyB)
{
return inCurrencyA.cp == inCurrencyB.cp &&
inCurrencyA.sp == inCurrencyB.sp &&
inCurrencyA.gp == inCurrencyB.gp &&
inCurrencyA.pp == inCurrencyB.pp;
}
static getCurrencyDelta(inCurrencyA, inCurrencyB)
{
const currency =
{
cp : inCurrencyA.cp - inCurrencyB.cp,
sp : inCurrencyA.sp - inCurrencyB.sp,
gp : inCurrencyA.gp - inCurrencyB.gp,
pp : inCurrencyA.pp - inCurrencyB.pp,
}
currency.cp = currency.cp ? currency.cp : 0;
currency.sp = currency.sp ? currency.sp : 0;
currency.gp = currency.gp ? currency.gp : 0;
currency.pp = currency.pp ? currency.pp : 0;
return currency;
}
}
//the ledger form
class LedgerForm extends FormApplication
{
static get defaultOptions()
{
const defaults = super.defaultOptions;
const overrides =
{
height: '700',
width: '650',
id: 'ledger',
template: Ledger.TEMPLATES.LEDGERLIST,
title: 'Ledger',
currencies: ['cp', 'sp', 'gp', 'pp'],
};
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
return mergedOptions;
}
getData(options)
{
let outLedgers = {ledgers: LedgerData.getLedgerForActor(this.object)};
return outLedgers;
}
}
function addLedgerEntry_Ext(actor, description)
{
//if for any reason actor is null, return early.
if(actor === null)
{
console.log('Ledger ! Actor is null, exiting early');
return;
}
const userId = game.user.id;
const altCurrency = actor.data.data.altCurrency;
const currency = actor.data.data.currency;
const lastEntry = LedgerData.getActorLedgerLastEntry(actor, userId);
//if the last entry is null, it doesn't exist, so we should make a new entry.
if(lastEntry === null)
{
console.log('Ledger ! No last entry found, creating new entry');
LedgerData.addLedgerEntry(actor, userId, currency, altCurrency, currency, altCurrency, "Initial entry.");
}
else
{
//check if there's a delta, if there is we need to create an entry.
if(!CashConverter.currencyCheck(altCurrency, lastEntry.altCurrency) || !CashConverter.currencyCheck(currency, lastEntry.currency))
{
console.log('Ledger ! Changes detected, adding a new entry!');
const currencyDiff = CashConverter.getCurrencyDelta(currency, lastEntry.currency);
const altCurrencyDiff = CashConverter.getCurrencyDelta(altCurrency, lastEntry.altCurrency);
LedgerData.addLedgerEntry(actor, userId, currency, altCurrency, currencyDiff, altCurrencyDiff, description);
}
}
}
function getActorLedger_Ext(actor)
{
let ledgerForm = new LedgerForm(actor).render(true, {actor});
}
function addLedgerButtons(sheet, jq, data)
{
const actor = data.actor;
if (!actor || !actor.isOwner)
{
return;
}
const html = jq[0];
const tab = html.querySelector('.tab.inventory');
if (!tab)
{
return;
}
const currencyTab = tab.querySelector('.inventory-filters');
if (!currencyTab)
{
return;
}
const updateTooltip = 'Add ledger entry';
const openLedgerTooltip = 'Opens the ledger';
const descBoxTooltip = 'Add ledger entry';
const newRow = document.createElement("flexrow");
newRow.classList.add("pfledger-spacer");
const descriptionBox = document.createElement("input");
descriptionBox.classList.add("pfledger-desc-box");
descriptionBox.setAttribute("value", "...");
descriptionBox.title = descBoxTooltip;
currencyTab.append(descriptionBox);
const updateButton = document.createElement("button");
updateButton.classList.add("pfledger-button");
updateButton.textContent = "Update Ledger";
updateButton.title = updateTooltip;
updateButton.addEventListener("click", event => {
addLedgerEntry_Ext(actor, descriptionBox.value)
});
currencyTab.append(updateButton);
const openLedgerButton = document.createElement("button");
openLedgerButton.classList.add("pfledger-button");
openLedgerButton.textContent = "Open Ledger...";
openLedgerButton.title = openLedgerTooltip;
openLedgerButton.addEventListener("click", event => {
getActorLedger_Ext(actor)
});
currencyTab.append(openLedgerButton);
}
Hooks.on('renderActorSheetPF', addLedgerButtons);
//GM ledger forms.
class ledgerFormGM extends FormApplication
{
static get defaultOptions()
{
const defaults = super.defaultOptions;
const overrides =
{
height: '700',
width: '650',
id: 'ledger',
template: Ledger.TEMPLATES.LEDGERLIST,
title: 'Ledger',
currencies: ['cp', 'sp', 'gp', 'pp'],
};
const mergedOptions = foundry.utils.mergeObject(defaults, overrides);
return mergedOptions;
}
getData(options)
{
let allLedgers;
game.actors.forEach(actor =>{
const currentLedgers = LedgerData.getLedgerForActor(actor);
if(currentLedgers)
{
if(!allLedgers)
{
allLedgers = currentLedgers;
}
else
{
allLedgers = {...allLedgers, ...currentLedgers};
}
}
});
return {ledgers: allLedgers};
}
}
function getGMLedger_Ext()
{
let gmLedgerForm = new ledgerFormGM().render(true);
}
function GMLedgerButton(sheet)
{
if(!game.user.isGM)
{
return;
}
const openLedgerTooltip = 'Opens the combined player ledgers';
const ledgerButtonContents = 'Open Ledgers...';
const pfDetailsTab = sheet.element[0].querySelector('#pf1-details');
if(!pfDetailsTab || pfDetailsTab.querySelector('#PathfinderGMLedgerButton'))
{
return;
}
const openGMLedgerButton = document.createElement("button");
openGMLedgerButton.textContent = ledgerButtonContents;
openGMLedgerButton.title = openLedgerTooltip;
openGMLedgerButton.id = "PathfinderGMLedgerButton";
openGMLedgerButton.addEventListener("click", event =>{
getGMLedger_Ext();
})
pfDetailsTab.append(openGMLedgerButton);
}
Hooks.on('changeSidebarTab', GMLedgerButton);

View File

@@ -0,0 +1,57 @@
{{log 'ledgers' this}}
<div class = "pfledger">
<form>
<ul>
<table class = "pfledger-table">
<thead>
<tr>
<th class = "pfledger-th">Log</th>
<th class = "pfledger-th">PP</th>
<th class = "pfledger-th">GP</th>
<th class = "pfledger-th">SP</th>
<th class = "pfledger-th">CP</th>
<th class = "pfledger-th">WL:</th>
<th class = "pfledger-th">PP</th>
<th class = "pfledger-th">GP</th>
<th class = "pfledger-th">SP</th>
<th class = "pfledger-th">CP</th>
<th class = "pfledger-th">Character</th>
<th class = "pfledger-th">User</th>
</tr>
</thead>
<tbody>
{{#each ledgers}}
<tr>
<td class = "pfledger-td">{{Log}}</td>
<td class = "pfledger-td">{{currencyDiff.pp}}</td>
<td class = "pfledger-td">{{currencyDiff.gp}}</td>
<td class = "pfledger-td">{{currencyDiff.sp}}</td>
<td class = "pfledger-td">{{currencyDiff.cp}}</td>
<td class = "pfledger-td"></td>
<td class = "pfledger-td">{{altCurrencyDiff.pp}}</td>
<td class = "pfledger-td">{{altCurrencyDiff.gp}}</td>
<td class = "pfledger-td">{{altCurrencyDiff.sp}}</td>
<td class = "pfledger-td">{{altCurrencyDiff.cp}}</td>
<td class = "pfledger-td">{{Character}}</td>
<td class = "pfledger-td">{{UserName}}</td>
</tr>
<tr>
<td class = "pfledger-td">New Total:</td>
<td class = "pfledger-td">{{currency.pp}}</td>
<td class = "pfledger-td">{{currency.gp}}</td>
<td class = "pfledger-td">{{currency.sp}}</td>
<td class = "pfledger-td">{{currency.cp}}</td>
<td class = "pfledger-td"></td>
<td class = "pfledger-td">{{altCurrency.pp}}</td>
<td class = "pfledger-td">{{altCurrency.gp}}</td>
<td class = "pfledger-td">{{altCurrency.sp}}</td>
<td class = "pfledger-td">{{altCurrency.cp}}</td>
<td class = "pfledger-td"></td>
<td class = "pfledger-td"></td>
</tr>
{{/each}}
</tbody>
</table>
</ul>
</form>
</div>