From 8a9be762091e74ec511816f970b91e9b797bdce4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20B=C3=B6ttner?= Date: Fri, 18 Jun 2021 10:59:58 +0200 Subject: [PATCH] Indentation of code and bugfix Last changes where bug ridden, sorry for anyone encountering these releases. This corrects the remaining errors after restructuring the code and corrects indentation --- scripts/populateLoot.js | 512 ++++++++++++++++++++-------------------- 1 file changed, 256 insertions(+), 256 deletions(-) diff --git a/scripts/populateLoot.js b/scripts/populateLoot.js index 25af584..7f87827 100644 --- a/scripts/populateLoot.js +++ b/scripts/populateLoot.js @@ -3,275 +3,275 @@ import Item5e from "../../../systems/dnd5e/module/item/entity.js"; export class LootPopulator { constructor() { this.moduleNamespace = "lootpopulatornpc5e"; - return this; - } - + return this; + } async generateLoot(token) { - //instead of the main actor we want/need the actor of the token. - const tokenId = token.id; - const actor = token.actor; - - const ls5e_moduleNamespace = "lootsheetnpc5e"; - const rolltableName = actor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("fallbackRolltable"); - const shopQtyFormula = actor.getFlag(ls5e_moduleNamespace, "shopQty") || this._getSetting("fallbackShopQty") || "1"; - const itemQtyFormula = actor.getFlag(ls5e_moduleNamespace, "itemQty") || this._getSetting("fallbackItemQty") || "1"; - const itemQtyLimit = actor.getFlag(ls5e_moduleNamespace, "itemQtyLimit") || this._getSetting("fallbackItemQtyLimit") || "0"; - const itemOnlyOnce = actor.getFlag(ls5e_moduleNamespace, "itemOnlyOnce") || false; - const reducedVerbosity = this._getSetting("reduceUpdateVerbosity") || true; - let shopQtyRoll = new Roll(shopQtyFormula); - - shopQtyRoll.roll(); - - if (!rolltableName) { - return; - } - - let rolltable = game.tables.getName(rolltableName); - - if (!rolltable) { - return ui.notifications.error(this.moduleNamespace + `: No Rollable Table found with name "${rolltableName}".`); - } - - - - if (itemOnlyOnce) { - if (rolltable.results.length < shopQtyRoll.total) { - return ui.notifications.error(this.moduleNamespace + `: Cannot create a loot with ${shopQtyRoll.total} unqiue entries if the rolltable only contains ${rolltable.results.length} items`); - } - } - - if (!itemOnlyOnce) { - for (let i = 0; i < shopQtyRoll.total; i++) { - const rollResult = await rolltable.roll(); - let newItem = null; - - - - if (rollResult.results[0].collection === "Item") { - newItem = game.items.get(rollResult.results[0].data.resultId); - } else { - const items = game.packs.get(rollResult.results[0].data.collection); - newItem = await items.getDocument(rollResult.results[0].data.resultId); - } - - newItem = this._rollSubTables(newItem); - - if (!newItem || newItem === null) { - return; - } - - if (newItem.type === "spell") { - newItem = await Item5e.createScrollFromSpell(newItem) - } - - let itemQtyRoll = new Roll(itemQtyFormula); - itemQtyRoll.roll(); - - console.log(this.moduleNamespace + `: Adding ${itemQtyRoll.total} x ${newItem.name}`) - - let existingItem = actor.items.find(item => item.data.name == newItem.name); - - if (existingItem === undefined) { - await actor.createEmbeddedDocuments("Item", [newItem.toObject()]); - console.log(this.moduleNamespace + `: ${newItem.name} does not exist.`); - existingItem = await actor.items.find(item => item.data.name == newItem.name); - - if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(itemQtyRoll.total)) { - await existingItem.update({ "data.quantity": itemQtyLimit }); - if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyLimit} x ${newItem.name}.`); - } else { - await existingItem.update({ "data.quantity": itemQtyRoll.total }); - if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); - } - } else { - console.log(this.moduleNamespace + `: Item ${newItem.name} exists.`); - - let newQty = Number(existingItem.data.data.quantity) + Number(itemQtyRoll.total); - - if (itemQtyLimit > 0 && Number(itemQtyLimit) === Number(existingItem.data.data.quantity)) { - if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: ${newItem.name} already at maximum quantity (${itemQtyLimit}).`); - } - else if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(newQty)) { - //console.log("Exceeds existing quantity, limiting"); - await existingItem.update({ "data.quantity": itemQtyLimit }); - - if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added additional quantity to ${newItem.name} to the specified maximum of ${itemQtyLimit}.`); - } else { - await existingItem.update({ "data.quantity": newQty }); - if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added additional ${itemQtyRoll.total} quantity to ${newItem.name}.`); - } - } - } - } else { - // Get a list which contains indexes of all possible results - - const rolltableIndexes = [] - - // Add one entry for each weight an item has - for (let index in [...Array(rolltable.results.length).keys()]) { - let numberOfEntries = rolltable.data.results[index].weight - for (let i = 0; i < numberOfEntries; i++) { - rolltableIndexes.push(index); - } - } - - // Shuffle the list of indexes - var currentIndex = rolltableIndexes.length, temporaryValue, randomIndex; - - // While there remain elements to shuffle... - while (0 !== currentIndex) { - - // Pick a remaining element... - randomIndex = Math.floor(Math.random() * currentIndex); - currentIndex -= 1; - - // And swap it with the current element. - temporaryValue = rolltableIndexes[currentIndex]; - rolltableIndexes[currentIndex] = rolltableIndexes[randomIndex]; - rolltableIndexes[randomIndex] = temporaryValue; - } - - // console.log(`Rollables: ${rolltableIndexes}`) - - let indexesToUse = []; - let numberOfAdditionalItems = 0; - // Get the first N entries from our shuffled list. Those are the indexes of the items in the roll table we want to add - // But because we added multiple entries per index to account for weighting, we need to increase our list length until we got enough unique items - while (true) - { - let usedEntries = rolltableIndexes.slice(0, shopQtyRoll.total + numberOfAdditionalItems); - // console.log(`Distinct: ${usedEntries}`); - let distinctEntris = [...new Set(usedEntries)]; - - if (distinctEntris.length < shopQtyRoll.total) { - numberOfAdditionalItems++; - // console.log(`numberOfAdditionalItems: ${numberOfAdditionalItems}`); - continue; - } - - indexesToUse = distinctEntris - // console.log(`indexesToUse: ${indexesToUse}`) - break; - } - - for (const index of indexesToUse) - { - let itemQtyRoll = new Roll(itemQtyFormula); - itemQtyRoll.roll(); - - let newItem = null - - if (rolltable.results[index].collection === "Item") { - newItem = game.items.get(rolltable.results[index].resultId); - } else { - //Try to find it in the compendium - const items = game.packs.get(rolltable.results[index].data.collection); - newItem = await items.getDocument(rollResult.results[0].data.resultId); - } - - newItem = this._rollSubTables(newItem,index); - - if (!newItem || newItem === null) { - return ui.notifications.error(this.moduleNamespace + `: No item found "${rolltable.results[index].resultId}".`); - } - - if (newItem.type === "spell") { - newItem = await Item5e.createScrollFromSpell(newItem) - } - - await item.createEmbeddedDocuments("Item", [newItem.toObject()]); - let existingItem = actor.items.find(item => item.data.name == newItem.name); - - if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(itemQtyRoll.total)) { - await existingItem.update({ "data.quantity": itemQtyLimit }); - if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyLimit} x ${newItem.name}.`); - } else { - await existingItem.update({ "data.quantity": itemQtyRoll.total }); - if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); - } - } - } - - if (this._getSetting('generateCurrency') && this._getSetting('lootCurrencyDefault')){ - let lootCurrencyString = this._getSetting('lootCurrencyDefault'); - - if (this._getSetting('useBetterRolltables')){ - lootCurrencyString = rolltable.getFlag('better-rolltables','table-currency-string') || lootCurrencyString; + //instead of the main actor we want/need the actor of the token. + const tokenId = token.id; + const actor = token.actor; + const ls5e_moduleNamespace = "lootsheetnpc5e"; + const rolltableName = actor.getFlag(ls5e_moduleNamespace, "rolltable") || this._getSetting("fallbackRolltable"); + const shopQtyFormula = actor.getFlag(ls5e_moduleNamespace, "shopQty") || this._getSetting("fallbackShopQty") || "1"; + const itemQtyFormula = actor.getFlag(ls5e_moduleNamespace, "itemQty") || this._getSetting("fallbackItemQty") || "1"; + const itemQtyLimit = actor.getFlag(ls5e_moduleNamespace, "itemQtyLimit") || this._getSetting("fallbackItemQtyLimit") || "0"; + const itemOnlyOnce = actor.getFlag(ls5e_moduleNamespace, "itemOnlyOnce") || false; + const reducedVerbosity = this._getSetting("reduceUpdateVerbosity") || true; + let shopQtyRoll = new Roll(shopQtyFormula); + + shopQtyRoll.roll(); + + if (!rolltableName) { + return; + } + + let rolltable = game.tables.getName(rolltableName); + + if (!rolltable) { + return ui.notifications.error(this.moduleNamespace + `: No Rollable Table found with name "${rolltableName}".`); + } + + if (itemOnlyOnce) { + if (rolltable.results.length < shopQtyRoll.total) { + return ui.notifications.error(this.moduleNamespace + `: Cannot create a loot with ${shopQtyRoll.total} unqiue entries if the rolltable only contains ${rolltable.results.length} items`); + } + } + + if (!itemOnlyOnce) { + for (let i = 0; i < shopQtyRoll.total; i++) { + const rollResult = await rolltable.roll(); + let newItem = null; + + if (rollResult.results[0].collection === "Item") { + newItem = game.items.get(rollResult.results[0].data.resultId); + } else { + const items = game.packs.get(rollResult.results[0].data.collection); + newItem = await items.getDocument(rollResult.results[0].data.resultId); + } + + newItem = this._rollSubTables(newItem); + + if (!newItem || newItem === null) { + return; + } + + if (newItem.type === "spell") { + newItem = await Item5e.createScrollFromSpell(newItem) + } + + let itemQtyRoll = new Roll(itemQtyFormula); + itemQtyRoll.roll(); + + console.log(this.moduleNamespace + `: Adding ${itemQtyRoll.total} x ${newItem.name}`) + + let existingItem = actor.items.find(item => item.data.name == newItem.name); + + if (existingItem === undefined) { + await actor.createEmbeddedDocuments("Item", [newItem.toObject()]); + console.log(this.moduleNamespace + `: ${newItem.name} does not exist.`); + existingItem = await actor.items.find(item => item.data.name == newItem.name); + + if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(itemQtyRoll.total)) { + await existingItem.update({ "data.quantity": itemQtyLimit }); + if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyLimit} x ${newItem.name}.`); + } else { + await existingItem.update({ "data.quantity": itemQtyRoll.total }); + if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); + } + } else { + console.log(this.moduleNamespace + `: Item ${newItem.name} exists.`); + + let newQty = Number(existingItem.data.data.quantity) + Number(itemQtyRoll.total); + + if (itemQtyLimit > 0 && Number(itemQtyLimit) === Number(existingItem.data.data.quantity)) { + if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: ${newItem.name} already at maximum quantity (${itemQtyLimit}).`); + } + else if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(newQty)) { + //console.log("Exceeds existing quantity, limiting"); + await existingItem.update({ "data.quantity": itemQtyLimit }); + + if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added additional quantity to ${newItem.name} to the specified maximum of ${itemQtyLimit}.`); + } else { + await existingItem.update({ "data.quantity": newQty }); + if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added additional ${itemQtyRoll.total} quantity to ${newItem.name}.`); } - - await this.addCurrenciesToActor(actor, this._generateCurrency(lootCurrencyString)); } - } - - async addCurrenciesToActor(actor, lootCurrency) { - let currencyData = duplicate(actor.data.data.currency), - cr = actor.data.data.details.cr || 0, - amount = 0; - - for (var key in lootCurrency) { - if (currencyData.hasOwnProperty(key)) { - if(this._getSetting('adjustCurrencyWithCR')){ - amount = Number(currencyData[key].value || 0) + Math.ceil(cr) + Number(lootCurrency[key]); - } else { - amount = Number(currencyData[key].value || 0) + Number(lootCurrency[key]); - } - - currencyData[key] = {"value": amount.toString()}; + } + } else { + // Get a list which contains indexes of all possible results + + const rolltableIndexes = [] + + // Add one entry for each weight an item has + for (let index in [...Array(rolltable.results.length).keys()]) { + let numberOfEntries = rolltable.data.results[index].weight + for (let i = 0; i < numberOfEntries; i++) { + rolltableIndexes.push(index); } } - - await actor.update({"data.currency": currencyData}); - } - - _generateCurrency(currencyString) { - const currenciesToAdd = {}; - if (currencyString) { - const currenciesPieces = currencyString.split(","); - for (const currency of currenciesPieces) { - const match = /(.*)\[(.*?)\]/g.exec(currency); //capturing 2 groups, the formula and then the currency symbol in brakets [] - if (!match || match.length < 3) { - ui.notifications.warn(this.moduleNamespace + `: Currency loot field contain wrong formatting, currencies need to be define as "diceFormula[currencyType]" => "1d100[gp]" but was ${currency}`); - continue; - } - const rollFormula = match[1]; - const currencyString = match[2]; - const amount = this._tryRoll(rollFormula); - - if (!this._getSetting("reduceUpdateVerbosity")) ui.notifications.info(this.moduleNamespace + `: Adding `+amount+currencyString+` to the actor.`); - currenciesToAdd[currencyString] = (currenciesToAdd[currencyString] || 0) + amount; - } + + // Shuffle the list of indexes + var currentIndex = rolltableIndexes.length, temporaryValue, randomIndex; + + // While there remain elements to shuffle... + while (0 !== currentIndex) { + + // Pick a remaining element... + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex -= 1; + + // And swap it with the current element. + temporaryValue = rolltableIndexes[currentIndex]; + rolltableIndexes[currentIndex] = rolltableIndexes[randomIndex]; + rolltableIndexes[randomIndex] = temporaryValue; + } + + // console.log(`Rollables: ${rolltableIndexes}`) + + let indexesToUse = []; + let numberOfAdditionalItems = 0; + // Get the first N entries from our shuffled list. Those are the indexes of the items in the roll table we want to add + // But because we added multiple entries per index to account for weighting, we need to increase our list length until we got enough unique items + while (true) + { + let usedEntries = rolltableIndexes.slice(0, shopQtyRoll.total + numberOfAdditionalItems); + // console.log(`Distinct: ${usedEntries}`); + let distinctEntris = [...new Set(usedEntries)]; + + if (distinctEntris.length < shopQtyRoll.total) { + numberOfAdditionalItems++; + // console.log(`numberOfAdditionalItems: ${numberOfAdditionalItems}`); + continue; + } + + indexesToUse = distinctEntris + // console.log(`indexesToUse: ${indexesToUse}`) + break; + } + + for (const index of indexesToUse) + { + let itemQtyRoll = new Roll(itemQtyFormula); + itemQtyRoll.roll(); + + let newItem = null + + if (rolltable.results[index].collection === "Item") { + newItem = game.items.get(rolltable.results[index].resultId); + } else { + //Try to find it in the compendium + const items = game.packs.get(rolltable.results[index].data.collection); + newItem = await items.getDocument(rollResult.results[0].data.resultId); + } + + newItem = this._rollSubTables(newItem,index); + + if (!newItem || newItem === null) { + return ui.notifications.error(this.moduleNamespace + `: No item found "${rolltable.results[index].resultId}".`); + } + + if (newItem.type === "spell") { + newItem = await Item5e.createScrollFromSpell(newItem) + } + + await item.createEmbeddedDocuments("Item", [newItem.toObject()]); + let existingItem = actor.items.find(item => item.data.name == newItem.name); + + if (itemQtyLimit > 0 && Number(itemQtyLimit) < Number(itemQtyRoll.total)) { + await existingItem.update({ "data.quantity": itemQtyLimit }); + if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyLimit} x ${newItem.name}.`); + } else { + await existingItem.update({ "data.quantity": itemQtyRoll.total }); + if (!reducedVerbosity) ui.notifications.info(this.moduleNamespace + `: Added new ${itemQtyRoll.total} x ${newItem.name}.`); + } } - return currenciesToAdd; } - - _tryRoll(rollFormula){ - try { - return new Roll(rollFormula).roll().total || 1; - } catch (error) { - return 1; + + if (this._getSetting('generateCurrency') && this._getSetting('lootCurrencyDefault')){ + let lootCurrencyString = this._getSetting('lootCurrencyDefault'); + + if (this._getSetting('useBetterRolltables')){ + lootCurrencyString = rolltable.getFlag('better-rolltables','table-currency-string') || lootCurrencyString; } + + await this.addCurrenciesToActor(actor, this._generateCurrency(lootCurrencyString)); } - - async _rollSubTables(item, index = 0){ - if (item instanceof RollTable){ - let subTableResults = await item.roll(); - - if(subTableResults.results[index].data.collection === "Item"){ - item = game.items.get(subTableResults.results[index].data.resultId); + } + + async addCurrenciesToActor(actor, lootCurrency) { + let currencyData = duplicate(actor.data.data.currency), + cr = actor.data.data.details.cr || 0, + amount = 0; + + for (var key in lootCurrency) { + if (currencyData.hasOwnProperty(key)) { + if(this._getSetting('adjustCurrencyWithCR')){ + amount = Number(currencyData[key].value || 0) + Math.ceil(cr) + Number(lootCurrency[key]); } else { - let itemCollection = game.packs.get(subTableResults.results[index].data.collection); - item = await itemCollection.getDocument(subTableResults.results[index].data.resultId); + amount = Number(currencyData[key].value || 0) + Number(lootCurrency[key]); } - - if (item instanceof RollTable){ - item = await _rollSubTables(item,index); + + currencyData[key] = {"value": amount.toString()}; + } + } + + await actor.update({"data.currency": currencyData}); + + } + + _generateCurrency(currencyString) { + const currenciesToAdd = {}; + + if (currencyString) { + const currenciesPieces = currencyString.split(","); + + for (const currency of currenciesPieces) { + const match = /(.*)\[(.*?)\]/g.exec(currency); //capturing 2 groups, the formula and then the currency symbol in brakets [] + + if (!match || match.length < 3) { + ui.notifications.warn(this.moduleNamespace + `: Currency loot field contain wrong formatting, currencies need to be define as "diceFormula[currencyType]" => "1d100[gp]" but was ${currency}`); + continue; } + + const rollFormula = match[1]; + const currencyString = match[2]; + const amount = this._tryRoll(rollFormula); + + if (!this._getSetting("reduceUpdateVerbosity")) ui.notifications.info(this.moduleNamespace + `: Adding `+amount+currencyString+` to the actor.`); + currenciesToAdd[currencyString] = (currenciesToAdd[currencyString] || 0) + amount; } - - return item; } - - _getSetting(setting){ - return game.settings.get(this.moduleNamespace,setting); + + return currenciesToAdd; + } + + _tryRoll(rollFormula){ + try { + return new Roll(rollFormula).roll().total || 1; + } catch (error) { + return 1; + } + } + + async _rollSubTables(item, index = 0){ + if (item instanceof RollTable){ + let subTableResults = await item.roll(); + + if(subTableResults.results[index].data.collection === "Item"){ + item = game.items.get(subTableResults.results[index].data.resultId); + } else { + let itemCollection = game.packs.get(subTableResults.results[index].data.collection); + item = await itemCollection.getDocument(subTableResults.results[index].data.resultId); + } + + if (item instanceof RollTable){ + item = await this._rollSubTables(item,index); + } } + return item; + + } + + _getSetting(setting){ + return game.settings.get(this.moduleNamespace,setting); + } }