964
edits
(Add a manual exception to getSkillcapeTable to support the HP skillcapes being silly) |
No edit summary |
||
(15 intermediate revisions by 4 users not shown) | |||
Line 4: | Line 4: | ||
local Constants = require('Module:Constants') | local Constants = require('Module:Constants') | ||
local GameData = require('Module:GameData') | local GameData = require('Module:GameData') | ||
local Common = require('Module:Common') | |||
local Items = require('Module:Items') | local Items = require('Module:Items') | ||
local Icons = require('Module:Icons') | local Icons = require('Module:Icons') | ||
local Pets = require('Module:Pets') | local Pets = require('Module:Pets') | ||
function p.getPurchase(purchaseName) | function p.getPurchase(purchaseName) | ||
local purchList = p.getPurchases(function(purch) return Common.getPurchaseName(purch) == purchaseName end) | |||
if purchList ~= nil and not Shared.tableIsEmpty(purchList) then | |||
return purchList[1] | |||
end | |||
end | end | ||
Line 35: | Line 19: | ||
return GameData.getEntityByID('shopPurchases', id) | return GameData.getEntityByID('shopPurchases', id) | ||
end | end | ||
-- Accepts a function(purchase, name) and a category. | |||
-- Prevents external modules from having to make GameData and Common calls. | |||
function p.getCategoryPurchases(checkFunc, category) | |||
local shopCat = GameData.getEntityByName('shopCategories', category) | |||
if shopCat == nil then | |||
return Shared.printError('Invalid category ' .. shopCat) | |||
end | |||
-- We make a nested func to resolve the item name first, if required. | |||
local func = | |||
function(purchase) | |||
if purchase.category ~= shopCat.id then | |||
return false | |||
end | |||
local name = Common.getPurchaseName(purchase) | |||
return checkFunc(purchase, name) | |||
end | |||
return GameData.getEntities('shopPurchases', func) | |||
end | |||
function p.getPurchases(checkFunc) | function p.getPurchases(checkFunc) | ||
return GameData.getEntities('shopPurchases', checkFunc) | |||
end | end | ||
Line 45: | Line 52: | ||
return p.getCostString(purchase.cost, displayInline) | return p.getCostString(purchase.cost, displayInline) | ||
elseif stat == 'requirements' then | elseif stat == 'requirements' then | ||
return | return Common.getRequirementString(purchase.purchaseRequirements, 'None') | ||
elseif stat == 'contents' then | elseif stat == 'contents' then | ||
return p._getPurchaseContents(purchase, true) | return p._getPurchaseContents(purchase, true) | ||
elseif stat == 'type' then | elseif stat == 'type' then | ||
return | return Common.getPurchaseType(purchase) | ||
elseif stat == 'buyLimit' then | elseif stat == 'buyLimit' then | ||
return p._getPurchaseBuyLimit(purchase, not displayInline) | return p._getPurchaseBuyLimit(purchase, not displayInline) | ||
Line 71: | Line 78: | ||
local purchaseList = {} | local purchaseList = {} | ||
if statName == 'cost' then | if statName == 'cost' then | ||
purchaseList = p.getPurchases(function(purch) return | purchaseList = p.getPurchases(function(purch) return Common.getPurchaseName(purch) == purchaseName end) | ||
else | else | ||
purchaseList = {p.getPurchase(purchaseName)} | purchaseList = {p.getPurchase(purchaseName)} | ||
Line 85: | Line 92: | ||
return table.concat(resultPart, ' or ') | return table.concat(resultPart, ' or ') | ||
end | end | ||
end | end | ||
function p._getPurchaseExpansionIcon(purch) | function p._getPurchaseExpansionIcon(purch) | ||
if purch.id ~= nil then | |||
return Icons.getExpansionIcon(purch.id) | |||
elseif purch.contains ~= nil then | |||
local item = nil | |||
if purch.contains.items ~= nil and not Shared.tableIsEmpty(purch.contains.items) then | |||
return Icons.getExpansionIcon(purch.contains.items[1].id) | |||
elseif purch.contains.itemCharges ~= nil and not Shared.tableIsEmpty(purch.contains.itemCharges) then | |||
return Icons.getExpansionIcon(purch.contains.itemCharges.id) | |||
end | |||
if purch.contains.petID ~= nil then | |||
return Icons.getExpansionIcon(purch.contains.petID) | return Icons.getExpansionIcon(purch.contains.petID) | ||
end | |||
end | |||
return '' | |||
end | end | ||
Line 137: | Line 121: | ||
return Constants.getModifiersText(purch.contains.modifiers, false) | return Constants.getModifiersText(purch.contains.modifiers, false) | ||
elseif purch.contains.petID ~= nil then | elseif purch.contains.petID ~= nil then | ||
local pet = Pets.getPetByID(purch.contains.petID) | |||
return Pets._getPetEffect(pet) | |||
elseif purch.contains.items ~= nil and Shared.tableCount(purch.contains.items) == 1 then | elseif purch.contains.items ~= nil and Shared.tableCount(purch.contains.items) == 1 then | ||
item = Items.getItemByID(purch.contains.items[1].id) | item = Items.getItemByID(purch.contains.items[1].id) | ||
Line 158: | Line 142: | ||
local displayInline = (inline ~= nil and inline or false) | local displayInline = (inline ~= nil and inline or false) | ||
local costArray = {} | local costArray = {} | ||
local currencies = {'gp', 'slayerCoins', 'raidCoins'} | |||
for i, currency in ipairs(currencies) do | |||
if cost[currency] ~= nil then | |||
local costStr = p.getCurrencyCostString(cost[currency], currency) | |||
if costStr ~= nil then | |||
table.insert(costArray, costStr) | |||
end | |||
end | |||
end | |||
if cost.items ~= nil and not Shared.tableIsEmpty(cost.items) then | if cost.items ~= nil and not Shared.tableIsEmpty(cost.items) then | ||
local itemArray = {} | |||
for i, itemCost in ipairs(cost.items) do | for i, itemCost in ipairs(cost.items) do | ||
local item = Items.getItemByID(itemCost.id) | local item = Items.getItemByID(itemCost.id) | ||
if item ~= nil then | |||
table.insert(itemArray, Icons.Icon({item.name, type="item", notext=(not displayInline and true or nil), qty=itemCost.quantity})) | |||
end | |||
end | |||
if not Shared.tableIsEmpty(itemArray) then | |||
table.insert(costArray, table.concat(itemArray, ', ')) | |||
end | end | ||
end | end | ||
if not Shared.tableIsEmpty(costArray) then | |||
local sep, lastSep = '<br/>', '<br/>' | |||
if displayInline then | |||
sep = ', ' | |||
lastSep = Shared.tableCount(costArray) > 2 and ', and ' or ' and ' | |||
end | |||
return mw.text.listToText(costArray, sep, lastSep) | |||
end | |||
end | end | ||
Line 203: | Line 187: | ||
function p.getCurrencyCostString(cost, currency) | function p.getCurrencyCostString(cost, currency) | ||
local decoratorList = { | |||
["gp"] = Icons.GP, | |||
["slayerCoins"] = Icons.SC, | |||
["raidCoins"] = Icons.RC | |||
} | |||
local decorator = nil | |||
if currency ~= nil then | |||
decorator = decoratorList[currency] | |||
end | |||
if decorator == nil then | |||
decorator = function(cost) return cost end | |||
end | end | ||
if cost.type == 'BankSlot' then | |||
-- Unusual bit of code that basically evaluates wikitext '<math>C_b</math>*' | |||
return mw.getCurrentFrame():callParserFunction('#tag:math', {'C_b'}) .. '*' | |||
elseif cost.type == 'Linear' and (cost.initial > 0 or cost.scaling > 0) then | |||
return decorator(cost.initial) .. '<br/>+' .. decorator(cost.scaling) .. ' for each purchase' | |||
elseif cost.type == 'Glove' or cost.type == 'Fixed' and cost.cost > 0 then | |||
-- Type Glove exists in game so the Merchant's Permit cost reduction can be applied, | |||
-- it makes no difference here | |||
return decorator(cost.cost) | |||
return | |||
end | end | ||
end | end | ||
Line 325: | Line 225: | ||
for i, itemLine in ipairs(purchase.contains.items) do | for i, itemLine in ipairs(purchase.contains.items) do | ||
local item = Items.getItemByID(itemLine.id) | local item = Items.getItemByID(itemLine.id) | ||
local itemQty = itemLine.quantity | |||
if asList then | if asList then | ||
table.insert(containArray, Icons.Icon({item.name, type='item', qty=itemQty})) | table.insert(containArray, Icons.Icon({item.name, type='item', qty=itemQty})) | ||
Line 331: | Line 231: | ||
local GPVal = item.sellsFor * itemQty | local GPVal = item.sellsFor * itemQty | ||
GPTotal = GPTotal + GPVal | GPTotal = GPTotal + GPVal | ||
table.insert(containArray, '|-\r\n| | table.insert(containArray, '|-\r\n| class="table-img"| ' .. Icons.Icon({item.name, type='item', notext=true, size='25'})) | ||
table.insert(containArray, '|data-sort-value="'..item.name..'"|'.. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}) .. '\r\n| data-sort-value="' .. itemQty .. '" style="text-align:right" | ' .. Shared.formatnum(itemQty)) | table.insert(containArray, '|data-sort-value="'..item.name..'"|'.. Icons.getExpansionIcon(item.id) .. Icons.Icon({item.name, type='item', noicon=true}) .. '\r\n| data-sort-value="' .. itemQty .. '" style="text-align:right" | ' .. Shared.formatnum(itemQty)) | ||
table.insert(containArray, '| data-sort-value="' .. GPVal .. '"| ' .. Icons.GP(GPVal)) | table.insert(containArray, '| data-sort-value="' .. GPVal .. '"| ' .. Icons.GP(GPVal)) | ||
Line 338: | Line 238: | ||
end | end | ||
if purchase.contains.itemCharges ~= nil and purchase.contains.itemCharges.quantity > 0 then | if purchase.contains.itemCharges ~= nil and purchase.contains.itemCharges.quantity > 0 then | ||
local gloveItem = Items.getItemByID(purchase.contains.itemCharges.id) | |||
local chargeQty = purchase.contains.itemCharges.quantity | |||
if gloveItem ~= nil then | |||
if asList then | |||
table.insert(containArray, '+'..Shared.formatnum(chargeQty)..' '..Icons.Icon({gloveItem.name, type='item'})..' Charges') | |||
else | |||
table.insert(containArray, '|-\r\n| class="table-img"| ' .. Icons.Icon({gloveItem.name, type='item', notext=true, size='25'})) | |||
table.insert(containArray, '| ' .. Icons.Icon({gloveItem.name, type='item', noicon=true}) .. ' Charges\r\n| data-sort-value="' .. chargeQty .. '" style="text-align:right" | ' .. Shared.formatnum(chargeQty)) | |||
table.insert(containArray, '| data-sort-value="0"| ' .. Icons.GP(0)) | |||
end | |||
end | |||
end | end | ||
end | end | ||
Line 361: | Line 261: | ||
function p.getPurchaseContents(frame) | function p.getPurchaseContents(frame) | ||
local args = frame.args ~= nil and frame.args or frame | local args = frame.args ~= nil and frame.args or frame | ||
local purchaseName = args[1] | local purchaseName = Shared.fixPagename(args[1]) | ||
local asList = (args[2] ~= nil and string.upper(args[2]) == 'TRUE') | local asList = (args[2] ~= nil and string.upper(args[2]) == 'TRUE') | ||
local purchase = p.getPurchase(purchaseName) | local purchase = p.getPurchase(purchaseName) | ||
Line 385: | Line 285: | ||
function p._getPurchaseBuyLimit(purchase, asList) | function p._getPurchaseBuyLimit(purchase, asList) | ||
if asList == nil then asList = true end | if asList == nil then asList = true end | ||
local defaultLimit = (purchase.defaultBuyLimit == 0 and 'Unlimited') or Shared.formatnum(purchase.defaultBuyLimit) | |||
if purchase.buyLimitOverrides == nil or Shared.tableIsEmpty(purchase.buyLimitOverrides) then | |||
-- Same limit for all game modes | |||
return defaultLimit | |||
else | |||
-- The limit varies depending on game mode | |||
local limitTable = {} | |||
local gamemodeHasIcon = { 'melvorF:Hardcore', 'melvorF:Adventure' } | |||
for i, buyLimit in ipairs(purchase.buyLimitOverrides) do | |||
local gamemode = GameData.getEntityByID('gamemodes', buyLimit.gamemodeID) | |||
if gamemode ~= nil then | |||
local gamemodeName = Shared.splitString(gamemode.name, ' ')[1] | local gamemodeName = Shared.splitString(gamemode.name, ' ')[1] | ||
local gamemodeText = nil | |||
if Shared.contains(gamemodeHasIcon, gamemode.id) then | |||
gamemodeText = Icons.Icon({gamemodeName, notext=(not asList or nil)}) | |||
else | |||
gamemodeText = '[[Game Mode#' .. gamemodeName .. '|' .. gamemodeName .. ']]' | |||
end | |||
local limitText = (buyLimit.maximum == 0 and 'Unlimited') or Shared.formatnum(buyLimit.maximum) | |||
table.insert(limitTable, limitText .. (asList and ' for ' or ' ') .. gamemodeText) | |||
end | |||
end | |||
table.insert(limitTable, defaultLimit .. (asList and ' for ' or ' ') .. 'All other game modes') | |||
return table.concat(limitTable, (asList and ' or ' or '<br/>')) | |||
end | |||
end | end | ||
Line 423: | Line 323: | ||
return p._getPurchaseBuyLimit(purchase, asList) | return p._getPurchaseBuyLimit(purchase, asList) | ||
end | end | ||
end | end | ||
Line 454: | Line 334: | ||
else | else | ||
args[1] = purchase | args[1] = purchase | ||
return | return Common.getPurchaseIcon(args) | ||
end | end | ||
end | end | ||
Line 462: | Line 342: | ||
for j, curr in ipairs(costCurrencies) do | for j, curr in ipairs(costCurrencies) do | ||
local costAmt = purchase.cost[curr] | local costAmt = purchase.cost[curr] | ||
if costAmt.type == 'BankSlot' then | |||
return -1 | |||
elseif costAmt.type == 'Linear' then | |||
return costAmt.initial | |||
elseif costAmt.type == 'Glove' or costAmt.type == 'Fixed' and costAmt.cost > 0 then | |||
return costAmt.cost | |||
end | |||
end | |||
end | end | ||
Line 535: | Line 415: | ||
end | end | ||
for i, purchase in ipairs(Purchases) do | for i, purchase in ipairs(Purchases) do | ||
local purchName = Common.getPurchaseName(purchase) | |||
local purchExpIcon = p._getPurchaseExpansionIcon(purchase) | |||
local purchType = Common.getPurchaseType(purchase) | |||
local purchType = | |||
local costString = p.getCostString(purchase.cost, false) | local costString = p.getCostString(purchase.cost, false) | ||
table.insert(resultPart, '|-') | table.insert(resultPart, '|-') | ||
for j, column in ipairs(usedColumns) do | for j, column in ipairs(usedColumns) do | ||
if column == 'Purchase' then | if column == 'Purchase' then | ||
table.insert(resultPart, '| | table.insert(resultPart, '|class="table-img"|' .. Common.getPurchaseIcon({purchase, notext=true, size='50'})) | ||
table.insert(resultPart, '| data-sort-value="'..purchName..'"|'..purchExpIcon .. Common.getPurchaseIcon({purchase, noicon=true})) | |||
table.insert(resultPart, '| data-sort-value="'.. | |||
elseif column == 'Type' then | elseif column == 'Type' then | ||
table.insert(resultPart, '| ' .. purchType) | table.insert(resultPart, '| ' .. purchType) | ||
Line 573: | Line 435: | ||
table.insert(resultPart, cellProp .. '| ' .. costString) | table.insert(resultPart, cellProp .. '| ' .. costString) | ||
elseif column == 'Requirements' then | elseif column == 'Requirements' then | ||
table.insert(resultPart, '| ' .. | table.insert(resultPart, '| ' .. Common.getRequirementString(purchase.purchaseRequirements, 'None')) | ||
elseif column == 'Buy Limit' then | elseif column == 'Buy Limit' then | ||
local buyLimit = p._getPurchaseBuyLimit(purchase, false) | local buyLimit = p._getPurchaseBuyLimit(purchase, false) | ||
Line 586: | Line 448: | ||
table.insert(resultPart, '|}') | table.insert(resultPart, '|}') | ||
return table.concat(resultPart, ' | return table.concat(resultPart, '\n') | ||
end | end | ||
Line 618: | Line 480: | ||
end | end | ||
end | end | ||
local shopCat = GameData.getEntityByName('shopCategories', cat) | |||
if shopCat == nil then | if shopCat == nil then | ||
return Shared.printError('Invalid category ' .. cat) | return Shared.printError('Invalid category ' .. cat) | ||
else | else | ||
local catPurchases = p.getPurchases(function(purch) return purch.category == shopCat.id end) | |||
return p._getShopTable(catPurchases, options) | return p._getShopTable(catPurchases, options) | ||
end | end | ||
Line 628: | Line 490: | ||
function p.getItemCostArray(itemID) | function p.getItemCostArray(itemID) | ||
local purchaseArray = {} | |||
for i, purchase in ipairs(GameData.rawData.shopPurchases) do | |||
if purchase.cost ~= nil and purchase.cost.items ~= nil then | |||
for j, itemCost in ipairs(purchase.cost.items) do | |||
if itemCost.id == itemID then | |||
table.insert(purchaseArray, { ["purchase"] = purchase, ["qty"] = itemCost.quantity }) | |||
break | |||
end | |||
end | |||
end | |||
end | |||
return purchaseArray | |||
end | end | ||
function p.getItemSourceArray(itemID) | function p.getItemSourceArray(itemID) | ||
local purchaseArray = {} | |||
for i, purchase in ipairs(GameData.rawData.shopPurchases) do | |||
if purchase.contains ~= nil then | |||
if purchase.contains.items ~= nil then | |||
for j, itemContains in ipairs(purchase.contains.items) do | |||
if itemContains.id == itemID then | |||
table.insert(purchaseArray, { ["purchase"] = purchase, ["qty"] = itemContains.quantity }) | |||
break | |||
end | |||
end | |||
end | |||
if purchase.contains.itemCharges ~= nil and purchase.contains.itemCharges.id == itemID then | |||
table.insert(purchaseArray, { ["purchase"] = purchase, ["qty"] = 1 }) | |||
end | |||
end | |||
end | |||
return purchaseArray | |||
end | end | ||
Line 666: | Line 528: | ||
result = result..'\r\n!colspan="2"|'..Icons.Icon({'Shop'})..' Purchase' | result = result..'\r\n!colspan="2"|'..Icons.Icon({'Shop'})..' Purchase' | ||
if purchase.contains.items ~= nil and Shared.tableCount(purchase.contains.items) > 1 then | if purchase.contains.items ~= nil and Shared.tableCount(purchase.contains.items) > 1 then | ||
result = result..' - '..p._getPurchaseExpansionIcon(purchase)..Icons.Icon({ | result = result..' - '..p._getPurchaseExpansionIcon(purchase)..Icons.Icon({Common.getPurchaseName(purchase), type='item'}) | ||
end | end | ||
Line 673: | Line 535: | ||
result = result..'\r\n|-\r\n!style="text-align:right;"|Requirements' | result = result..'\r\n|-\r\n!style="text-align:right;"|Requirements' | ||
result = result..'\r\n|'.. | result = result..'\r\n|'..Common.getRequirementString(purchase.purchaseRequirements, 'None') | ||
result = result..'\r\n|-\r\n!style="text-align:right;"|Contains' | result = result..'\r\n|-\r\n!style="text-align:right;"|Contains' | ||
result = result..'\r\n | result = result..'\r\n|'..p._getPurchaseContents(purchase, true) | ||
result = result..'\r\n|}' | result = result..'\r\n|}' | ||
Line 704: | Line 566: | ||
function p.getShopMiscUpgradeTable() | function p.getShopMiscUpgradeTable() | ||
local purchList = p.getPurchases(function(purch) return | -- All purchases in the general category besides Auto Eat, which is handled by getAutoEatTable() | ||
local purchList = p.getPurchases(function(purch) return purch.category == 'melvorD:General' and string.find(purch.id, '^melvorD:Auto_Eat') == nil end) | |||
return p._getShopTable(purchList, { columns = { 'Purchase', 'Description', 'Cost', 'Requirements' }, purchaseHeader = 'Upgrade' }) | |||
end | |||
function p.getShopSkillUpgradeTable() | |||
-- All purchaes in the SkillUpgrades category except tools and any upgrades displayed as | |||
-- tools (e.g. ship upgrades) | |||
local purchList = p.getPurchases( | |||
function(purch) | |||
return purch.category == 'melvorD:SkillUpgrades' | |||
-- Exclude tools, handled by p.getToolTable() | |||
and string.find(purch.id, '_Axe$') == nil | |||
and string.find(purch.id, '_Pickaxe$') == nil | |||
and string.find(purch.id, '_Rod$') == nil | |||
and string.find(purch.id, '_Pickaxe$') == nil | |||
and string.find(purch.id, 'Fire$') == nil | |||
and string.find(purch.id, 'Furnace$') == nil | |||
and string.find(purch.id, 'Pot$') == nil | |||
and string.find(purch.id, 'Sieve$') == nil | |||
and string.find(purch.id, 'Trowel$') == nil | |||
and string.find(purch.id, 'Brush$') == nil | |||
and string.find(purch.id, 'Shovel$') == nil | |||
and string.find(purch.id, 'ShipUpgrade') == nil | |||
-- Exclude God upgrades, handled by p.getGodUpgradeTable() | |||
and p.getGodUpgradeDungeon(purch) == nil | |||
end | |||
) | |||
return p._getShopTable(purchList, { columns = { 'Purchase', 'Description', 'Cost', 'Requirements' }, purchaseHeader = 'Upgrade' }) | return p._getShopTable(purchList, { columns = { 'Purchase', 'Description', 'Cost', 'Requirements' }, purchaseHeader = 'Upgrade' }) | ||
end | |||
function p.isSkillcapePurchase(purch, isSuperior, skillID) | |||
-- Returns true or false depending on whether the purchase is a skillcape or not. | |||
-- If isSuperior is true, then this checks for superior skillcapes, false checks | |||
-- for regular skillcapes, and nil checks for both. | |||
-- If skillID is specified, then the skillcape must also relate to that skill | |||
local checkCategories = (isSuperior == nil and {'melvorTotH:SuperiorSkillcapes', 'melvorD:Skillcapes'}) or (isSuperior and {'melvorTotH:SuperiorSkillcapes'}) or {'melvorD:Skillcapes'} | |||
-- Some skillcapes (such as Archaeology & Cartography) reside outside of the usual categories | |||
local overrideIDs = { | |||
['melvorTotH:SuperiorSkillcapes'] = { | |||
'melvorAoD:Superior_Archaeology_Skillcape', | |||
'melvorAoD:Superior_Cartography_Skillcape', | |||
'melvorAoD:Cape_of_Completion_AoD' | |||
}, | |||
['melvorD:Skillcapes'] = { | |||
'melvorAoD:Archaeology_Skillcape', | |||
'melvorAoD:Cartography_Skillcape' | |||
} | |||
} | |||
for i, cat in ipairs(checkCategories) do | |||
if purch.category == cat or Shared.contains(overrideIDs[cat], purch.id) then | |||
if skillID == nil then | |||
return true | |||
else | |||
-- Also validate purchase requirements for relevant SkillLevel requirement | |||
local hasReq = false | |||
if type(purch.purchaseRequirements) == 'table' then | |||
for j, req in ipairs(purch.purchaseRequirements) do | |||
if req.type == 'SkillLevel' then | |||
if req.skillID == skillID then | |||
hasReq = true | |||
else | |||
-- The presence of any other skill's requirement indicates | |||
-- this is not a skillcape for skill with ID skillID | |||
return false | |||
end | |||
end | |||
end | |||
end | |||
return hasReq | |||
end | |||
end | |||
end | |||
return false | |||
end | end | ||
function p._getShopSkillcapeTable(showSuperior) | function p._getShopSkillcapeTable(showSuperior) | ||
local capeList = p.getPurchases(function(purch) return p.isSkillcapePurchase(purch, showSuperior) end) | |||
local capeList = p.getPurchases(function(purch) return purch | |||
local sortOrderFunc = | local sortOrderFunc = | ||
function(a, b) | function(a, b) | ||
local costA, costB = p._getPurchaseSortValue(a), p._getPurchaseSortValue(b) | local costA, costB = p._getPurchaseSortValue(a), p._getPurchaseSortValue(b) | ||
if costA == costB then | if costA == costB then | ||
return | return Common.getPurchaseName(a) < Common.getPurchaseName(b) | ||
else | else | ||
return costA < costB | return costA < costB | ||
Line 733: | Line 668: | ||
local capeCategory = frame.args ~= nil and frame.args[1] or frame | local capeCategory = frame.args ~= nil and frame.args[1] or frame | ||
local showSuperior = string.lower(capeCategory) == 'superior' | local showSuperior = string.lower(capeCategory) == 'superior' | ||
return p._getShopSkillcapeTable(showSuperior) | return p._getShopSkillcapeTable(showSuperior) | ||
end | end | ||
Line 739: | Line 674: | ||
function p.getSkillcapeTable(frame) | function p.getSkillcapeTable(frame) | ||
local skillName = frame.args ~= nil and frame.args[1] or frame | local skillName = frame.args ~= nil and frame.args[1] or frame | ||
local skillID = Constants.getSkillID(skillName) | |||
local | if skillID == nil then | ||
if | return Shared.printError('No such skill "' .. (skillName or 'nil') .. '"') | ||
end | end | ||
local capeList = p.getPurchases(function(purch) return p.isSkillcapePurchase(purch, nil, skillID) end) | |||
if Shared.tableIsEmpty(capeList) then | if Shared.tableIsEmpty(capeList) then | ||
return '' | return '' | ||
else | else | ||
capeList = GameData.sortByOrderTable(capeList, GameData.rawData.shopDisplayOrder, true) | |||
local resultPart = {} | local resultPart = {} | ||
table.insert(resultPart, '{| class="wikitable" | table.insert(resultPart, '{| class="wikitable"\n') | ||
table.insert(resultPart, '!Skillcape!!Name!!Requirements!!Effect') | table.insert(resultPart, '!Skillcape!!Name!!Requirements!!Effect') | ||
for i, cape in ipairs(capeList) do | for i, cape in ipairs(capeList) do | ||
local capeItem = Items.getItemByID(cape.contains.items[1].id) | local capeItem = Items.getItemByID(cape.contains.items[1].id) | ||
if capeItem ~= nil then | if capeItem ~= nil then | ||
table.insert(resultPart, ' | table.insert(resultPart, '\n|-\n| ' .. Icons.Icon({capeItem.name, type='item', size='60', notext=true})) | ||
table.insert(resultPart, ' | table.insert(resultPart, '\n| data-sort-value="'..capeItem.name..'"|'..Icons.getExpansionIcon(capeItem.id) .. Icons.Icon({capeItem.name, type='item', noicon=true})) | ||
table.insert(resultPart, ' | table.insert(resultPart, '\n| ' .. Common.getRequirementString(cape.purchaseRequirements, 'None')) | ||
table.insert(resultPart, ' | table.insert(resultPart, '\n| ' .. p._getPurchaseDescription(cape)) | ||
end | end | ||
end | end | ||
table.insert(resultPart, ' | table.insert(resultPart, '\n|}') | ||
return table.concat(resultPart) | return table.concat(resultPart) | ||
end | end | ||
Line 778: | Line 713: | ||
local mods = {["increasedAutoEatEfficiency"] = 0, ["increasedAutoEatHPLimit"] = 0, ["increasedAutoEatThreshold"] = 0} | local mods = {["increasedAutoEatEfficiency"] = 0, ["increasedAutoEatHPLimit"] = 0, ["increasedAutoEatThreshold"] = 0} | ||
for i, purchase in ipairs(purchasesAE) do | for i, purchase in ipairs(purchasesAE) do | ||
local purchaseName = Common.getPurchaseName(purchase) | |||
-- Modifiers must be accumulated as we go | -- Modifiers must be accumulated as we go | ||
for modName, modValue in pairs(mods) do | for modName, modValue in pairs(mods) do | ||
Line 786: | Line 721: | ||
end | end | ||
table.insert(resultPart, '|-\r\n| | table.insert(resultPart, '|-\r\n|class="table-img" data-sort-value="' .. purchaseName .. '"| ' .. Icons.Icon({purchaseName, type='upgrade', size=50, notext=true})) | ||
table.insert(resultPart, '| ' .. Icons.Icon({purchaseName, type='upgrade', noicon=true})) | table.insert(resultPart, '| ' .. Icons.Icon({purchaseName, type='upgrade', noicon=true})) | ||
table.insert(resultPart, '| style="text-align:right;" data-sort-value="' .. mods.increasedAutoEatThreshold .. '" | ' .. Shared.formatnum(Shared.round(mods.increasedAutoEatThreshold, 0, 0)) .. '%') | table.insert(resultPart, '| style="text-align:right;" data-sort-value="' .. mods.increasedAutoEatThreshold .. '" | ' .. Shared.formatnum(Shared.round(mods.increasedAutoEatThreshold, 0, 0)) .. '%') | ||
Line 796: | Line 731: | ||
return table.concat(resultPart, '\r\n') | return table.concat(resultPart, '\r\n') | ||
end | |||
function p.getGodUpgradeDungeon(purch) | |||
-- Identifies skill upgrades which have a dungeon completion requirement for an area | |||
-- whose name ends with 'God Dungeon'. Returns the ID of the dungeon which must be | |||
-- completed before the purchase may be bought if the purchase is a god upgrade | |||
if purch.category == 'melvorD:SkillUpgrades' and type(purch.purchaseRequirements) == 'table' then | |||
for i, req in ipairs(purch.purchaseRequirements) do | |||
if req.type == 'DungeonCompletion' and string.find(req.dungeonID, 'God_Dungeon$') ~= nil then | |||
return req.dungeonID | |||
end | |||
end | |||
end | |||
end | end | ||
function p.getGodUpgradeTable() | function p.getGodUpgradeTable() | ||
local resultPart = {} | local resultPart = {} | ||
local upgradeList = p.getPurchases( | local upgradeList = p.getPurchases( | ||
function(purch) | function(purch) | ||
return p.getGodUpgradeDungeon(purch) ~= nil | |||
end) | end) | ||
if Shared.tableIsEmpty(upgradeList) then | if Shared.tableIsEmpty(upgradeList) then | ||
return '' | |||
end | |||
-- Table header | -- Table header | ||
Line 829: | Line 763: | ||
-- Rows for each God upgrade | -- Rows for each God upgrade | ||
for i, upgrade in ipairs(upgradeList) do | for i, upgrade in ipairs(upgradeList) do | ||
local upgradeName = Common.getPurchaseName(upgrade) | |||
local dung = | local dung = GameData.getEntityByID('dungeons', p.getGodUpgradeDungeon(upgrade)) | ||
local costSortValue = p._getPurchaseSortValue(upgrade) | local costSortValue = p._getPurchaseSortValue(upgrade) | ||
table.insert(resultPart, '|-\r\n| | table.insert(resultPart, '|-\r\n|class="table-img" data-sort-value="' .. upgradeName .. '"| ' ..p._getPurchaseExpansionIcon(upgrade).. Icons.Icon({upgradeName, type='upgrade', size=50, notext=true})) | ||
table.insert(resultPart, '| ' .. Icons.Icon({upgradeName, type='upgrade', noicon=true})) | table.insert(resultPart, '| ' .. Icons.Icon({upgradeName, type='upgrade', noicon=true})) | ||
table.insert(resultPart, '| ' .. p._getPurchaseDescription(upgrade)) | table.insert(resultPart, '| ' .. p._getPurchaseDescription(upgrade)) | ||
Line 841: | Line 775: | ||
return table.concat(resultPart, '\r\n') | return table.concat(resultPart, '\r\n') | ||
end | |||
function p.getAoDTable(frame) | |||
-- All purchases in the Atlas of Discovery category except for skillcapes, which are handled | |||
-- by p.getShopSKilcapeTable() | |||
local purchList = p.getPurchases( | |||
function(purch) | |||
return purch.category == 'melvorAoD:AtlasOfDiscovery' and not p.isSkillcapePurchase(purch) | |||
end | |||
) | |||
return p._getShopTable(purchList, { columns = { 'Purchase', 'Description', 'Cost', 'Requirements' } }) | |||
end | end | ||
Line 867: | Line 813: | ||
local headerRowSpan = (Shared.tableIsEmpty(toolArray) and 1) or 2 | local headerRowSpan = (Shared.tableIsEmpty(toolArray) and 1) or 2 | ||
local resultPart = {} | local resultPart = {} | ||
table.insert(resultPart, '{| class="wikitable"') | table.insert(resultPart, '{| class="wikitable stickyHeader"') | ||
table.insert(resultPart, '\n|- class="headerRow-0"') | |||
table.insert(resultPart, '\n!rowspan="' .. headerRowSpan .. '" colspan="2"| Name') | table.insert(resultPart, '\n!rowspan="' .. headerRowSpan .. '" colspan="2"| Name') | ||
table.insert(resultPart, '\n!rowspan="' .. headerRowSpan .. '"| ' .. (skillName == nil and 'Requirements' or Icons.Icon({skillName, type='skill', notext=true}) .. ' Level')) | table.insert(resultPart, '\n!rowspan="' .. headerRowSpan .. '"| ' .. (skillName == nil and 'Requirements' or Icons.Icon({skillName, type='skill', notext=true}) .. ' Level')) | ||
Line 876: | Line 823: | ||
end | end | ||
if headerRowSpan > 1 then | if headerRowSpan > 1 then | ||
table.insert(resultPart, '\n|-' .. string.rep('\n!This ' .. toolName .. '\n!Total', Shared.tableCount(modifiers))) | table.insert(resultPart, '\n|- class="headerRow-1"' .. string.rep('\n!This ' .. toolName .. '\n!Total', Shared.tableCount(modifiers))) | ||
end | end | ||
-- Keep track of modifiers which are present on tools but not exposed within the table, so | |||
-- that an error may be printed if any are omitted | |||
local modsUnused = {} | |||
for i, tool in ipairs(toolArray) do | for i, tool in ipairs(toolArray) do | ||
local toolName = | local toolName = Common.getPurchaseName(tool) | ||
local toolCost = p.getCostString(tool.cost, false) | local toolCost = p.getCostString(tool.cost, false) | ||
local toolCostSort = p._getPurchaseSortValue(tool) or 0 | local toolCostSort = p._getPurchaseSortValue(tool) or 0 | ||
table.insert(resultPart, '\n|-') | table.insert(resultPart, '\n|-') | ||
table.insert(resultPart, '\n| | table.insert(resultPart, '\n|class="table-img" data-sort-value="' .. toolName .. '"| ' .. Icons.Icon({toolName, type='upgrade', size='50', notext=true})) | ||
table.insert(resultPart, '\n| data-sort-value="' .. toolName.. '"|' .. Icons.getExpansionIcon(tool.id) .. toolName) | table.insert(resultPart, '\n| data-sort-value="' .. toolName.. '"|' .. Icons.getExpansionIcon(tool.id) .. toolName) | ||
local level, levelStyle = nil, nil | local level, levelStyle = nil, nil | ||
Line 897: | Line 847: | ||
if skillID == nil then | if skillID == nil then | ||
-- Return all requirements | -- Return all requirements | ||
level = | level = Common.getRequirementString(tool.purchaseRequirements, 'None') | ||
if level ~= 'None' then | if level ~= 'None' then | ||
levelStyle = '' | levelStyle = '' | ||
Line 914: | Line 864: | ||
table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. toolCostSort .. '"| ' .. toolCost) | table.insert(resultPart, '\n|style="text-align:right" data-sort-value="' .. toolCostSort .. '"| ' .. toolCost) | ||
local resultPrefix = '' | |||
local cellStart = '\n|style="text-align:right"' | local cellStart = '\n|style="text-align:right"' | ||
if tool.contains ~= nil and tool.contains.modifiers ~= nil then | if tool.contains ~= nil and tool.contains.modifiers ~= nil then | ||
for modName, modVal in pairs(tool.contains.modifiers) do | |||
if modTotal[modName] == nil and not Shared.contains(modsUnused, modName) then | |||
-- Mod with name modName is provided by the purchase, but not exposed within | |||
-- the output table | |||
table.insert(modsUnused, modName) | |||
end | |||
end | |||
for j, modDef in ipairs(modifiers) do | for j, modDef in ipairs(modifiers) do | ||
local modName = modDef.name | local modName = modDef.name | ||
Line 935: | Line 894: | ||
end | end | ||
local resultPrefix = '' | |||
if not Shared.tableIsEmpty(modsUnused) then | |||
resultPrefix = Shared.printError('The following modifiers are not included within the table: ' .. table.concat(modsUnused, ', ')) .. '\n' | |||
end | |||
table.insert(resultPart, '\n|}') | table.insert(resultPart, '\n|}') | ||
return table.concat(resultPart) | return resultPrefix .. table.concat(resultPart) | ||
end | end | ||
Line 985: | Line 948: | ||
['Cooking Fire'] = { | ['Cooking Fire'] = { | ||
{ name = 'increasedSkillXP', skillID = 'melvorD:Cooking', header = 'Bonus ' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' XP', sign = '+', suffix = '%' }, | { name = 'increasedSkillXP', skillID = 'melvorD:Cooking', header = 'Bonus ' .. Icons.Icon({'Cooking', type='skill', notext=true}) .. ' XP', sign = '+', suffix = '%' }, | ||
{ name = 'increasedChancePerfectCookFire', header = 'Fire Perfect Cook Chance', sign ='+', suffix = '%' }, | { name = 'increasedChancePerfectCookFire', header = Icons.Icon({'Normal Cooking Fire', type='upgrade', notext=true, nolink=true}) .. ' Perfect Cook Chance', sign ='+', suffix = '%' }, | ||
{ name = 'decreasedPassiveCookInterval', header = 'Passive Cook Time Decrease', sign = '-', suffix = '%' }, | { name = 'decreasedPassiveCookInterval', header = 'Passive Cook Time Decrease', sign = '-', suffix = '%' }, | ||
{ name = 'increasedChanceToDoubleItemsSkill', skillID = 'melvorD:Cooking', header = '2x Items Chance', sign = '+', suffix = '%' }, | { name = 'increasedChanceToDoubleItemsSkill', skillID = 'melvorD:Cooking', header = '2x Items Chance', sign = '+', suffix = '%' }, | ||
Line 991: | Line 954: | ||
}, | }, | ||
['Furnace'] = { | ['Furnace'] = { | ||
{ name = 'increasedChancePerfectCookFurnace', header = Icons.Icon({'Basic Furnace', type='upgrade', notext=true, nolink=true}) .. ' Perfect Cook Chance', sign = '+', suffix = '%' }, | |||
{ name = 'increasedChanceToDoubleItemsSkill', skillID = 'melvorD:Cooking', header = '2x Items Chance', sign = '+', suffix = '%' }, | { name = 'increasedChanceToDoubleItemsSkill', skillID = 'melvorD:Cooking', header = '2x Items Chance', sign = '+', suffix = '%' }, | ||
{ name = 'decreasedPassiveCookInterval', header = 'Passive Cook Time Decrease', sign = '-', suffix = '%' }, | { name = 'decreasedPassiveCookInterval', header = 'Passive Cook Time Decrease', sign = '-', suffix = '%' }, | ||
Line 997: | Line 961: | ||
}, | }, | ||
['Pot'] = { | ['Pot'] = { | ||
{ name = 'increasedChancePerfectCookPot', header = Icons.Icon({'Basic Pot', type='upgrade', notext=true, nolink=true}) .. ' Perfect Cook Chance', sign = '+', suffix = '%' }, | |||
{ name = 'increasedChanceToDoubleItemsSkill', skillID = 'melvorD:Cooking', header = '2x Items Chance', sign = '+', suffix = '%' }, | { name = 'increasedChanceToDoubleItemsSkill', skillID = 'melvorD:Cooking', header = '2x Items Chance', sign = '+', suffix = '%' }, | ||
{ name = 'decreasedPassiveCookInterval', header = 'Passive Cook Time Decrease', sign = '-', suffix = '%' }, | { name = 'decreasedPassiveCookInterval', header = 'Passive Cook Time Decrease', sign = '-', suffix = '%' }, | ||
{ name = 'decreasedSkillIntervalPercent', skillID = 'melvorD:Cooking', header = 'Active Cook Time Decrease', sign = '-', suffix = '%' }, | { name = 'decreasedSkillIntervalPercent', skillID = 'melvorD:Cooking', header = 'Active Cook Time Decrease', sign = '-', suffix = '%' }, | ||
{ name = 'increasedChanceAdditionalSkillResource', skillID = 'melvorD:Cooking', header = '+1 Item Chance', sign = '+', suffix = '%' } | { name = 'increasedChanceAdditionalSkillResource', skillID = 'melvorD:Cooking', header = '+1 Item Chance', sign = '+', suffix = '%' }, | ||
{ name = 'increasedMasteryXP', skillID = 'melvorD:Cooking', header = 'Increased Cooking ' .. Icons.Icon({'Mastery', nolink=true}) .. ' XP', sign = '+', suffix = '%'} | |||
} | } | ||
} | } | ||
return p.getToolTable(categoryShort, categoryShort .. '$', modifiers[category], nil) | return p.getToolTable(categoryShort, categoryShort .. '$', modifiers[category], nil) | ||
end | |||
--Adding table for Ship upgrades for Cartography | |||
function p.getShipTable(frame) | |||
local modifiers = { | |||
{ name = 'decreasedSkillIntervalPercent', header = 'Cartography Interval', sign = '-', suffix = '%' }, | |||
{ name = 'increasedSightRange', header = 'Increased Sight Range', sign = '+', suffix = '' }, | |||
{ name = 'increasedSurveyRange', header = 'Increased Survey Range', sign = '+', suffix = ''}, | |||
} | |||
return p.getToolTable('Ship', 'Ship', modifiers, 'melvorAoD:Cartography') | |||
end | |||
function p.getArchToolTable(frame)local category = nil | |||
if frame ~= nil then category = frame.args ~= nil and frame.args[1] or frame end | |||
local validCategories = {'Sieve', 'Trowel', 'Brush', 'Shovel'} | |||
if category == nil or not Shared.contains(validCategories, category) then | |||
return Shared.printError('Invalid category specified. Must be one of the following: ' .. mw.text.listToText(validCategories, ', ', ' or ')) | |||
end | |||
local modifiers = { | |||
{name = 'increased'..category..'ToolLevel', header = 'Increased '..category..' Tool level', sign = '+', suffix = ''} | |||
} | |||
return p.getToolTable(category, category .. '$', modifiers, 'melvorAoD:Archaeology') | |||
end | |||
-- Below functions included for backwards compatibility | |||
-- TODO: Remove dependency on these functions in all other modules | |||
function p._getPurchaseName(purchase) | |||
return Common.getPurchaseName(purchase) | |||
end | |||
function p._getPurchaseType(purchase) | |||
return Common.getPurchaseType(purchase) | |||
end | |||
function p._getPurchaseIcon(iconArgs) | |||
return Common.getPurchaseIcon(iconArgs) | |||
end | |||
function p.getRequirementString(reqs) | |||
return Common.getRequirementString(reqs, 'None') | |||
end | end | ||
return p | return p |
edits