Anonymous

Module:Items/SourceTables: Difference between revisions

From Melvor Idle
m
Add custom separator for ItemSources
(Fix various issues)
m (Add custom separator for ItemSources)
 
(29 intermediate revisions by 6 users not shown)
Line 1: Line 1:
local p = {}
local p = {}


local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
Line 12: Line 11:
local Monsters = require('Module:Monsters')
local Monsters = require('Module:Monsters')
local Skills = require('Module:Skills')
local Skills = require('Module:Skills')
local SourceOverrides = {
['melvorAoD:EarthGolem'] = 'Earth Golem (AoD)'
}


function p._getCreationTable(item)
function p._getCreationTable(item)
Line 43: Line 46:
['Summoning'] = { }
['Summoning'] = { }
}
}
}
}


-- Gathering skills
-- Gathering skills
Line 58: Line 61:
if localSkillID == 'Farming' then
if localSkillID == 'Farming' then
req = { recipe.seedCost }
req = { recipe.seedCost }
local category = GameData.getEntityByID(skillData.categories, recipe.categoryID)
qty = 5 * category.harvestMultiplier
end
end
-- Action time
-- Action time
Line 72: Line 77:
-- Special requirements
-- Special requirements
if recipe.totalMasteryRequired ~= nil then
if recipe.totalMasteryRequired ~= nil then
specialReq = Icons.Icon({'Mastery', notext=true}) .. Shared.formatNum(recipe.totalMasteryRequired) .. 'total [[' .. skill .. ']] [[Mastery]]'
specialReq = Icons.Icon({'Mastery', notext=true}) .. Shared.formatnum(recipe.totalMasteryRequired) .. ' total [[' .. skill .. ']] [[Mastery]]'
end
end
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time, maxTime, specialReq))
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time, maxTime, specialReq))
Line 145: Line 150:
req = req .. '<br/>' .. (costLen == 1 and '' or 'and one of the following:<br/>') .. table.concat(otherCostArray, "<br/>'''OR''' ")
req = req .. '<br/>' .. (costLen == 1 and '' or 'and one of the following:<br/>') .. table.concat(otherCostArray, "<br/>'''OR''' ")
end
end
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time))
specialReq = 'At least 1 ' .. Icons.Icon({'Summoning%23Summoning Marks', item.name, img=item.name, type='mark'}) .. ' mark discovered'
table.insert(tables, p.buildCreationTable(skill, lvl, xp, req, qty, time, nil, specialReq))
-- Some items (such as Arrow shafts) have multiple recipes
-- Some items (such as Arrow shafts) have multiple recipes
elseif type(recipe.alternativeCosts) == 'table' then
elseif type(recipe.alternativeCosts) == 'table' then
Line 200: Line 206:
local spell = Magic.getSpell(spellName, 'altMagic')
local spell = Magic.getSpell(spellName, 'altMagic')
if spell == nil then
if spell == nil then
return 'ERROR: Could not find Alt. Magic spell "' .. spellName .. '"[[Category:Pages with script errors]]'
return Shared.printError('Could not find Alt. Magic spell "' .. spellName .. '"')
else
else
return p._buildAltMagicTable(spell)
return p._buildAltMagicTable(spell)
Line 280: Line 286:
local item = Items.getItem(itemName)
local item = Items.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


Line 286: Line 292:
end
end


function p._getItemSources(item, asList, addCategories)
function p._getItemSources(item, asList, addCategories, separator)
local lineArray = {}
local lineArray = {}
local categoryArray = {}
local categoryArray = {}
local sep = separator or ','


--Alright, time to go through all the ways you can get an item...
--Alright, time to go through all the ways you can get an item...
Line 295: Line 302:
for i, monster in ipairs(GameData.rawData.monsters) do
for i, monster in ipairs(GameData.rawData.monsters) do
local isDrop = false
local isDrop = false
if monster.bones == item.id and Monsters._getMonsterBones(monster) ~= nil then
if monster.bones ~= nil and monster.bones.itemID == item.id and Monsters._getMonsterBones(monster) ~= nil then
-- Item is a bone, and is either a shard from God dungeons or dropped by a non-boss monster with a loot table
-- Item is a bone, and is either a shard from God dungeons or dropped by a non-boss monster with a loot table
isDrop = true
elseif monster.barrierPercent ~= nil and 'melvorAoD:Barrier_Dust' == item.id and not Monsters._isDungeonOnlyMonster(monster) then
-- Item is Barrier Dust and is not a dungeon exclusive monster
isDrop = true
isDrop = true
elseif monster.lootTable ~= nil then
elseif monster.lootTable ~= nil then
Line 312: Line 322:
if isDrop then
if isDrop then
-- Item drops when the monster is killed
-- Item drops when the monster is killed
table.insert(killStrPart, Icons.Icon({monster.name, type='monster', notext=true}))
local iconName = monster.name
if SourceOverrides[monster.id] ~= nil then
iconName = SourceOverrides[monster.id]
end
table.insert(killStrPart, Icons.Icon({iconName, type='monster', notext=true}))
end
end
end
end
Line 337: Line 351:


