Skip to content

Commit 49c86cd

Browse files
authored
Merge pull request #433 from costonb/split-currency
Add ability to split coins
2 parents 3176599 + 589fbcf commit 49c86cd

File tree

2 files changed

+105
-197
lines changed

2 files changed

+105
-197
lines changed

lootsheet-simple.js

+86-187
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,84 @@ class LootSheet5eNPCHelper {
2626
})
2727
return currency
2828
}
29+
30+
/**
31+
* Shared code for distributing coins so it can be called both from socket and as GM
32+
* @param {Actor5e} containerActor - The actor who is initiating the distribution of coins
33+
* @returns
34+
*/
35+
static distributeCoins(containerActor) {
36+
let observers = []
37+
let players = game.users.players
38+
39+
// Calculate observers
40+
for (let player of players) {
41+
let playerPermission = LootSheet5eNPCHelper.getLootPermissionForPlayer(containerActor, player)
42+
if (player != 'default' && playerPermission >= 2) {
43+
if (player.character != null && (player.role === 1 || player.role === 2))
44+
observers.push(player.character)
45+
}
46+
}
47+
48+
if (observers.length === 0) return
49+
50+
// Calculate split of currency
51+
let currencySplit = foundry.utils.duplicate(
52+
LootSheet5eNPCHelper.convertCurrencyFromObject(containerActor.system.currency),
53+
)
54+
55+
// keep track of the remainder
56+
let currencyRemainder = {}
57+
58+
for (let c in currencySplit) {
59+
if (observers.length) {
60+
// calculate remainder
61+
currencyRemainder[c] = currencySplit[c] % observers.length
62+
63+
currencySplit[c] = Math.floor(currencySplit[c] / observers.length)
64+
} else currencySplit[c] = 0
65+
}
66+
67+
// add currency to actors existing coins
68+
let msg = []
69+
for (let u of observers) {
70+
if (u === null) continue
71+
72+
msg = []
73+
let currency = LootSheet5eNPCHelper.convertCurrencyFromObject(u.system.currency),
74+
newCurrency = foundry.utils.duplicate(
75+
LootSheet5eNPCHelper.convertCurrencyFromObject(u.system.currency),
76+
)
77+
78+
for (let c in currency) {
79+
// add msg for chat description
80+
if (currencySplit[c]) {
81+
msg.push(` ${currencySplit[c]} ${c} coins`)
82+
}
83+
// Add currency to permitted actor
84+
newCurrency[c] = parseInt(currency[c] || 0) + (currencySplit[c] ?? 0)
85+
}
86+
u.update({
87+
'system.currency': newCurrency,
88+
})
89+
90+
// Create chat message for coins received
91+
if (msg.length != 0) {
92+
let message = `${u.name} receives: `
93+
message += msg.join(',')
94+
ChatMessage.create({
95+
user: game.user._id,
96+
speaker: {
97+
actor: containerActor,
98+
alias: containerActor.name,
99+
},
100+
content: message,
101+
})
102+
}
103+
}
104+
// Remove currency from loot actor.
105+
containerActor.update({'system.currency': currencyRemainder})
106+
}
29107
}
30108

