Module:CombatAreas/AreaTables: Difference between revisions

getDungeonTable: Add Requirements column; getSlayerAreaTable: Additional formatting for Requirements & area effects columns
m (Correct case)
(getDungeonTable: Add Requirements column; getSlayerAreaTable: Additional formatting for Requirements & area effects columns)
 
(12 intermediate revisions by 3 users not shown)
Line 2: Line 2:


local p = {}
local p = {}
local AreaData = mw.loadData('Module:CombatAreas/data')


local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local GameData = require('Module:GameData')
local Icons = require('Module:Icons')
local Icons = require('Module:Icons')
local Items = require('Module:Items')
local Items = require('Module:Items')
local Monsters = require('Module:Monsters')
local Monsters = require('Module:Monsters')
local CombatAreas = require('Module:CombatAreas')
local Pets = require('Module:Pets')
local Pets = require('Module:Pets')
local Areas = require('Module:CombatAreas')


function p.getLowHighLevels(idList)
function p.getLowHighLevels(idList)
local lowLevel = 1000000
local lowLevel = 1000000
local highLevel = 0
local highLevel = 0
for i, monID in Shared.skpairs(idList) do
for i, monID in ipairs(idList) do
local monster = Monsters.getMonsterByID(monID)
local monster = Monsters.getMonsterByID(monID)
local cmbLevel = Monsters._getMonsterCombatLevel(monster)
local cmbLevel = Monsters._getMonsterCombatLevel(monster)
Line 28: Line 27:
local result = '{| class="wikitable sortable stickyHeader"'
local result = '{| class="wikitable sortable stickyHeader"'
result = result..'\r\n|- class="headerRow-0"'
result = result..'\r\n|- class="headerRow-0"'
result = result..'\r\n!colspan="2"|Zone!!Difficulty!!Lowest Monster Level!!Highest Monster Level'
result = result..'\r\n!colspan="2"|Zone!!Difficulty!!Lowest Monster Level!!Highest Monster Level!!Requirements'


for i, areaIdx in ipairs(AreaData.displayOrder.combatAreas) do
local areas = GameData.sortByOrderTable(GameData.rawData.combatAreas, GameData.rawData.combatAreaDisplayOrder)
local area = CombatAreas.getAreaByID('combat', areaIdx)
for i, area in ipairs(areas) do
result = result..'\r\n|-'
result = result..'\r\n|-'
result = result..'\r\n|'..Icons.Icon({area.name, type='combat', size='50', notext=true})
result = result..'\r\n|class="table-img" data-sort-value="' .. area.name .. '"| '..Icons.Icon({area.name, type='combatArea', size='50', notext=true})
result = result..'||'..Icons.Icon({area.name, type='combat', noicon=true})
result = result..'||' .. Icons.getExpansionIcon(area.id) .. Icons.Icon({area.name, type='combatArea', noicon=true})
local diff1 = Constants.getDifficultyString(area.difficulty[1])
result = result..'||data-sort-value="'..area.difficulty[1]..'"|'..Areas._getAreaStat(area, 'difficulty')
local diff2 = Constants.getDifficultyString(area.difficulty[2])
local lowLvl, highLvl = p.getLowHighLevels(area.monsterIDs)
result = result..'||data-sort-value="'..area.difficulty[1]..'"|'..diff1
result = result .. '||data-sort-value="' .. lowLvl .. '"| ' .. Shared.formatnum(lowLvl)
if diff1 ~= diff2 and diff2 ~= nil then result = result..' - '..diff2 end
result = result .. '||data-sort-value="' .. highLvl .. '"| ' .. Shared.formatnum(highLvl)
local lowLvl, highLvl = p.getLowHighLevels(area.monsters)
local reqText = Areas._getAreaRequirements(area)
result = result..'||'..lowLvl..'||'..highLvl
if reqText == nil or reqText == '' then
result = result .. '||class="table-na"| None'
else
result = result .. '||' .. reqText
end
end
end
result = result..'\r\n|}'
result = result..'\r\n|}'
Line 52: Line 55:
result = result..'\r\n!colspan="2"|Zone!!Difficulty!!Highest Monster Level!!Requirements!!Area Effect'
result = result..'\r\n!colspan="2"|Zone!!Difficulty!!Highest Monster Level!!Requirements!!Area Effect'