if not Shared.tableIsEmpty(dungeonStrPart) then
if not Shared.tableIsEmpty(dungeonStrPart) then
table.insert(lineArray, 'Completing: ' .. table.concat(dungeonStrPart, ','))
table.insert(lineArray, 'Completing: ' .. table.concat(dungeonStrPart, sep))
end
end
if not Shared.tableIsEmpty(killStrPart) then
if not Shared.tableIsEmpty(killStrPart) then
table.insert(lineArray, 'Killing: ' .. table.concat(killStrPart, ','))
table.insert(lineArray, 'Killing: ' .. table.concat(killStrPart, sep))
end
end


Line 357: Line 371:


if not Shared.tableIsEmpty(lootPart) then
if not Shared.tableIsEmpty(lootPart) then
table.insert(lineArray, 'Opening: ' .. table.concat(lootPart, ','))
table.insert(lineArray, 'Opening: ' .. table.concat(lootPart, sep))
end
end


Line 382: Line 396:
end
end
local typeText = (catName == 'up' and 'Upgrading') or 'Downgrading'
local typeText = (catName == 'up' and 'Upgrading') or 'Downgrading'
table.insert(lineArray, typeText .. ': ' .. table.concat(parts, ','))
table.insert(lineArray, typeText .. ': ' .. table.concat(parts, sep))
end
end
end
end
Line 389: Line 403:
local thiefItems = Skills.getThievingSourcesForItem(item.id)
local thiefItems = Skills.getThievingSourcesForItem(item.id)
if type(thiefItems) == 'table' then
if type(thiefItems) == 'table' then
local includedNPCs = {}
local thiefPart = {}
local thiefPart = {}
for i, thiefRow in ipairs(thiefItems) do
for i, thiefRow in ipairs(thiefItems) do
Line 394: Line 409:
--if 'all' is the npc, this is a rare item so just say 'Thieving level 1'
--if 'all' is the npc, this is a rare item so just say 'Thieving level 1'
table.insert(lineArray, Icons._SkillReq('Thieving', 1))
table.insert(lineArray, Icons._SkillReq('Thieving', 1))
else
elseif not Shared.contains(includedNPCs, thiefRow.npc) then
table.insert(thiefPart, Icons.Icon({thiefRow.npc, type='thieving', notext=true}))
table.insert(thiefPart, Icons.Icon({thiefRow.npc, type='thieving', notext=true}))
table.insert(includedNPCs, thiefRow.npc)
end
end
end
end
if #thiefPart > 0 then
if not Shared.tableIsEmpty(thiefPart) then
table.insert(lineArray, 'Pickpocketing: ' .. table.concat(thiefPart, ','))
table.insert(lineArray, 'Pickpocketing: ' .. table.concat(thiefPart, sep))
end
end
end
-- Can we get this item by casting an Alt. Magic spell?
local castPart = {}
for i, spell in ipairs(Magic.getSpellsProducingItem(item.id)) do
table.insert(castPart, Icons.Icon({spell.name, type=Magic._getSpellIconType(spell), notext=true}))
end
if not Shared.tableIsEmpty(castPart) then
table.insert(lineArray, 'Casting: ' .. table.concat(castPart, sep))
end
end


Line 420: Line 445:
['Summoning'] = { }
['Summoning'] = { }
}
}
}
}


-- Gathering skills
-- Gathering skills
Line 450: Line 475:
(localSkillID == 'Herblore' and Shared.contains(recipe.potionIDs, item.id)) then
(localSkillID == 'Herblore' and Shared.contains(recipe.potionIDs, item.id)) then
table.insert(lineArray, Icons._SkillReq(skill, recipe.level))
table.insert(lineArray, Icons._SkillReq(skill, recipe.level))
break
end
end
end
-- Township trading
for i, tsResource in ipairs(SkillData.Township.itemConversions.fromTownship) do
local found = false
for j, tradeDef in ipairs(tsResource.items) do
if tradeDef.itemID == item.id then
found = true
local levelReq = nil
if tradeDef.unlockRequirements ~= nil then
for k, req in ipairs(tradeDef.unlockRequirements) do
if req.type == 'SkillLevel' and req.skillID == 'melvorD:Township' then
levelReq = req.level
break
end
end
if levelReq == nil then
table.insert(lineArray, Icons.Icon({SkillData.Township.name, type='skill'}))
else
table.insert(lineArray, Icons._SkillReq(SkillData.Township.name, levelReq))
end
end
end
if found then
break
end
end
if found then
break
end
end
-- Archaeology sources
-- Digsites
for i, digsite in ipairs(SkillData.Archaeology.digSites) do
local found = false
for artefactType, artefactItems in pairs(digsite.artefacts) do
for j, itemDef in ipairs(artefactItems) do
if itemDef.itemID == item.id then
table.insert(lineArray, Icons._SkillReq(SkillData.Archaeology.name, digsite.level))
found = true
break
end
end
if found then
break
end
end
if found then
break
end
end
-- Museum rewards
for i, museumReward in ipairs(SkillData.Archaeology.museumRewards) do
if type(museumReward.items) == 'table' and Shared.contains(museumReward.items, item.id) then
table.insert(lineArray, Icons.Icon('Museum'))
break
end
end
-- Cartography
-- Paper
for i, recipe in ipairs(SkillData.Cartography.paperRecipes) do
if recipe.productId == item.id then
table.insert(lineArray, Icons.Icon({SkillData.Cartography.name, type='skill'}))
break
end
end
-- POI discovery rewards
for i, worldMap in ipairs(SkillData.Cartography.worldMaps) do
local found = false
for j, poi in ipairs(worldMap.pointsOfInterest) do
if type(poi.discoveryRewards) == 'table' and type(poi.discoveryRewards.items) == 'table' then
for k, itemDef in ipairs(poi.discoveryRewards.items) do
if itemDef.id == item.id then
-- Find level for POI hex
local level = 1
local poiHex = nil
local skillID = SkillData.Cartography.skillID
for m, hex in ipairs(worldMap.hexes) do
if hex.coordinates.q == poi.coords.q and hex.coordinates.r == poi.coords.r then
for n, req in ipairs(hex.requirements) do
if req.type == 'SkillLevel' and req.skillID == skillID then
level = req.level
break
end
end
break
end
end
table.insert(lineArray, Icons._SkillReq(SkillData.Cartography.name, level))
found = true
break
end
end
if found then
break
end
end
end
if found then
break
end
end
-- Travel events
for i, event in ipairs(SkillData.Cartography.travelEvents) do
local found = false
if type(event.rewards) == 'table' and type(event.rewards.items) == 'table' then
for j, itemDef in ipairs(event.rewards.items) do
if itemDef.id == item.id and itemDef.quantity > 0 then
table.insert(lineArray, Icons.Icon({SkillData.Cartography.name, type='skill'}))
found = true
break
end
end
if found then
break
break
end
end
Line 460: Line 604:
end
end