31109
class QuantityDialog extends Dialog {
@@ -925,6 +1003,9 @@ class LootSheet5eNPC extends dnd5e.applications.actor.ActorSheet5eNPC2 {
9251003
*/
9261004
_distributeCoins(event) {
9271005
event.preventDefault()
1006+
if (!game.settings.get('lootsheet-simple', 'lootCurrency')) {
1007+
return
1008+
}
9281009

9291010
let targetGm = null
9301011
game.users.forEach((u) => {
@@ -942,11 +1023,14 @@ class LootSheet5eNPC extends dnd5e.applications.actor.ActorSheet5eNPC2 {
9421023
if (this.token === null) {
9431024
return ui.notifications.error(`You must loot items from a token.`)
9441025
}
1026+
if (!game.user.character) {
1027+
return ui.notifications.error(`No active character for user.`)
1028+
}
9451029

9461030
if (game.user.isGM) {
9471031
//don't use socket
9481032
let container = canvas.tokens.get(this.token.id)
949-
this._hackydistributeCoins(container.actor)
1033+
LootSheet5eNPCHelper.distributeCoins(container.actor)
9501034
return
9511035
}
9521036

@@ -960,99 +1044,6 @@ class LootSheet5eNPC extends dnd5e.applications.actor.ActorSheet5eNPC2 {
9601044
game.socket.emit(LootSheet5eNPC.SOCKET, packet)
9611045
}
9621046

963-
_hackydistributeCoins(containerActor) {
964-
//This is identical as the distributeCoins function defined in the init hook which for some reason can't be called from the above _distributeCoins method of the lootsheet-simple class. I couldn't be bothered to figure out why a socket can't be called as the GM... so this is a hack but it works.
965-
let actorData = containerActor.system
966-
let observers = []
967-
let players = game.users.players
968-
969-
// Calculate observers
970-
for (let player of players) {
971-
let playerPermission = LootSheet5eNPCHelper.getLootPermissionForPlayer(actorData, player)
972-
if (player != 'default' && playerPermission >= 2) {
973-
let actor = game.actors.get(player.system.character)
974-
if (actor != null && (player.system.role === 1 || player.system.role === 2))
975-
observers.push(actor)
976-
}
977-
}
978-
979-
if (observers.length === 0) return
980-
981-
// Calculate split of currency
982-
let currencySplit = foundry.utils.duplicate(
983-
LootSheet5eNPCHelper.convertCurrencyFromObject(containerActor.system.currency),
984-
)
985-
986-
// keep track of the remainder
987-
let currencyRemainder = {}
988-
989-
for (let c in currencySplit) {
990-
if (observers.length) {
991-
// calculate remainder
992-
currencyRemainder[c] = currencySplit[c] % observers.length
993-
994-
currencySplit[c] = Math.floor(currencySplit[c] / observers.length)
995-
} else currencySplit[c] = 0
996-
}
997-
998-
// add currency to actors existing coins
999-
let msg = []
1000-
for (let u of observers) {
1001-
if (u === null) continue
1002-
1003-
msg = []
1004-
let currency = LootSheet5eNPCHelper.convertCurrencyFromObject(u.system.currency),
1005-
newCurrency = foundry.utils.duplicate(
1006-
LootSheet5eNPCHelper.convertCurrencyFromObject(u.system.currency),
1007-
)
1008-
1009-
for (let c in currency) {
1010-
// add msg for chat description
1011-
if (currencySplit[c]) {
1012-
msg.push(` ${currencySplit[c]} ${c} coins`)
1013-
}
1014-
if (currencySplit[c] != null) {
1015-
// Add currency to permitted actor
1016-
newCurrency[c] = parseInt(currency[c] || 0) + currencySplit[c]
1017-
u.update({
1018-
'system.currency': newCurrency,
1019-
})
1020-
}
1021-
}
1022-
1023-
// Remove currency from loot actor.
1024-
let lootCurrency = LootSheet5eNPCHelper.convertCurrencyFromObject(
1025-
containerActor.system.currency,
1026-
),
1027-
zeroCurrency = {}
1028-
1029-
for (let c in lootCurrency) {
1030-
zeroCurrency[c] = {
1031-
type: currencySplit[c].type,
1032-
label: currencySplit[c].type,
1033-
value: currencyRemainder[c],
1034-
}
1035-
containerActor.update({
1036-
'system.currency': zeroCurrency,
1037-
})
1038-
}
1039-
1040-
// Create chat message for coins received
1041-
if (msg.length != 0) {
1042-
let message = `${u.name} receives: `
1043-
message += msg.join(',')
1044-
ChatMessage.create({
1045-
user: game.user._id,
1046-
speaker: {
1047-
actor: containerActor,
1048-
alias: containerActor.name,
1049-
},
1050-
content: message,
1051-
})
1052-
}
1053-
}
1054-
}
1055-
10561047
/* -------------------------------------------- */
10571048

10581049
/**
@@ -1682,98 +1673,6 @@ Hooks.once('init', () => {
16821673
}
16831674
}
16841675

1685-
function distributeCoins(containerActor) {
1686-
let actorData = containerActor.system
1687-
let observers = []
1688-
let players = game.users.players
1689-
1690-
// Calculate observers
1691-
for (let player of players) {
1692-
let playerPermission = LootSheet5eNPCHelper.getLootPermissionForPlayer(actorData, player)
1693-
if (player != 'default' && playerPermission >= 2) {
1694-
let actor = game.actors.get(player.system.character)
1695-
if (actor != null && (player.system.role === 1 || player.system.role === 2))
1696-
observers.push(actor)
1697-
}
1698-
}
1699-
1700-
if (observers.length === 0) return
1701-
1702-
// Calculate split of currency
1703-
let currencySplit = foundry.utils.duplicate(
1704-
LootSheet5eNPCHelper.convertCurrencyFromObject(containerActor.system.currency),
1705-
)
1706-
1707-
// keep track of the remainder
1708-
let currencyRemainder = {}
1709-
1710-
for (let c in currencySplit) {
1711-
if (observers.length) {
1712-
// calculate remainder
1713-
currencyRemainder[c] = currencySplit[c] % observers.length
1714-
1715-
currencySplit[c] = Math.floor(currencySplit[c] / observers.length)
1716-
} else currencySplit[c] = 0
1717-
}
1718-
1719-
// add currency to actors existing coins
1720-
let msg = []
1721-
for (let u of observers) {
1722-
if (u === null) continue
1723-
1724-
msg = []
1725-
let currency = LootSheet5eNPCHelper.convertCurrencyFromObject(u.system.currency),
1726-
newCurrency = foundry.utils.duplicate(
1727-
LootSheet5eNPCHelper.convertCurrencyFromObject(u.system.currency),
1728-
)
1729-
1730-
for (let c in currency) {
1731-
// add msg for chat description
1732-
if (currencySplit[c]) {
1733-
msg.push(` ${currencySplit[c]} ${c} coins`)
1734-
}
1735-
1736-
// Add currency to permitted actor
1737-
newCurrency[c] = parseInt(currency[c] || 0) + currencySplit[c]
1738-
1739-
u.update({
1740-
'system.currency': newCurrency,
1741-
})
1742-
}
1743-
1744-
// Remove currency from loot actor.
1745-
let lootCurrency = LootSheet5eNPCHelper.convertCurrencyFromObject(
1746-
containerActor.system.currency,
1747-
),
1748-
zeroCurrency = {}
1749-
1750-
for (let c in lootCurrency) {
1751-
zeroCurrency[c] = {
1752-
type: currencySplit[c].type,
1753-
label: currencySplit[c].type,
1754-
value: currencyRemainder[c],
1755-
}
1756-
containerActor.update({
1757-
'system.currency': zeroCurrency,
1758-
})
1759-
}
1760-
1761-
// Create chat message for coins received
1762-
if (msg.length != 0) {
1763-
let message = `${u.name} receives: `
1764-
message += msg.join(',')
1765-
ChatMessage.create({
1766-
user: game.user._id,
1767-
speaker: {
1768-
actor: containerActor,
1769-
alias: containerActor.name,
1770-
},
1771-
content: message,
1772-
})
1773-
}
1774-
}
1775-
}
1776-
17771676
function lootCoins(containerActor, looter) {
17781677
let sheetCurrency = LootSheet5eNPCHelper.convertCurrencyFromObject(
17791678
containerActor.system.currency,
@@ -1872,7 +1771,7 @@ Hooks.once('init', () => {
18721771
'Player attempted to distribute coins on a different scene.',
18731772
)
18741773
}
1875-
distributeCoins(container.actor)
1774+
LootSheet5eNPCHelper.distributeCoins(container.actor)
18761775
}
18771776

18781777
if (data.type === 'lootCoins') {

template/npc-sheet.hbs

+19-10
Original file line numberDiff line numberDiff line change
@@ -294,16 +294,17 @@
294294
>
295295
<dnd5e-inventory class="inventory-element" v2="">
296296
<section class="currency {{@root.editable}}">
297-
<button
298-
type="button"
299-
class="item-action unbutton"
300-
data-action="currency"
301-
data-tooltip="DND5E.CurrencyManager.Title"
302-
aria-label="Manage Currency"
303-
>
304-
<i class="fas fa-coins"></i>
305-
</button>
306-
297+
{{#if @root.owner}}
298+
<button
299+
type="button"
300+
class="item-action unbutton"
301+
data-action="currency"
302+
data-tooltip="DND5E.CurrencyManager.Title"
303+
aria-label="Manage Currency"
304+
>
305+
<i class="fas fa-coins"></i>
306+
</button>
307+
{{/if}}
307308
{{#each system.currency}}
308309
<label aria-label="{{ lookup (lookup @root.config.currencies @key) 'label' }}">
309310
<i
@@ -321,6 +322,14 @@
321322
/>
322323
</label>
323324
{{/each}} {{#ifeq lootsheettype "Loot"}} {{#if lootCurrency}}
325+
<button
326+
type="button"
327+
class="item-action unbutton split-coins"
328+
data-tooltip="Split Coins"
329+
aria-label="Split Coins"
330+
>
331+
<i class="fas fa-coins"></i>
332+
</button>
324333
<button
325334
type="button"
326335
class="item-action unbutton currency-loot"

0 commit comments

Comments
 (0)