for i, areaIdx in ipairs(AreaData.displayOrder.slayerAreas) do
local areas = GameData.sortByOrderTable(GameData.rawData.slayerAreas, GameData.rawData.slayerAreaDisplayOrder)
local area = CombatAreas.getAreaByID('slayer', areaIdx)
for i, area in ipairs(areas) do
result = result..'\r\n|-'
result = result..'\r\n|-'
result = result..'\r\n|'..Icons.Icon({area.name, type='slayer', size='50', notext=true})
result = result..'\r\n|class="table-img" data-sort-value="' .. area.name .. '"| '..Icons.Icon({area.name, type='slayer', size='50', notext=true})
result = result..'||'..Icons.Icon({area.name, type='slayer', noicon=true})
result = result..'||' .. Icons.getExpansionIcon(area.id) .. Icons.Icon({area.name, type='slayer', noicon=true})
local diff1 = Constants.getDifficultyString(area.difficulty[1])
result = result..'||data-sort-value="'..area.difficulty[1]..'"|'..Areas._getAreaStat(area, 'difficulty')
local diff2 = Constants.getDifficultyString(area.difficulty[2])
local lowLvl, highLvl = p.getLowHighLevels(area.monsterIDs)
result = result..'||data-sort-value="'..area.difficulty[1]..'"|'..diff1
result = result..'||data-sort-value="' .. highLvl .. '"| ' .. Shared.formatnum(highLvl)
if diff1 ~= diff2 and diff2 ~= nil then result = result..' - '..diff2 end
local reqText = Areas._getAreaRequirements(area)
local lowLvl, highLvl = p.getLowHighLevels(area.monsters)
if reqText == nil or reqText == '' then
result = result..'||'..highLvl
result = result .. '||class="table-na"| None'
result = result..'||'..CombatAreas._getAreaRequirements(area)
else
result = result..'|| '..CombatAreas._getAreaStat(area, 'areaEffectDesc')
result = result .. '||' .. reqText
end
local effectText = Areas._getAreaStat(area, 'areaEffectDesc')
local classText = ((effectText == nil or effectText == 'None') and 'class="table-na"|') or ''
result = result..'||' .. classText .. ' ' .. effectText
end
end


Line 76: Line 83:
asList = true
asList = true
elseif type(asList) == 'string' then
elseif type(asList) == 'string' then
asList = asList.upper ~= 'FALSE'
asList = string.upper(asList) ~= 'FALSE'
end
end


Line 83: Line 90:
-- GP reward
-- GP reward
if area.isEvent == nil or not area.isEvent then
if area.eventID == nil then
local bossMonster = Monsters.getMonsterByID(area.monsters[Shared.tableCount(area.monsters)])
local bossMonster = Monsters.getMonsterByID(area.monsterIDs[Shared.tableCount(area.monsterIDs)])
local gpMin = bossMonster.dropCoins[1]
local gp = bossMonster.gpDrops
local gpMax = bossMonster.dropCoins[2]
if gp.min > 0 and gp.max > 0 then
if gpMin > 0 and gpMax > 0 then
if gp.min == gp.max then
if gpMin == gpMax then
table.insert(rewardList, chr .. Icons.GP(gp.min))
table.insert(rewardList, chr .. Icons.GP(gpMin))
else
else
table.insert(rewardList, chr .. Icons.GP(gpMin, gpMax))
table.insert(rewardList, chr .. Icons.GP(gp.min, gp.max))
end
end
end
end
Line 97: Line 103:
-- Item rewards
-- Item rewards
if type(area.rewards) == 'table' then
local itemLists = {}
for i, rewardID in ipairs(area.rewards) do
if type(area.rewardItemIDs) == 'table' then
table.insert(itemLists, area.rewardItemIDs)
end
if area.eventID ~= nil then
local event = GameData.getEntityByID('combatEvents', area.eventID)
if event ~= nil and type(event.itemRewardIDs) == 'table' then
table.insert(itemLists, event.itemRewardIDs)
end
end
for i, itemList in ipairs(itemLists) do
for j, rewardID in ipairs(itemList) do
local rewardItem = Items.getItemByID(rewardID)
local rewardItem = Items.getItemByID(rewardID)
if rewardItem == nil then
if rewardItem == nil then
table.insert(rewardList, chr .. 'Unknown item (ID ' .. tostring(rewardID) .. ')[[Category:Pages with script errors]]')
table.insert(rewardList, chr .. 'Unknown item (ID ' .. rewardID .. ')[[Category:Pages with script errors]]')
else
else
table.insert(rewardList, chr .. Icons.Icon({rewardItem.name, type='item', qty=1}))
table.insert(rewardList, chr .. Icons.Icon({rewardItem.name, type='item', qty=1}))
end
end
end
end
-- Event (Impending Darkness) rewards
if area.isEvent ~= nil and area.isEvent then
for i, rewardID in ipairs(AreaData.event.rewards) do
local rewardItem = Items.getItemByID(rewardID)
table.insert(rewardList, chr .. Icons.Icon({rewardItem.name, type='item', qty=1}))
end
end
end
end
Line 126: Line 134:
local areaName = frame.args ~= nil and frame.args[1] or frame
local areaName = frame.args ~= nil and frame.args[1] or frame
local asList = frame.args ~= nil and frame.args[2] or true
local asList = frame.args ~= nil and frame.args[2] or true
local area = CombatAreas.getArea(areaName)
local area = Areas.getArea(areaName)
if area == nil then
if area == nil then
return "ERROR: Could not find an area named "..areaName..'[[Category:Pages with script errors]]'
return Shared.printError('Could not find an area named "' .. areaName .. '"')
end
end