-- Woodcutting: Nests
-- Woodcutting
-- TODO Ash
-- Raven Nest
if item.id == SkillData.Woodcutting.nestItemID then
if item.id == SkillData.Woodcutting.ravenNestItemID then
table.insert(lineArray, Icons._SkillReq(SkillData.Woodcutting.name, 1))
elseif item.id == SkillData.Woodcutting.ravenNestItemID then
local levelReq = nil
local levelReq = nil
for i, tree in ipairs(SkillData.Woodcutting.trees) do
for i, tree in ipairs(SkillData.Woodcutting.trees) do
Line 472: Line 614:
end
end
table.insert(lineArray, Icons._SkillReq(SkillData.Woodcutting.name, levelReq))
table.insert(lineArray, Icons._SkillReq(SkillData.Woodcutting.name, levelReq))
-- Bird Nest, Ash, and Mushroom
elseif Shared.contains({
SkillData.Woodcutting.nestItemID,
SkillData.Woodcutting.ashItemID,
SkillData.Woodcutting.mushroomItemID
}, item.id) then
table.insert(lineArray, Icons._SkillReq(SkillData.Woodcutting.name, 1))
end
end


-- Fishing: Junk & Specials
-- Fishing
-- Junk
if Shared.contains(SkillData.Fishing.junkItemIDs, item.id) then
if Shared.contains(SkillData.Fishing.junkItemIDs, item.id) then
table.insert(lineArray, Icons.Icon({'Fishing', type='skill', notext=true}) .. ' [[Fishing#Junk|Junk]]')
table.insert(lineArray, Icons.Icon({'Fishing', type='skill', notext=true}) .. ' [[Fishing#Junk|Junk]]')
-- Specials
elseif GameData.getEntityByProperty(SkillData.Fishing.specialItems, 'itemID', item.id) ~= nil then
elseif GameData.getEntityByProperty(SkillData.Fishing.specialItems, 'itemID', item.id) ~= nil then
table.insert(lineArray, Icons.Icon({'Fishing', type='skill', notext=true}) .. ' [[Fishing#Special|Special]]')
table.insert(lineArray, Icons.Icon({'Fishing', type='skill', notext=true}) .. ' [[Fishing#Special|Special]]')
elseif item.id == SkillData.Fishing.lostChestItem then
table.insert(lineArray, Icons._SkillReq(SkillData.Fishing.name, 100))
end
end


-- Firemaking: Coal
-- Firemaking: Coal
-- TODO Ash, Charcoal, Diamonds, Fire spirits
if Shared.contains({SkillData.Firemaking.coalItemID,
if item.id == SkillData.Firemaking.coalItemID then
SkillData.Firemaking.ashItemID,
table.insert(lineArray, Icons._SkillReq("Firemaking", 1))
SkillData.Firemaking.charcoalItemID,
SkillData.Firemaking.fireSpiritItemID,
SkillData.Firemaking.diamondItemID
}, item.id) then
table.insert(lineArray, Icons._SkillReq(SkillData.Firemaking.name, 1))
end
end


Line 491: Line 648:
GameData.getEntityByProperty('randomSuperiorGems', 'itemID', item.id) ~= nil) then
GameData.getEntityByProperty('randomSuperiorGems', 'itemID', item.id) ~= nil) then
table.insert(lineArray, Icons.Icon({"Mining", type='skill', notext=true})..' [[Mining#Gems|Gem]]')
table.insert(lineArray, Icons.Icon({"Mining", type='skill', notext=true})..' [[Mining#Gems|Gem]]')
elseif item.id == SkillData.Mining.runestoneItemID then
-- From pure essence mining
local recipe = GameData.getEntityByID(SkillData.Mining.rockData, 'melvorTotH:Pure_Essence')
if recipe ~= nil then
table.insert(lineArray, Icons._SkillReq(SkillData.Mining.name, recipe.level))
end
end
end


-- Alt. Magic
-- General rare drops for non-combat skills
if not Shared.tableIsEmpty(Magic.getSpellsProducingItem(item.id)) then
-- Includes items like Circlet/Jewel of Rhaelyx, Mysterious stones, Signet ring half (a),
table.insert(lineArray, Icons.Icon({"Alt. Magic", type='skill'}))
-- relics (for Ancient Relics mode)
end
local skillIconList, subText = {}, ''
 
