17,101
edits
(_getDungeonRewards: Add support for Impending Darkness Event) |
(Use tabs instead of spaces for indentation; _getDungeonRewards: Rework to remove redundant cape overrides) |
||
Line 14: | Line 14: | ||
function p.getLowHighLevels(idList) | function p.getLowHighLevels(idList) | ||
local lowLevel = 1000000 | |||
local highLevel = 0 | |||
for i, monID in Shared.skpairs(idList) do | |||
local monster = Monsters.getMonsterByID(monID) | |||
local cmbLevel = Monsters._getMonsterCombatLevel(monster) | |||
if cmbLevel < lowLevel then lowLevel = cmbLevel end | |||
if cmbLevel > highLevel then highLevel = cmbLevel end | |||
end | |||
return lowLevel, highLevel | |||
end | end | ||
function p.getCombatAreaTable() | function p.getCombatAreaTable() | ||
local result = '{| class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|- class="headerRow-0"' | |||
result = result..'\r\n!colspan="2"|Zone!!Difficulty!!Lowest Monster Level!!Highest Monster Level' | |||
for i, areaIdx in ipairs(AreaData.displayOrder.combatAreas) do | |||
local area = CombatAreas.getAreaByID('combat', areaIdx) | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..Icons.Icon({area.name, type='combat', size='50', notext=true}) | |||
result = result..'||'..Icons.Icon({area.name, type='combat', noicon=true}) | |||
local diff1 = Constants.getDifficultyString(area.difficulty[1]) | |||
local diff2 = Constants.getDifficultyString(area.difficulty[2]) | |||
result = result..'||data-sort-value="'..area.difficulty[1]..'"|'..diff1 | |||
if diff1 ~= diff2 and diff2 ~= nil then result = result..' - '..diff2 end | |||
local lowLvl, highLvl = p.getLowHighLevels(area.monsters) | |||
result = result..'||'..lowLvl..'||'..highLvl | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p.getSlayerAreaTable() | function p.getSlayerAreaTable() | ||
local result = '{| class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|- class="headerRow-0"' | |||
result = result..'\r\n!colspan="2"|Zone!!Difficulty!!Highest Monster Level!!Requirements!!Area Effect' | |||
for i, areaIdx in ipairs(AreaData.displayOrder.slayerAreas) do | |||
local area = CombatAreas.getAreaByID('slayer', areaIdx) | |||
result = result..'\r\n|-' | |||
result = result..'\r\n|'..Icons.Icon({area.name, type='slayer', size='50', notext=true}) | |||
result = result..'||'..Icons.Icon({area.name, type='slayer', noicon=true}) | |||
local diff1 = Constants.getDifficultyString(area.difficulty[1]) | |||
local diff2 = Constants.getDifficultyString(area.difficulty[2]) | |||
result = result..'||data-sort-value="'..area.difficulty[1]..'"|'..diff1 | |||
if diff1 ~= diff2 and diff2 ~= nil then result = result..' - '..diff2 end | |||
local lowLvl, highLvl = p.getLowHighLevels(area.monsters) | |||
result = result..'||'..highLvl | |||
result = result..'||'..CombatAreas._getAreaRequirements(area) | |||
result = result..'|| '..CombatAreas._getAreaStat(area, 'areaEffectDesc') | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p._getDungeonRewards(area, asList) | function p._getDungeonRewards(area, asList) | ||
if asList == nil then | |||
asList = true | |||
elseif type(asList) == 'string' then | |||
asList = asList.upper ~= 'FALSE' | |||
end | |||
local chr = asList and '* ' or '' | |||
local rewardList = {} | |||
-- GP reward | |||
if area.isEvent == nil or not area.isEvent then | |||
local bossMonster = Monsters.getMonsterByID(area.monsters[Shared.tableCount(area.monsters)]) | |||
local gpMin = bossMonster.dropCoins[1] | |||
local gpMax = bossMonster.dropCoins[2] | |||
if gpMin > 0 and gpMax > 0 then | |||
if gpMin == gpMax then | |||
table.insert(rewardList, chr .. Icons.GP(gpMin)) | |||
else | |||
table.insert(rewardList, chr .. Icons.GP(gpMin, gpMax)) | |||
end | |||
end | |||
end | |||
-- Item rewards | |||
if type(area.rewards) == 'table' then | |||
for i, rewardID in ipairs(area.rewards) do | |||
local rewardItem = Items.getItemByID(rewardID) | |||
if rewardItem == nil then | |||
table.insert(rewardList, chr .. 'Unknown item (ID ' .. tostring(rewardID) .. ')[[Category:Pages with Script Errors]]') | |||
else | |||
table.insert(rewardList, chr .. Icons.Icon({rewardItem.name, type='item', qty=1})) | |||
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 | |||
if asList then | |||
return table.concat(rewardList, '\r\n') | |||
else | |||
return table.concat(rewardList, '<br/>') | |||
end | |||
end | end | ||
function p.getDungeonRewards(frame) | function p.getDungeonRewards(frame) | ||
local areaName = frame.args ~= nil and frame.args[1] or frame | |||
local asList = frame.args ~= nil and frame.args[2] or true | |||
local area = CombatAreas.getArea(areaName) | |||
if area == nil then | |||
return "ERROR: Could not find an area named "..areaName..'[[Category:Pages with script errors]]' | |||
end | |||
if area.type == 'dungeon' then | |||
return p._getDungeonRewards(area, asList) | |||
else | |||
return "ERROR: "..areaName.." is not a dungeon[[Category:Pages with script errors]]" | |||
end | |||
end | end | ||
function p.getDungeonTable(frame) | function p.getDungeonTable(frame) | ||
local result = '{| class="wikitable sortable stickyHeader"' | |||
result = result..'\r\n|-class="headerRow-0"' | |||
result = result..'\r\n!colspan="2"|Dungeon!!Difficulty!!Monsters!!Boss Level!!Reward(s)!!Boss Pet' | |||
for i, dungIdx in ipairs(AreaData.displayOrder.dungeons) do | |||
local dung = CombatAreas.getAreaByID('dungeon', dungIdx) | |||
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..'||'..Icons.Icon({dung.name, type='dungeon', noicon=true}) | |||
result = result..'||data-sort-value="'..dung.difficulty[1]..'"|'..CombatAreas._getAreaStat(dung, 'difficulty') | |||
result = result..'||'..Shared.tableCount(dung.monsters) | |||
local boss = Monsters.getMonsterByID(dung.monsters[Shared.tableCount(dung.monsters)]) | |||
result = result..'||'..Shared.formatnum(Monsters._getMonsterCombatLevel(boss)) | |||
result = result..'||'..p._getDungeonRewards(dung, false) | |||
if dung.petID ~= nil then | |||
local pet = Pets.getPetByID(dung.petID) | |||
result = result..'||data-sort-value="'..pet.name..'"|'..Icons.Icon({pet.name, type='pet'}) | |||
else | |||
result = result..'|| ' | |||
end | |||
end | |||
result = result..'\r\n|}' | |||
return result | |||
end | end | ||
function p._getDungeonDRTable(dung, mode, doStuns) | function p._getDungeonDRTable(dung, mode, doStuns) | ||
local AutoEatVals = {T1 = 0.2, T2 = 0.3, T3 = 0.4, T3W = 0.45} | |||
--NOTE: Due to Agility Obstacles, this value is a tad arbitrary | |||
local MaxViableHP = 1120 | |||
--This is the highest DR to list as possible. Value might be slightly off right now, currently just setting up value for testing | |||
local MaxViableDR = 81 | |||
--This is the highest DR row shown. This should be higher than MaxViableDR | |||
local MaxVisibleDR = 85 | |||
if doStuns == nil then | |||
doStuns = true | |||
elseif type(doStuns) == 'string' then | |||
doStuns = string.upper(doStuns) == 'TRUE' | |||
end | |||
--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 | |||
--Then, figure out the DR row to start with | |||
--This is the DR that is one lower than the lowest possible DR for the best style | |||
local StyleArray = {"Melee", "Ranged", "Magic"} | |||
local EatThreshold = math.floor(MaxViableHP * AutoEatVals.T3W) | |||
local minDR = 100 | |||
for i, playerStyle in Shared.skpairs(StyleArray) do | |||
local maxStyleDR = 0 | |||
for enemyStyle, styleHit in Shared.skpairs(MaxHits) do | |||
if styleHit > 0 and styleHit > EatThreshold then | |||
local styleDR = math.ceil((1 - (EatThreshold / styleHit)) * 100) | |||
styleDR = math.ceil(styleDR / Constants.getTriangleDRModifier(playerStyle, enemyStyle, mode)) | |||
maxStyleDR = math.max(maxStyleDR, styleDR) | |||
end | |||
end | |||
minDR = math.min(minDR, maxStyleDR) | |||
end | |||
minDR = minDR - 1 | |||
--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 | end | ||
function p.getDungeonDRTable(frame) | 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 |