Line 134: Line 142:
return p._getDungeonRewards(area, asList)
return p._getDungeonRewards(area, asList)
else
else
return "ERROR: "..areaName.." is not a dungeon[[Category:Pages with script errors]]"
return Shared.printError('"' .. areaName .. '" is not a dungeon')
end
end
end
end
Line 141: Line 149:
local result = '{| class="wikitable sortable stickyHeader"'
local result = '{| class="wikitable sortable stickyHeader"'
result = result..'\r\n|-class="headerRow-0"'
result = result..'\r\n|-class="headerRow-0"'
result = result..'\r\n!colspan="2"|Dungeon!!Difficulty!!Monsters!!Boss Level!!Reward(s)!!Boss Pet'
result = result..'\r\n!colspan="2"|Dungeon!!Difficulty!!Monsters!!Boss Level!!Requirements!!Rewards!!Boss Pet'
 
local areas = GameData.sortByOrderTable(GameData.rawData.dungeons, GameData.rawData.dungeonDisplayOrder)
for i, dung in ipairs(areas) do
local monsterCount = Shared.tableCount(dung.monsterIDs)
local boss = Monsters.getMonsterByID(dung.monsterIDs[monsterCount])


for i, dungIdx in ipairs(AreaData.displayOrder.dungeons) do
local dung = CombatAreas.getAreaByID('dungeon', dungIdx)
result = result..'\r\n|-'
result = result..'\r\n|-'
result = result..'\r\n|data-sort-value="'..dung.name..'"|'..Icons.Icon({dung.name, type='dungeon', size='50', notext=true})
result = result..'\r\n|class="table-img" data-sort-value="'..dung.name..'"|'..Icons.Icon({dung.name, type='dungeon', size='50', notext=true})
result = result..'||'..Icons.Icon({dung.name, type='dungeon', noicon=true})
result = result..'||' .. Icons.getExpansionIcon(dung.id) .. Icons.Icon({dung.name, type='dungeon', noicon=true})
result = result..'||data-sort-value="'..dung.difficulty[1]..'"|'..CombatAreas._getAreaStat(dung, 'difficulty')
result = result..'||data-sort-value="'..dung.difficulty[1]..'"|'..Areas._getAreaStat(dung, 'difficulty')
result = result..'||'..Shared.tableCount(dung.monsters)
result = result..'||'..monsterCount
 
local boss = Monsters.getMonsterByID(dung.monsters[Shared.tableCount(dung.monsters)])
result = result..'||'..Shared.formatnum(Monsters._getMonsterCombatLevel(boss))
result = result..'||'..Shared.formatnum(Monsters._getMonsterCombatLevel(boss))
 
local reqText = Areas._getAreaRequirements(dung)
if reqText == nil or reqText == '' then
result = result .. '||class="table-na"| None'
else
result = result .. '||' .. reqText
end
result = result..'||'..p._getDungeonRewards(dung, false)
result = result..'||'..p._getDungeonRewards(dung, false)
if dung.petID ~= nil then
local petAdded = false
local pet = Pets.getPetByID(dung.petID)
if dung.pet ~= nil then
result = result..'||data-sort-value="'..pet.name..'"|'..Icons.Icon({pet.name, type='pet'})
local pet = GameData.getEntityByID('pets', dung.pet.petID)
else
if pet ~= nil then
result = result..'|| '
result = result..'||data-sort-value="'..pet.name..'"|'..Icons.Icon({pet.name, type='pet'})
local petDrop = Pets._getPetChance(pet)
if petDrop ~= nil then
result = result..'<br/>'..petDrop
end
petAdded = true
end
end
if not petAdded then
result = result..'||class="table-na"| None'
end
end
end
end
Line 167: Line 190:
end
end


function p._getDungeonDRTable(dung, mode, doStuns)
function p.buildCombatNavText(frame)
local AutoEatVals = {T1 = 0.2, T2 = 0.3, T3 = 0.4, T3W = 0.45}
--This isn't actually called on any pages but instead exists to save me time on updating Template:CombatNav for the new expansion
--NOTE: Due to Agility Obstacles, this value is a tad arbitrary
local areas = GameData.sortByOrderTable(GameData.rawData.slayerAreas, GameData.rawData.slayerAreaDisplayOrder)
local MaxViableHP = 1120
local outArray = {}
--This is the highest DR to list as possible. Value might be slightly off right now, currently just setting up value for testing
for i, area in ipairs(areas) do
local MaxViableDR = 81
local id = area.id
--This is the highest DR row shown. This should be higher than MaxViableDR
if Shared.startsWith(id, 'melvorTotH') then
local MaxVisibleDR = 85
table.insert(outArray, '|-')
 