for i, skillDataAll in ipairs(GameData.rawData.skillData) do
--Finally there are some weird exceptions:
local skillData = skillDataAll.data
--Rhaelyx pieces
local skillName, displaySkillName = skillData.name, false
if Shared.contains({'Circlet of Rhaelyx', 'Jewel of Rhaelyx', 'Mysterious Stone'}, item.name) then
-- All general rare drops within the Magic are for Alt. Magic
local rhaSkills = {
if skillDataAll.skillID == 'melvorD:Magic' then
Circlet = {'Woodcutting', 'Fishing', 'Mining', 'Thieving', 'Farming', 'Agility', 'Astrology'},
skillName, displaySkillName = 'Alt. Magic', true
Jewel = {'Firemaking', 'Cooking', 'Smithing', 'Fletching', 'Crafting', 'Runecrafting', 'Herblore', 'Summoning'}
}
local rhaSkList, subText = nil, ''
if item.name == 'Circlet of Rhaelyx' then
rhaSkList = {rhaSkills.Circlet}
elseif item.name == 'Jewel of Rhaelyx' then
rhaSkList = {rhaSkills.Jewel}
elseif item.name == 'Mysterious Stone' then
rhaSkList = {rhaSkills.Jewel, rhaSkills.Circlet}
subText = '<br/>after finding ' .. Icons.Icon({'Crown of Rhaelyx', type='item'})
end
end
 
if type(skillData.rareDrops) == 'table' then
local rhaStrPart = {}
for j, rareDrop in ipairs(skillData.rareDrops) do
for i, skillList in ipairs(rhaSkList) do
local isAltItem = (rareDrop.altItemID ~= nil and rareDrop.altItemID == item.id)
for j, skillName in ipairs(skillList) do
if isAltItem or rareDrop.itemID == item.id then
table.insert(rhaStrPart, Icons.Icon({skillName, type='skill', notext=true}))
if Shared.tableIsEmpty(skillIconList) then
-- Initialize subText
if isAltItem then
local wornItem = Items.getItemByID(rareDrop.itemID)
subText = ' while wearing ' .. Icons.Icon({wornItem.name, type='item'})
elseif rareDrop.altItemID ~= nil then
-- There exists an alt item, but we are not searching for it
local altItem = Items.getItemByID(rareDrop.altItemID)
subText = ' if not worn (Instead of ' .. Icons.Icon({altItem.name, type='item'}) .. ')'
elseif rareDrop.itemID == 'melvorD:Mysterious_Stone' then
local foundItem = Items.getItemByID('melvorD:Crown_of_Rhaelyx')
subText = '<br/>after finding ' .. Icons.Icon({foundItem.name, type='item'})
end
if type(rareDrop.gamemodes) == 'table' then
local gamemodeText = {}
for k, gamemodeID in ipairs(rareDrop.gamemodes) do
local gamemode = GameData.getEntityByID('gamemodes', gamemodeID)
if gamemode ~= nil then
table.insert(gamemodeText, gamemode.name)
end
end
if not Shared.tableIsEmpty(gamemodeText) then
subText = subText .. ' (' .. table.concat(gamemodeText, ', ') .. ' only)'
end
end
end
local skillText = Icons.Icon({skillName, type='skill', notext=true})
if displaySkillName then
skillText = skillText .. ' (' .. Icons.Icon({skillName, type='skill', noicon=true}) .. ')'
end
table.insert(skillIconList, skillText)
end
end
end
end
end
table.insert(lineArray, 'Any action in: ' .. table.concat(rhaStrPart, ', ') .. subText)
end
if not Shared.tableIsEmpty(skillIconList) then
table.insert(lineArray, 'Any action in: ' .. table.concat(skillIconList, ', ') .. subText)
skillIconList, subText = {}, ''
end
 
-- Supplementary stuff on top of general rare drops
if item.id == 'melvorD:Gold_Topaz_Ring' then
table.insert(lineArray, 'Killing any monster if not worn (Instead of '..Icons.Icon({"Signet Ring Half (b)", type="item"})..')')
elseif item.id == 'melvorD:Signet_Ring_Half_B' then
table.insert(lineArray, 'Killing any monster while wearing '..Icons.Icon({'Gold Topaz Ring', type='item'}))
elseif item.id == 'melvorTotH:Deadly_Toxins_Potion' then
--Adding a special override for Deadly Toxins potions
table.insert(lineArray, 'Brewing [[Lethal Toxins Potion]]s while wearing '..Icons.Icon({'Toxic Maker Gloves', type='item'}))
end
end


Line 553: Line 750:
end
end


