17,097
edits
m (Remove redundant item source overrides) |
(_getItemSources/_getItemLootSourceTable: Refactor monster drops code) |
||
Line 19: | Line 19: | ||
local sourceOverrides = { | local sourceOverrides = { | ||
['Dungeon'] = { | ['Dungeon'] = { | ||
[361] = 'Volcanic Cave', -- Fire Cape | |||
[941] = 'Infernal Stronghold', -- Infernal Cape | |||
[950] = 'Volcanic Cave', -- A Tale of the Past, a future's prophecy | [950] = 'Volcanic Cave', -- A Tale of the Past, a future's prophecy | ||
[951] = 'Fire God Dungeon', -- The First Hero and an Unknown Evil | [951] = 'Fire God Dungeon', -- The First Hero and an Unknown Evil | ||
Line 149: | Line 151: | ||
break | break | ||
end | end | ||
--If this is a perfect item, need to find the original | --If this is a perfect item, need to find the original | ||
if item2.perfectItem == item.id and item2.recipeRequirements ~= nil then | if item2.perfectItem == item.id and item2.recipeRequirements ~= nil then | ||
Line 321: | Line 323: | ||
--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... | ||
--First up: Can we kill somebody and take theirs? | --First up: Can we kill somebody and take theirs? | ||
local | local killStrPart = {} | ||
local | local dungeonStrPart = {} | ||
for i, monster in ipairs(MonsterData.Monsters) do | |||
for i, monster in | local isDrop = false | ||
if monster.bones == item.id and ((monster.lootTable ~= nil and not monster.isBoss) or Shared.contains(item.name, 'Shard')) then | |||
-- 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.lootTable ~= nil then | |||
-- If the monster has a loot table, check if the item we are looking for is in there | |||
for j, loot in ipairs(monster.lootTable) do | |||
if loot[1] == item.id then | |||
isDrop = true | |||
break | |||
end | |||
end | end | ||
end | end | ||
if isDrop then | |||
if not Shared.contains(item.name, 'Shard') and Monsters._isDungeonOnlyMonster(monster) then | |||
-- For dungeon exclusive monsters, loot is only rolled when they are the last | |||
-- monster within that dungeon (unless it is a shard) | |||
if monster.isBoss then | |||
local areaList = Areas.getMonsterAreas(monster.id) | |||
for k, area in ipairs(areaList) do | |||
if area.type == 'dungeon' and area.monsters[#area.monsters] == monster.id then | |||
table.insert(dungeonStrPart, Icons.Icon({area.name, type='dungeon', notext=true})) | |||
end | |||
end | |||
end | |||
else | |||
-- Item is not an end of dungeon reward, and drops when the monster is killed | |||
table.insert(killStrPart, Icons.Icon({monster.name, type='monster', notext=true})) | |||
end | |||
end | |||
end | end | ||
-- Is the item dropped from a cycle of the Impending Darkness event? | -- Is the item dropped from a cycle of the Impending Darkness event? | ||
for i, eventItemID in ipairs(Areas.eventData.rewards) do | for i, eventItemID in ipairs(Areas.eventData.rewards) do | ||
if item.id == eventItemID then | |||
local dungPrefix = (i == Shared.tableCount(Areas.eventData.rewards) and '' or i .. ' ' .. (i == 1 and 'cycle' or 'cycles') .. ' of ') | |||
table.insert(dungeonStrPart, dungPrefix .. Icons.Icon({'Impending Darkness Event', type='dungeon', notext=true})) | |||
break | |||
end | |||
end | end | ||
-- Special exceptions for Fire/Infernal Cape and first two lore books | -- Special exceptions for Fire/Infernal Cape and first two lore books | ||
if sourceOverrides['Dungeon'][item.id] ~= nil then | if sourceOverrides['Dungeon'][item.id] ~= nil then | ||
table.insert(dungeonStrPart, Icons.Icon({sourceOverrides['Dungeon'][item.id], type='dungeon', notext=true})) | |||
end | end | ||
if | if Shared.tableCount(dungeonStrPart) > 0 then | ||
if | table.insert(lineArray, 'Completing: ' .. table.concat(dungeonStrPart, ',')) | ||
end | |||
if Shared.tableCount(killStrPart) > 0 then | |||
table.insert(lineArray, 'Killing: ' .. table.concat(killStrPart, ',')) | |||
end | |||
--Next: Can we find it in a box? | --Next: Can we find it in a box? | ||
Line 405: | Line 383: | ||
local cookStr = '' | local cookStr = '' | ||
local growStr = '' | local growStr = '' | ||
local count1 = 0 | |||
local count2 = 0 | local count2 = 0 | ||
for i, item2 in pairs(ItemData.Items) do | for i, item2 in pairs(ItemData.Items) do | ||
if item2.dropTable ~= nil then | if item2.dropTable ~= nil then | ||
Line 473: | Line 451: | ||
table.insert(lineArray, Icons.Icon({"Astrology", type="skill"})) | table.insert(lineArray, Icons.Icon({"Astrology", type="skill"})) | ||
end | end | ||
--SmithCheck: | --SmithCheck: | ||
if item.smithingLevel ~= nil then | if item.smithingLevel ~= nil then | ||
Line 493: | Line 471: | ||
table.insert(lineArray, Icons._SkillReq("Runecrafting", item.runecraftingLevel)) | table.insert(lineArray, Icons._SkillReq("Runecrafting", item.runecraftingLevel)) | ||
end | end | ||
--CookCheck | --CookCheck | ||
if item.cookingLevel ~= nil then | if item.cookingLevel ~= nil then | ||
Line 659: | Line 637: | ||
--Alright, time to go through a few ways to get the item | --Alright, time to go through a few ways to get the item | ||
--First up: Can we kill somebody and take theirs? | --First up: Can we kill somebody and take theirs? | ||
for i, monster in | for i, monster in ipairs(MonsterData.Monsters) do | ||
local minqty = 1 | local minqty = 1 | ||
local qty = 1 | local qty = 1 | ||
Line 666: | Line 644: | ||
--Only add bones if this monster has loot (ie appears outside a dungeon) and isn't a boss | --Only add bones if this monster has loot (ie appears outside a dungeon) and isn't a boss | ||
--... unless we're looking for Shards of course, at which point we'll take any monster with the right bones | --... unless we're looking for Shards of course, at which point we'll take any monster with the right bones | ||
if ((monster.lootTable ~= nil and not monster.isBoss) or Shared.contains(item.name, 'Shard')) | if monster.bones == item.id and ((monster.lootTable ~= nil and not monster.isBoss) or Shared.contains(item.name, 'Shard')) then | ||
qty = monster.boneQty ~= nil and monster.boneQty or 1 | qty = monster.boneQty ~= nil and monster.boneQty or 1 | ||
minqty = qty | minqty = qty | ||
Line 672: | Line 650: | ||
totalWt = 1 | totalWt = 1 | ||
elseif monster.lootTable ~= nil then | elseif monster.lootTable ~= nil then | ||
for j, loot in | -- If the monster has a loot table, check if the item we are looking for is in there | ||
for j, loot in ipairs(monster.lootTable) do | |||
totalWt = totalWt + loot[2] | totalWt = totalWt + loot[2] | ||
if loot[1] == item.id then | if loot[1] == item.id then | ||
Line 682: | Line 661: | ||
local lootChance = monster.lootChance ~= nil and monster.bones ~= item.id and monster.lootChance or 100 | local lootChance = monster.lootChance ~= nil and monster.bones ~= item.id and monster.lootChance or 100 | ||
if wt > 0 and lootChance > 0 then | |||
if not Shared.contains(item.name, 'Shard') and Monsters._isDungeonOnlyMonster(monster) then | |||
-- For dungeon exclusive monsters, loot is only rolled when they are the last | |||
-- monster within that dungeon (unless it is a shard) | |||
if monster.isBoss then | |||
local areaList = Areas.getMonsterAreas(monster.id) | |||
for k, area in ipairs(areaList) do | |||
if area.type == 'dungeon' and area.monsters[#area.monsters] == monster.id then | |||
table.insert(dropRows, {source = Icons.Icon({area.name, type='dungeon'}), type = '[[Dungeon]]', minqty = minqty, qty = qty, weight = wt * lootChance, totalWeight = totalWt * 100}) | |||
end | |||
end | |||
end | |||
else | |||
-- Item is not an end of dungeon reward, and drops when the monster is killed | |||
table.insert(dropRows, {source = Icons.Icon({monster.name, type='monster'}), type = '[[Monster]]', minqty = minqty, qty = qty, weight = wt * lootChance, totalWeight = totalWt * 100}) | |||
end | |||
end | |||
end | end | ||
-- Is the item dropped from a cycle of the Impending Darkness event? | -- Is the item dropped from a cycle of the Impending Darkness event? | ||
for i, eventItemID in ipairs(Areas.eventData.rewards) do | for i, eventItemID in ipairs(Areas.eventData.rewards) do | ||
Line 721: | Line 687: | ||
end | end | ||
end | end | ||
--Special exception for the Fire/Infernal Cape and first two lore books as bonus dungeon drops | --Special exception for the Fire/Infernal Cape and first two lore books as bonus dungeon drops | ||
if sourceOverrides['Dungeon'][item.id] ~= nil then | if sourceOverrides['Dungeon'][item.id] ~= nil then | ||
local sourceTxt = Icons.Icon({sourceOverrides['Dungeon'][item.id], type='dungeon'}) | local sourceTxt = Icons.Icon({sourceOverrides['Dungeon'][item.id], type='dungeon'}) | ||
table.insert(dropRows, {source=sourceTxt, type='[[Dungeon]]', minqty=1, qty=1, weight = 1, totalWeight = 1}) | table.insert(dropRows, {source = sourceTxt, type = '[[Dungeon]]', minqty = 1, qty = 1, weight = 1, totalWeight = 1}) | ||
end | end | ||
Line 966: | Line 931: | ||
table.sort(itemArray, function(a, b) return a.id < b.id end) | table.sort(itemArray, function(a, b) return a.id < b.id end) | ||
for i, item in | for i, item in ipairs(itemArray) do | ||
table.insert(resultPart, '|-\r\n') | table.insert(resultPart, '|-\r\n') | ||
table.insert(resultPart, '! '..Icons.Icon({item.name, type='item', notext='true'})..'\r\n! '..Icons.Icon({item.name, type='item', noicon=true})..'\r\n') | table.insert(resultPart, '! '..Icons.Icon({item.name, type='item', notext='true'})..'\r\n! '..Icons.Icon({item.name, type='item', noicon=true})..'\r\n') |