zischenstand
This commit is contained in:
46
src/modules/PFLedger/css/ledger.css
Normal file
46
src/modules/PFLedger/css/ledger.css
Normal 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;
|
||||
}
|
||||
36
src/modules/PFLedger/module.json
Normal file
36
src/modules/PFLedger/module.json
Normal 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"
|
||||
}
|
||||
}
|
||||
326
src/modules/PFLedger/scripts/ledger.js
Normal file
326
src/modules/PFLedger/scripts/ledger.js
Normal 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);
|
||||
57
src/modules/PFLedger/templates/ledger.hbs
Normal file
57
src/modules/PFLedger/templates/ledger.hbs
Normal 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>
|
||||
Reference in New Issue
Block a user