--Gold Topaz Ring drops from any action (when not wearing a Gold Topaz Ring)
-- Township Task reward
--Also handling Signet Ring things here
for _, task in ipairs(SkillData.Township.tasks) do
if item.id == 'melvorD:Gold_Topaz_Ring' then
if task.rewards.items[1] ~= nil then -- Skip tasks with no items
table.insert(lineArray, 'Any non-combat action if not worn (Instead of '..Icons.Icon({"Signet Ring Half (a)", type="item"})..')')
if GameData.getEntityByID(task.rewards.items, item.id) then
table.insert(lineArray, 'Killing any monster if not worn (Instead of '..Icons.Icon({"Signet Ring Half (b)", type="item"})..')')
table.insert(lineArray, Icons.Icon({'Tasks', type='township'}))
elseif item.id == 'melvorD:Signet_Ring_Half_A' then
break
table.insert(lineArray, 'Any non-combat action while wearing '..Icons.Icon({'Gold Topaz Ring', type='item'}))
end
elseif item.id == 'melvorD:Signet_Ring_Half_B' then
end
table.insert(lineArray, 'Killing any monster while wearing '..Icons.Icon({'Gold Topaz Ring', type='item'}))
end
end


Line 584: Line 780:
end
end
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


Line 594: Line 790:
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '{| class="wikitable sortable stickyHeader"')
table.insert(resultPart, '\r\n|- class="headerRow-0"')
table.insert(resultPart, '\r\n|- class="headerRow-0"')
table.insert(resultPart, '\r\n!Source!!Source Type!!Quantity!!colspan="2"|Chance')
table.insert(resultPart, '\r\n!Source!!Level!!Quantity!!colspan="2"|Chance')


--Set up function for adding rows
--Set up function for adding rows
local buildRow = function(source, type, minqty, qty, weight, totalWeight)
local buildRow = function(source, level, levelNum, minqty, qty, weight, totalWeight, expIcon)
if minqty == nil then minqty = 1 end
if minqty == nil then minqty = 1 end
if expIcon == nil then expIcon = '' end
if level == nil then level = 'N/A' end
local rowPart = {}
local rowPart = {}
table.insert(rowPart, '\r\n|-')
table.insert(rowPart, '\r\n|-')
table.insert(rowPart, '\r\n|style="text-align: left;"|'..source)
table.insert(rowPart, '\r\n|style="text-align: left;"|'..source)
table.insert(rowPart, '\r\n|style="text-align: left;"|'..type)
-- Retrieve numeric level value for sorting, or remove anything between [[]]
 
local levelValue = ''
if levelNum ~= nil then
levelValue = tostring(levelNum)
else
levelValue = level:match('%[%[.-%]%]%s*(%w+)$') or ''
end
table.insert(rowPart, '\r\n|style="text-align: left;" data-sort-value="'..levelValue..'"|'..expIcon.. level)
table.insert(rowPart, '\r\n|style="text-align: right;" data-sort-value="'..qty..'"|'..Shared.formatnum(minqty))
table.insert(rowPart, '\r\n|style="text-align: right;" data-sort-value="'..qty..'"|'..Shared.formatnum(minqty))
if qty ~= minqty then table.insert(rowPart, ' - '..Shared.formatnum(qty)) end
if qty ~= minqty then table.insert(rowPart, ' - '..Shared.formatnum(qty)) end
Line 638: Line 842:
for i, drop in ipairs(p._getItemMonsterSources(item)) do
for i, drop in ipairs(p._getItemMonsterSources(item)) do
local monster = GameData.getEntityByID('monsters', drop.id)
local monster = GameData.getEntityByID('monsters', drop.id)
local iconName = monster.name
if SourceOverrides[drop.id] ~= nil then
iconName = SourceOverrides[drop.id]
end
if monster ~= nil then
if monster ~= nil then
table.insert(dropRows, {source = Icons.Icon({monster.name, type='monster'}), type = '[[Monster]]', minqty = drop.minQty, qty = drop.maxQty, weight = drop.dropWt, totalWeight = drop.totalWt})
local monsterLevel = Monsters._getMonsterCombatLevel(monster)
table.insert(dropRows, {
source = Icons.Icon({iconName, type='monster'}),
level = Icons.Icon({'Monsters', img='Combat', notext=true}) .. ' Level ' .. Shared.formatnum(monsterLevel),
levelNum = monsterLevel,
minqty = drop.minQty,
qty = drop.maxQty,
weight = drop.dropWt,
totalWeight = drop.totalWt,
expIcon = Icons.getExpansionIcon(drop.id)})
end
end
--Patching in here because it uses the same format
--Can we find this in an Archaeology digsite?
for i, drop in ipairs(p._getItemArchSources(item)) do
if drop.name ~= nil then
table.insert(dropRows, {
source = Icons.Icon({drop.name, type='poi'}),  
level = Icons._SkillReq('Archaeology', drop.level) .. ' ('..drop.size..')',
levelNum = drop.level,
minqty = drop.minQty,  
qty = drop.maxQty,  
weight = drop.dropWt,  
totalWeight = drop.totalWt,
expIcon = Icons.getExpansionIcon(drop.id)})
end
end
end
end
Line 647: Line 881:
if (dungeon.oneTimeRewardID ~= nil and item.id == dungeon.oneTimeRewardID) or
if (dungeon.oneTimeRewardID ~= nil and item.id == dungeon.oneTimeRewardID) or
(type(dungeon.rewardItemIDs) == 'table' and Shared.contains(dungeon.rewardItemIDs, item.id)) then
(type(dungeon.rewardItemIDs) == 'table' and Shared.contains(dungeon.rewardItemIDs, item.id)) then
table.insert(dropRows, {source = Icons.Icon({dungeon.name, type='dungeon'}), type = '[[Dungeon]]', minqty = 1, qty = 1, weight = 1, totalWeight = 1})
table.insert(dropRows, {
source = Icons.Icon({dungeon.name, type='dungeon'}),  
level = '[[Dungeon]]',
minqty = 1,  
qty = 1,  
weight = 1,  
totalWeight = 1,
expIcon = Icons.getExpansionIcon(dungeon.id)})
elseif dungeon.eventID ~= nil then
elseif dungeon.eventID ~= nil then
-- Is the item dropped from a combat event (e.g. Impending Darkness event)?
-- Is the item dropped from a combat event (e.g. Impending Darkness event)?
Line 655: Line 896:
if item.id == itemRewardID then
if item.id == itemRewardID then
local sourceTxt = Icons.Icon({dungeon.name, type='dungeon'}) .. (eventCycle == Shared.tableCount(event.itemRewardIDs) and '' or ', Cycle ' .. eventCycle)
local sourceTxt = Icons.Icon({dungeon.name, type='dungeon'}) .. (eventCycle == Shared.tableCount(event.itemRewardIDs) and '' or ', Cycle ' .. eventCycle)
table.insert(dropRows, {source = sourceTxt, type = '[[Dungeon]]', minqty = 1, qty = 1, weight = 1, totalWeight = 1})
table.insert(dropRows, {
source = sourceTxt,  
level = '[[Dungeon]]',
minqty = 1,  
qty = 1,  
weight = 1,  
totalWeight = 1})
break
break
end
end
Line 678: Line 925:
if wt > 0 then
if wt > 0 then
local sourceTxt = Icons.Icon({item2.name, type='item'})
local sourceTxt = Icons.Icon({item2.name, type='item'})
table.insert(dropRows, {source = sourceTxt, type = '[[Chest]]', minqty = minQty, qty = maxQty, weight = wt, totalWeight = totalWt})
table.insert(dropRows, {
source = sourceTxt,  
level = '[[Chest]]',
minqty = minQty,  
qty = maxQty,  
weight = wt,  
totalWeight = totalWt,
expIcon = Icons.getExpansionIcon(item2.id)})
end
end
end
end
Line 692: Line 946:
sourceTxt = Icons.Icon({thiefRow.npc, type='thieving'})
sourceTxt = Icons.Icon({thiefRow.npc, type='thieving'})
end
end
table.insert(dropRows, {source = sourceTxt, type = Icons.Icon({SkillData.Thieving.name, type='skill'}), minqty = thiefRow.minQty, qty = thiefRow.maxQty, weight = thiefRow.wt, totalWeight = thiefRow.totalWt})
table.insert(dropRows, {
source = sourceTxt,  
level = Icons._SkillReq("Thieving", thiefRow.level),
levelNum = thiefRow.level,
minqty = thiefRow.minQty,  
qty = thiefRow.maxQty,  
weight = thiefRow.wt,  
totalWeight = thiefRow.totalWt,
expIcon = Icons.getExpansionIcon(thiefRow.npcID)})
end
end