table.insert(outArray, '| {{TotH}} {{ZoneIcon|'..area.name..'}}')
if doStuns == nil then
local monsterArray = {}
doStuns = true
for j, monsterID in ipairs(area.monsterIDs) do
elseif type(doStuns) == 'string' then
local monster = Monsters.getMonsterByID(monsterID)
doStuns = string.upper(doStuns) == 'TRUE'
table.insert(monsterArray, '{{MonsterIcon|'..monster.name..'}}')
end
end
 
table.insert(outArray, '| class="center" style="vertical-align:middle;" | '..table.concat(monsterArray, ' {{*}} '))
--First, figure out what our max hit for each style is
local MaxHits = { Melee = 0, Ranged = 0, Magic = 0 }
for i, monsterID in Shared.skpairs(dung.monsters) do
local monster = Monsters.getMonsterByID(monsterID)
local styleName = Constants.getCombatStyleName(monster.attackType)
local maxHit = Monsters._getMonsterMaxHit(monster, doStuns)
if maxHit > MaxHits[styleName] then
MaxHits[styleName] = maxHit
end
end
end
end
 
--Then, figure out the DR row to start with
areas = GameData.sortByOrderTable(GameData.rawData.dungeons, GameData.rawData.dungeonDisplayOrder)
--This is the DR that is one lower than the lowest possible DR for the best style
for i, area in ipairs(areas) do
local StyleArray = {"Melee", "Ranged", "Magic"}
local id = area.id
local EatThreshold = math.floor(MaxViableHP * AutoEatVals.T3W)
if Shared.startsWith(id, 'melvorTotH') then
local minDR = 100
table.insert(outArray, '|-')
for i, playerStyle in Shared.skpairs(StyleArray) do
table.insert(outArray, '| {{TotH}} {{ZoneIcon|'..area.name..'}}')
local maxStyleDR = 0
local monsterArray = {}
for enemyStyle, styleHit in Shared.skpairs(MaxHits) do
local mCheck = {}
if styleHit > 0 and styleHit > EatThreshold then
for j, monsterID in ipairs(area.monsterIDs) do
local styleDR = math.ceil((1 - (EatThreshold / styleHit)) * 100)
local monster = Monsters.getMonsterByID(monsterID)
styleDR = math.ceil(styleDR / Constants.getTriangleDRModifier(playerStyle, enemyStyle, mode))
if mCheck[monster.name] == nil then
maxStyleDR = math.max(maxStyleDR, styleDR)
table.insert(monsterArray, '{{MonsterIcon|'..monster.name..'}}')
end
mCheck[monster.name] = 1
end
end
table.insert(outArray, '| class="center" style="vertical-align:middle;" | '..table.concat(monsterArray, ' {{*}} '))
end
end
minDR = math.min(minDR, maxStyleDR)
end
end
 
minDR = minDR - 1
return table.concat(outArray, '\r\n')
 
--Finally, build the table using those starting points
local StyleHeader = "Melee!!Ranged!!Magic"
StyleHeader = StyleHeader..'!!'..StyleHeader..'!!'..StyleHeader..'!!'..StyleHeader
 
local result = '{| class="wikitable stickyHeader"'
result = result..'\r\n|-class="headerRow-0"'
result = result..'\r\n!Pre-Triangle DR!!colspan=3|AE T3 + Wasteful!!colspan=3|Auto Eat Tier 3!!colspan=3|Auto Eat Tier 2!!colspan=3|Auto Eat Tier 1'
result = result..'\r\n|-class="headerRow-0"'
result = result..'\r\n!DR %!!'..StyleHeader
 
local getHpForStyle = function(playerStyle, autoEat, playerDR)
return nil
end
 
for dr = minDR, MaxVisibleDR, 1 do
end
 
result = result..'\r\n|}'
 
return result
end
 
function p.getDungeonDRTable(frame)
local dungName = frame.args ~= nil and frame.args[1] or frame[1]
local mode = frame.args ~= nil and frame.args[2] or frame[2]
local doStuns = frame.args ~= nil and frame.args[3] or frame[3]
local dung = CombatAreas.getArea(dungName)
 
if dung == nil then
return 'ERROR: Invalid dungeon name'
end
 
return p._getDungeonDRTable(dung, mode, doStuns)
end
end


return p
return p