Skip to content

Commit

Permalink
Localization Hotfix, scenes and actor loot handling, API update
Browse files Browse the repository at this point in the history
* Hotfix localization for spell scrolls.
* convert Scenes and Actors instead of silently failing
* addLootToSelectedToken() to public API
  • Loading branch information
DanielBoettner authored Jan 2, 2022
2 parents a1fc4b5 + 707ddc8 commit 7e5d44f
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 30 deletions.
2 changes: 1 addition & 1 deletion module.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "better-rolltables",
"title": "Better Roll Tables",
"description": "Adding functionality to roll tables, especially to roll treasure and magic items",
"version": "1.8.93",
"version": "1.8.94",
"manifestPlusVersion": "1.2.0",
"authors": [
{
Expand Down
39 changes: 39 additions & 0 deletions scripts/API.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,45 @@ class API {
return game.settings.get(MODULE.ns, BRTCONFIG.TAGS.USE);
}

/**
* Roll a table an add the resulting loot to a given token.
*
* @param {RollTable} tableEntity
* @param {TokenDocument} token
* @param {options} object
* @returns
*/
async addLootToSelectedToken(tableEntity, token = null, options = null) {
let tokenstack = [];
const isTokenActor = (options && options?.isTokenActor),
stackSame = (options && options?.stackSame) ? options.stackSame : true,
customRoll = (options && options?.customRole) ? options.customRole : undefined,
itemLimit = (options && options?.itemLimit) ? Number(options.itemLimit) : 0;

if (null == token && (canvas.tokens.controlled.length === 0)) {
return ui.notifications.error('Please select a token first');
} else {
tokenstack = (token) ? (token.length >= 0) ? token : [token] : canvas.tokens.controlled;
}

ui.notifications.info(MODULE.ns + ' | API | Loot generation started.');

const brtBuilder = new BRTBuilder(tableEntity);

for (const token of tokenstack) {
const results = await brtBuilder.betterRoll(customRoll);
const br = new BetterResults(results);
const betterResults = await br.buildResults(tableEntity);
const currencyData = br.getCurrencyData();
const lootCreator = new LootCreator(betterResults, currencyData);

await lootCreator.addCurrenciesToToken(token, isTokenActor);
await lootCreator.addItemsToToken(token, stackSame, isTokenActor, itemLimit);
}

return ui.notifications.info(MODULE.ns + ' | API | Loot generation complete.');
}

/**
*
* @param {*} tableEntity
Expand Down
18 changes: 9 additions & 9 deletions scripts/better-tables.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ export class BetterTables {

if (game.settings.get(MODULE.ns, BRTCONFIG.SHOW_REROLL_BUTTONS)) {
// reroll button
const rerollButton = $(`<a class="roll-table-reroll-button" title="${game.i18n('BRT.DrawReroll')}">`).append("<i class='fas fa-dice-d20'></i>")
const rerollButton = $(`<a class="roll-table-reroll-button" title="${game.i18n.localize('BRT.DrawReroll')}">`).append("<i class='fas fa-dice-d20'></i>")
rerollButton.click(async () => {
let cardContent
if (pack && !id) {
Expand All @@ -358,7 +358,7 @@ export class BetterTables {
&& game.settings.get(MODULE.ns, BRTCONFIG.SHOW_CURRENCY_SHARE_BUTTON)
&& (message.data.flags?.betterTables?.loot.currency && Object.keys(message.data.flags.betterTables.loot.currency).length > 0)) {
// Currency share button
const currencyShareButton = $(`<a class="roll-table-share-currencies" title="${game.i18n('BRT.Currency.Buttons.Share.Label')}">`).append("<i class='fas fa-coins'></i>")
const currencyShareButton = $(`<a class="roll-table-share-currencies" title="${game.i18n.localize('BRT.Currency.Buttons.Share.Label')}">`).append("<i class='fas fa-coins'></i>")
currencyShareButton.click(async () => BetterTables._toggleCurrenciesShareSection(message, html))
$(html).find('.message-delete').before(currencyShareButton)
const shareButton = html[0].querySelector("button.brt-share-currencies-button")
Expand All @@ -376,7 +376,7 @@ export class BetterTables {
document = game.tables.get(id)
}
if (document) {
const openLink = $(`<a class="roll-table-open-table" title="${game.i18n('BRT.OpenRolltable')}">`).append("<i class='fas fa-th-list'></i>")
const openLink = $(`<a class="roll-table-open-table" title="${game.i18n.localize('BRT.OpenRolltable')}">`).append("<i class='fas fa-th-list'></i>")
if (id) openLink.data('id', id)
if (pack) openLink.data('pack', pack)
openLink.click(async () => document.sheet.render(true))
Expand Down Expand Up @@ -426,7 +426,7 @@ export class BetterTables {
const id = $(link).data('id')
const rolltable = game.tables.get(id)

const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n.localize('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
.click(async () => {
await game.betterTables.generateChatLoot(rolltable)
})
Expand All @@ -443,7 +443,7 @@ export class BetterTables {
const document = await pack.getDocument(id)
if (!document || document.documentName !== 'RollTable') return

const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n.localize('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
.click(async () => {
await game.betterTables.generateChatLoot(document)
})
Expand Down Expand Up @@ -476,8 +476,8 @@ export class BetterTables {
if (game.user.isGM) {
if (!options.force && game.settings.get(MODULE.ns, BRTCONFIG.SHOW_WARNING_BEFORE_REROLL)) {
Dialog.confirm({
title: game.i18n('BRT.Settings.RerollWarning.Title'),
content: game.i18n('BRT.Settings.RerollWarning.Description'),
title: game.i18n.localize('BRT.Settings.RerollWarning.Title'),
content: game.i18n.localize('BRT.Settings.RerollWarning.Description'),
yes: () => BetterTables.updateChatMessage(message, content, { 'force': true }),
defaultYes: false
})
Expand All @@ -498,7 +498,7 @@ export class BetterTables {
const id = $(link).data('id')
const rolltable = game.tables.get(id)

const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n.localize('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
.click(async () => {
await game.betterTables.generateChatLoot(rolltable)
})
Expand All @@ -515,7 +515,7 @@ export class BetterTables {
const document = await pack.getDocument(id)
if (!document || document.documentName !== 'RollTable') return

const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
const rollNode = $(`<a class="roll-table-roll-link" title="${game.i18n.localize('BRT.DrawReroll')}"><i class="fas fa-dice-d20"></i></a>`)
.click(async () => {
await game.betterTables.generateChatLoot(document)
})
Expand Down
64 changes: 45 additions & 19 deletions scripts/loot/loot-creator.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ export class LootCreator {
}

/**
*
*
* @param {boolean} stackSame Should same items be stacked together? Default = true
* @returns
* @returns
*/
async addItemsToActor (stackSame = true) {
const items = [];
Expand All @@ -73,7 +73,7 @@ export class LootCreator {
itemPrice = getProperty(newItemData, BRTCONFIG.PRICE_PROPERTY_PATH) || 0,
embeddedItems = [...actor.getEmbeddedCollection('Item').values()],
originalItem = embeddedItems.find(i => i.name === newItemData.name && itemPrice === getProperty(i.data, BRTCONFIG.PRICE_PROPERTY_PATH));

/** if the item is already owned by the actor (same name and same PRICE) */
if (originalItem && stackSame) {
/** add quantity to existing item */
Expand All @@ -84,7 +84,7 @@ export class LootCreator {

if (newQty != newItemQty){
setProperty(updateItem, BRTCONFIG.QUANTITY_PROPERTY_PATH, newQty);
await actor.updateEmbeddedDocuments('Item', [updateItem]);
await actor.updateEmbeddedDocuments('Item', [updateItem]);
}
return actor.items.get(originalItem.id);
} else {
Expand All @@ -94,15 +94,15 @@ export class LootCreator {
}

/**
*
*
* @param {number} currentQty Quantity of item we want to add
* @param {number} originalQty Quantity of the originalItem already in posession
* @param {number} customLimit A custom Limit
* @returns
* @param {number} customLimit A custom Limit
* @returns
*/
_handleLimitedQuantity(currentQty, originalQty, customLimit = 0){
const newQty = Number(originalQty) + Number(currentQty);

if (customLimit > 0 ){
// limit is bigger or equal to newQty
if(Number(customLimit) >= Number(newQty)){
Expand All @@ -122,25 +122,45 @@ export class LootCreator {
* @returns
*/
async buildItemData (item) {
let itemData;

let itemData = {},
existingItem = false;
/** Try first to load item from compendium */
if (item.collection) {
itemData = await getItemFromCompendium(item);
existingItem = await getItemFromCompendium(item);
}

/** Try first to load item from item list */
if (!itemData) {
if (!existingItem) {
/** if an item with this name exist we load that item data, otherwise we create a new one */
const itemEntity = game.items.getName(item.text);
if (itemEntity) {
itemData = duplicate(itemEntity.data);
existingItem = game.items.getName(item.text);
if (existingItem) {
itemData = duplicate(existingItem.data);
}
}

const itemConversions = {
Actor: {
text: `${item.text} Portrait`,
img: existingItem?.img || "icons/svg/mystery-man.svg"
},
Scene: {
text: 'Map of '+ existingItem?.data?.name,
img: existingItem?.data?.thumb || "icons/svg/direction.svg",
price: new Roll('1d20 + 10').roll().total || 1
}
};

const convert = itemConversions[existingItem.entity] ?? false;
/** Create item from text since the item does not exist */
if (!itemData) {
itemData = { name: item.text, type: BRTCONFIG.ITEM_LOOT_TYPE, img: item.img }; // "icons/svg/mystery-man.svg"
const createNewItem = !itemData || convert;

if (createNewItem) {
const name = convert?.text || item.text,
type = BRTCONFIG.ITEM_LOOT_TYPE,
img = convert?.img || item.img,
price = convert?.price || item.price || 0;

itemData = { name: name, type, img: img, data: { price: price }}; // "icons/svg/mystery-man.svg"
}

if (Object.getOwnPropertyDescriptor(item, 'commands') && item.commands) {
Expand Down Expand Up @@ -174,7 +194,7 @@ export class LootCreator {

/**
*
* @param {Token} token
* @param {Token|Actor} token
* @param {Boolean} is the token passed as the token actor instead?
*/
async addCurrenciesToToken (token, isTokenActor = false) {
Expand All @@ -194,7 +214,13 @@ export class LootCreator {
const amount = Number(currencyData[key] || 0) + Number(lootCurrency[key] || 0);
currencyData[key] = amount;
}
await token.update({ 'actorData.data.currency': currencyData });

if(isTokenActor) {
// @type {Actor}
return await token.update({'actorData.data.currency': currencyData});
} else {
return await token.actor.update({'data.currency': currencyData});
}
}

/**
Expand Down
3 changes: 2 additions & 1 deletion templates/welcome-screen.html
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,9 @@ <h3>Authors / Maintainers / Contributers</h3>
<label for="welcome-screen-show-again">Don't show this screen again until next update.</label> <input type="checkbox" class='show-again' id="welcome-screen-show-again" {{checked isChecked}} />
</div>
<h1>Patchnotes</h1>
<h2 id="v190">v1.9.0 <small>(& v1.8.92)</small></h2>
<h2 id="v1894">v1.8.9.4 <small>(& v1.8.92/3)</small></h2>
<ul>
<li>Fixed a bug in the localization on spell scrolls</li>
<li>Fixed a <a href="https://github.com/ultrakorne/better-rolltables/issues/158">bug</a> that made the module unusable when the spellCompendium was not found.</li>
<li>Added general <a href="https://foundryvtt.com/packages/pf1">Pathfinder 1e</a> support.
Thanks to <a href="https://github.com/mkahvi">Mana</a> for the quick help.</li>
Expand Down
1 change: 1 addition & 0 deletions wiki
Submodule wiki added at 186594

0 comments on commit 7e5d44f

Please sign in to comment.