Line 700: Line 962:
local fishType = Icons.Icon({'Fishing', type='skill'})
local fishType = Icons.Icon({'Fishing', type='skill'})
local fishTotWeight = Shared.tableCount(SkillData.Fishing.JunkItems)
local fishTotWeight = Shared.tableCount(SkillData.Fishing.JunkItems)
table.insert(dropRows, {source = fishSource, type = fishType, minqty = 1, qty = 1, weight = 1, totalWeight = fishTotWeight})
table.insert(dropRows, {
source = fishSource,  
level = Icons._SkillReq("Fishing", 1),
levelNum = 1,
minqty = 1,  
qty = 1,  
weight = 1,  
totalWeight = fishTotWeight})
else
else
local fishTotWeight, fishItem = 0, nil
local fishTotWeight, fishItem = 0, nil
Line 712: Line 981:
local fishSource = '[[Fishing#Special|Special]]'
local fishSource = '[[Fishing#Special|Special]]'
local fishType = Icons.Icon({SkillData.Fishing.name, type='skill'})
local fishType = Icons.Icon({SkillData.Fishing.name, type='skill'})
table.insert(dropRows, {source = fishSource, type = fishType, minqty = fishItem.minQuantity, qty = fishItem.maxQuantity, weight = fishItem.weight, totalWeight = fishTotWeight})
table.insert(dropRows, {
source = fishSource,  
level = Icons._SkillReq("Fishing", 1),
levelNum = 1,
minqty = fishItem.minQuantity,  
qty = fishItem.maxQuantity,  
weight = fishItem.weight,  
totalWeight = fishTotWeight})
end
end
end
end
Line 728: Line 1,004:
end
end
if thisGem ~= nil then
if thisGem ~= nil then
local mineType = Icons.Icon({SkillData.Mining.name, type='skill'})
local expIcon = ''
table.insert(dropRows, {source = '[[Mining#Gems|Gem]]', type = mineType, minqty = thisGem.minQuantity, qty = thisGem.maxQuantity, weight = thisGem.weight, totalWeight = totalGemWeight})
local sourceTxt
local lv = nil
if item.type == 'Superior Gem' then
expIcon = Icons.TotH()
sourceTxt = '[[Mining#Superior Gems|Superior Gem]]'
-- Superior gems can only be found with Mining 100 or above
lv = 100
else
sourceTxt = '[[Mining#Gems|Gem]]'
-- Gems can only be found with any Mining level
lv = 1
end
table.insert(dropRows, {
source = sourceTxt,
level = Icons._SkillReq('Mining', lv),
levelNum = lv,
minqty = thisGem.minQuantity,  
qty = thisGem.maxQuantity,  
weight = thisGem.weight,  
totalWeight = totalGemWeight,
expIcon = expIcon})
-- Check for Alt. Magic spells also
-- Check for Alt. Magic spells also
local magicType = Icons.Icon({SkillData.Magic.name, type = 'skill'})
local producesKey = (gemKey == 'randomGems' and 'RandomGem') or 'RandomSuperiorGem'
local producesKey = (gemKey == 'randomGems' and 'RandomGem') or 'RandomSuperiorGem'
for j, spell in ipairs(Magic.getSpellsBySpellBook('altMagic')) do
for j, spell in ipairs(Magic.getSpellsBySpellBook('altMagic')) do
if spell.produces ~= nil and spell.produces == producesKey then
if spell.produces ~= nil and spell.produces == producesKey then
table.insert(dropRows, {source = Icons.Icon({spell.name, type=Magic._getSpellIconType(spell)}), type = magicType, minqty = thisGem.minQuantity, qty = thisGem.maxQuantity, weight = thisGem.weight, totalWeight = totalGemWeight})
table.insert(dropRows, {
source = Icons.Icon({spell.name, type=Magic._getSpellIconType(spell)}),
level = Icons.Icon({'Alternative Magic', type='skill', img='Magic', notext=true}) .. ' Level ' .. spell.level,
levelNum = spell.level,
minqty = thisGem.minQuantity,  
qty = thisGem.maxQuantity,
weight = thisGem.weight,  
totalWeight = totalGemWeight,
expIcon = Icons.getExpansionIcon(spell.id)})
end
end
end
end
Line 749: Line 1,052:
if a.weight / a.totalWeight == b.weight / b.totalWeight then
if a.weight / a.totalWeight == b.weight / b.totalWeight then
if a.minqty + a.qty == b.minqty + b.qty then
if a.minqty + a.qty == b.minqty + b.qty then
return (a.type == b.type and a.source < b.source) or a.type < b.type
return (a.level == b.level and a.source < b.source) or a.level < b.level
else
else
return a.minqty + a.qty > b.minqty + b.qty
return a.minqty + a.qty > b.minqty + b.qty
Line 758: Line 1,061:
end)
end)
for i, data in ipairs(dropRows) do
for i, data in ipairs(dropRows) do
table.insert(resultPart, buildRow(data.source, data.type, data.minqty, data.qty, data.weight, data.totalWeight))
table.insert(resultPart, buildRow(data.source, data.level, data.levelNum, data.minqty, data.qty, data.weight, data.totalWeight, data.expIcon))
end
end


Line 769: Line 1,072:
local item = Items.getItem(itemName)
local item = Items.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


Line 804: Line 1,107:
local item = Items.getItem(itemName)
local item = Items.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


Line 822: Line 1,125:
local smithRecipe = p._getSuperheatSmithRecipe(item)
local smithRecipe = p._getSuperheatSmithRecipe(item)
if smithRecipe == nil then
if smithRecipe == nil then
return 'ERROR: The item "' .. item.name .. '" cannot be superheated[[Category:Pages with script errors]]'
return Shared.printError('The item "' .. item.name .. '" cannot be superheated')
end
end


Line 861: Line 1,164:
end
end


--Add the table end and add the table to the result string
--Add the table end and add the table to the result string
table.insert(superheatTable, '\r\n|}')
table.insert(superheatTable, '\r\n|}')
return table.concat(superheatTable)
return table.concat(superheatTable)
Line 870: Line 1,173:
local item = Items.getItem(itemName)
local item = Items.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


return p._getItemSuperheatTable(item)
return p._getItemSuperheatTable(item)
end
function p._getTownshipTraderTable(item)
for i, tsResource in ipairs(SkillData.Township.itemConversions.fromTownship) do
for j, tradeDef in ipairs(tsResource.items) do
if tradeDef.itemID == item.id then
-- Item found, build table
local res = GameData.getEntityByID(SkillData.Township.resources, tsResource.resourceID)
local resName = (res ~= nil and res.name) or 'Unknown'
local resQty = math.max(item.sellsFor, 2)
local resultPart = {}
table.insert(resultPart, '{| class="wikitable"\n|-')
table.insert(resultPart, '\n!colspan="2"| ' .. Icons.Icon({'Township', 'Trader', type='skill'}))
table.insert(resultPart, '\n|-\n!style="text-align:right;"| Cost')
table.insert(resultPart, '\n| ' .. Icons.Icon({resName, qty=resQty, type='resource'}))
table.insert(resultPart, '\n|-\n!style="text-align:right;| Requirements')
table.insert(resultPart, '\n| ' .. Shop.getRequirementString(tradeDef.unlockRequirements))
table.insert(resultPart, '\n|}')
return table.concat(resultPart)
end
end
end
return ''
end
end


Line 894: Line 1,222:
if creationTable ~= '' then table.insert(resultPart, '===Creation===\r\n') end
if creationTable ~= '' then table.insert(resultPart, '===Creation===\r\n') end
table.insert(resultPart, upgradeTable)
table.insert(resultPart, upgradeTable)
end
local townshipTable = p._getTownshipTraderTable(item)
if townshipTable ~= '' then
if not Shared.tableIsEmpty(resultPart) then table.insert(resultPart, '\n') end
table.insert(resultPart, '===Township===\n' .. townshipTable)
end
end


Line 912: Line 1,246:
local item = Items.getItem(itemName)
local item = Items.getItem(itemName)
if item == nil then
if item == nil then
return "ERROR: No item named "..itemName.." exists in the data module[[Category:Pages with script errors]]"
return Shared.printError('No item named "' .. itemName .. '" exists in the data module')
end
end


Line 945: Line 1,279:
local minQty = 1
local minQty = 1
local maxQty = 1
local maxQty = 1
if monster.bones == item.id and Monsters._getMonsterBones(monster) ~= nil then
if monster.bones ~= nil and monster.bones.itemID == item.id and Monsters._getMonsterBones(monster) ~= nil then
-- Item is a bone, and is either a shard from God dungeons or dropped by a non-boss monster with a loot table
-- Item is a bone, and is either a shard from God dungeons or dropped by a non-boss monster with a loot table
maxQty = (monster.bones.quantity ~= nil and monster.bones.quantity) or 1
maxQty = (monster.bones.quantity ~= nil and monster.bones.quantity) or 1
Line 951: Line 1,285:
chance = 1
chance = 1
weight = 1
weight = 1
elseif monster.barrierPercent ~= nil and 'melvorAoD:Barrier_Dust' == item.id and not Monsters._isDungeonOnlyMonster(monster) then
-- Item is Barrier Dust and is not a dungeon exclusive monster
maxQty = math.max(math.floor(Monsters._getMonsterStat(monster, 'Barrier') / 10 / 20), 1)
minQty = maxQty
chance = 1
elseif monster.lootTable ~= nil and not Monsters._isDungeonOnlyMonster(monster) then
elseif monster.lootTable ~= nil and not Monsters._isDungeonOnlyMonster(monster) then
-- If the monster has a loot table, check if the item we are looking for is in there
-- If the monster has a loot table, check if the item we are looking for is in there
Line 964: Line 1,303:
end
end
end
end
local lootChance = monster.lootChance ~= nil and monster.bones ~= item.id and monster.lootChance or 100
local lootChance = monster.lootChance ~= nil and (monster.bones == nil or monster.bones.itemID ~= item.id) and monster.lootChance or 100
chance = chance * lootChance
chance = chance * lootChance
weight = weight * 100
weight = weight * 100
Line 980: Line 1,319:
local item = Items.getItem(itemName)
local item = Items.getItem(itemName)
return p._getItemMonsterSources(item)
return p._getItemMonsterSources(item)
end
function p._getItemArchSources(item)
local check = false
local itemID = item.id
local resultArray = {}
for i, digSite in pairs(SkillData.Archaeology.digSites) do
for sizeName, size in pairs(digSite.artefacts) do
local found = nil
local sizeWeight = 0
for k, artefact in pairs(size) do
sizeWeight = sizeWeight + artefact.weight
if artefact.itemID == itemID then
found = artefact
end
end
if found ~= nil then
local min = found.minQuantity
local max = found.maxQuantity
table.insert(resultArray, {
id = digSite.id,
name = digSite.name,
level = digSite.level,
size = sizeName,
minQty = min,
maxQty = max,
dropWt = found.weight,
totalWt = sizeWeight})
end
end
end
return resultArray
end
function p.getItemArchSources(itemName)
local item = Items.getItem(itemName)
return p._getItemArchSources(item)
end
end


Line 987: Line 1,367:
function p.test()
function p.test()
local checkItems = {
local checkItems = {
'Gold Bar',
"Circlet of Rhaelyx",
'Raw Shrimp',
"Jewel of Rhaelyx",
'Coal Ore',
"Signet Ring Half (a)",
'Rune Platebody',
"Signet Ring Half (b)",
'Arrow Shafts',
"Gold Topaz Ring",
'Yew Longbow',
"Astrology Lesser Relic",
'Water Rune',
"Mysterious Stone",
'Steam Rune',
"Gold Bar",
'Controlled Heat Potion II',
"Raw Shrimp",
'Wolf',
"Coal Ore",
'Cyclops',
"Rune Platebody",
'Leprechaun',
"Arrow Shafts",
'Redwood Logs',
"Yew Longbow",
'Carrot Cake',
"Water Rune",
'Carrot Cake (Perfect)',
"Steam Rune",
'Mantalyme Herb',
"Controlled Heat Potion II",
'Carrot',
"Wolf",
'Topaz',
"Cyclops",
'Rune Essence',
"Leprechaun",
'Sanguine Blade',
"Redwood Logs",
'Ring of Power',
"Carrot Cake",
'Infernal Claw',
"Carrot Cake (Perfect)",
'Chapeau Noir',
"Mantalyme Herb",
'Stardust',
"Carrot",
'Rope',
"Topaz",
'Ancient Ring of Mastery',
"Rune Essence",
'Mysterious Stone',
"Sanguine Blade",
'Mastery Token (Cooking)',
"Ring of Power",
'Gem Gloves',
"Infernal Claw",
"Thief's Moneysack"
"Chapeau Noir",
"Stardust",
"Rope",
"Ancient Ring of Mastery",
"Mastery Token (Cooking)",
"Gem Gloves",
"Thief's Moneysack",
"Golden Stardust",
"Golden Star",
"Slayer Deterer",
"Paper",
"Lemon",
"Aranite Brush",
"Barrier Dust"
}
}
local checkFuncs = {
local checkFuncs = {
913

edits