Anonymous

Module:Monsters: Difference between revisions

From Melvor Idle
Update for v1.3
(getSpecAttackMaxHit: Resolve issue with aggregation of damage from multiple special attack damage sources)
(Update for v1.3)
Line 3: Line 3:
local Constants = require('Module:Constants')
local Constants = require('Module:Constants')
local Shared = require('Module:Shared')
local Shared = require('Module:Shared')
local Common = require('Module:Common')
local GameData = require('Module:GameData')
local GameData = require('Module:GameData')
local Areas = require('Module:CombatAreas')
local Areas = require('Module:CombatAreas')
Line 330: Line 331:


function p._isDungeonOnlyMonster(monster)
function p._isDungeonOnlyMonster(monster)
local areaList = Areas.getMonsterAreas(monster.id)
local areaList = Areas._getMonsterAreas(monster)
local inDungeon = false
local inDungeon = false


Line 358: Line 359:
local resultPart = {}
local resultPart = {}
local hideDungeons = excludeDungeons ~= nil and excludeDungeons or false
local hideDungeons = excludeDungeons ~= nil and excludeDungeons or false
local areaList = Areas.getMonsterAreas(monster.id)
local areaList = Areas._getMonsterAreas(monster)
for i, area in ipairs(areaList) do
for i, area in ipairs(areaList) do
if area.type ~= 'dungeon' or not hideDungeons then
if area.type ~= 'dungeon' or not hideDungeons then
local imgType = (area.type == 'slayerArea' and 'combatArea') or area.type
local imgType = (area.type == 'slayerArea' and 'combatArea') or area.type
local txt = Icons.Icon({area.name, type = imgType})
local txt = Icons.Icon({(area.name or area.id), type = imgType})
if area.type == 'slayerArea' then
if area.type == 'slayerArea' then
local areaDescrip = Areas._getAreaStat(area, 'areaEffectDesc')
local areaDescrip = Areas._getAreaStat(area, 'areaEffectDesc')
Line 922: Line 923:
if monster.isBoss then table.insert(monsterTypes, 'Boss') end
if monster.isBoss then table.insert(monsterTypes, 'Boss') end


local areaList = Areas.getMonsterAreas(monster.id)
local areaList = Areas._getMonsterAreas(monster)
local counts = {combatArea = 0, slayerArea = 0, dungeon = 0}
local counts = {combatArea = 0, slayerArea = 0, dungeon = 0}
for i, area in ipairs(areaList) do
for i, area in ipairs(areaList) do
Line 934: Line 935:
result = result.."\r\n|-\r\n|'''Monster Types:''' "..table.concat(monsterTypes, ", ")
result = result.."\r\n|-\r\n|'''Monster Types:''' "..table.concat(monsterTypes, ", ")


local SlayerTier = 'N/A'
local slayerCategoryText = 'N/A'
if monster.canSlayer then
local slayerTaskCategory = p._getMonsterSlayerTaskCategory(monster)
SlayerTier = Constants.getSlayerTierNameByLevel(p._getMonsterCombatLevel(monster))
if slayerTaskCategory ~= nil then
local catName = slayerTaskCategory.name
slayerCategoryText = '[[Slayer#' .. catName .. '|' .. catName .. ']]'
end
end


result = result.."\r\n|-\r\n|'''"..Icons.Icon({'Slayer', type='skill'}).." [[Slayer#Slayer Tier Monsters|Tier]]:''' "
result = result.."\r\n|-\r\n|'''"..Icons.Icon({'Slayer', type='skill'}).." [[Slayer#Slayer Tier Monsters|Tier]]:''' " .. slayerCategoryText
 
return result
end
 
function p._getMonsterSlayerTaskCategory(monster)
if monster.canSlayer then
if monster.canSlayer then
result = result.."[[Slayer#"..SlayerTier.."|"..SlayerTier.."]]"
for _, taskCategory in ipairs(GameData.rawData.slayerTaskCategories) do
else
local ms = taskCategory.monsterSelection
result = result..SlayerTier
if ms.type == 'CombatLevel' then
local cmbLevel = p._getMonsterCombatLevel(monster)
if cmbLevel >= ms.minLevel and (ms.maxLevel == nil or cmbLevel <= ms.maxLevel) then
return taskCategory
end
elseif ms.type == 'Abyss' then
if Areas._isMonsterInArea(monster, Areas.getAreaByID(ms.areaID)) then
return taskCategory
end
else
error('Unknown Slayer task category monster selection type: ' .. (ms.type or 'nil'))
end
end
end
end
return result
end
end


Line 1,631: Line 1,649:
function p.getSlayerTierMonsterTable(frame)
function p.getSlayerTierMonsterTable(frame)
-- Input validation
-- Input validation
local tier = frame.args ~= nil and frame.args[1] or frame
local args = frame.args ~= nil and frame.args or frame
local slayerTier = nil
local categoryName = args[1]
local slayerCategory = GameData.getEntityByName('slayerTaskCategories', categoryName)


if tier == nil then
if slayerCategory == nil then
return Shared.printError('No tier specified')
local catNames = {}
for i, cat in ipairs(GameData.rawData.slayerTaskCategories) do
if cat.name ~= nil then
table.insert(catNames, cat.name)
end
end
return Shared.printError('Invalid slayer category specified, must be any of: ' .. table.concat(catNames, ', '))
end
end


if tonumber(tier) ~= nil then
-- Build list of monsters
slayerTier = Constants.getSlayerTierByID(tonumber(tier))
else
slayerTier = Constants.getSlayerTier(tier)
end
 
if slayerTier == nil then
return Shared.printError('Invalid slayer tier')
end
 
-- Obtain required tier details
local minLevel, maxLevel = slayerTier.minLevel, slayerTier.maxLevel
 
-- Build list of monster IDs
-- Right now hiddenMonsterIDs is empty
-- Right now hiddenMonsterIDs is empty
local hiddenMonsterIDs = {}
local hiddenMonsterIDs = {}
local monsterList = GameData.getEntities('monsters',
local monsterList = GameData.getEntities('monsters',
         function(monster)
         function(monster)
            if monster.canSlayer and not Shared.contains(hiddenMonsterIDs, monster.id) then
local monsterCat = p._getMonsterSlayerTaskCategory(monster)
                local cmbLevel = p._getMonsterCombatLevel(monster)
return monsterCat ~= nil and monsterCat.id == slayerCategory.id
                return cmbLevel >= minLevel and (maxLevel == nil or cmbLevel <= maxLevel)
end
            end
)
            return false
        end)


if Shared.tableIsEmpty(monsterList) then
if Shared.tableIsEmpty(monsterList) then
Line 1,705: Line 1,715:
local accR = p._getMonsterAR(monster)
local accR = p._getMonsterAR(monster)
local evaR = {p._getMonsterER(monster, "Melee"), p._getMonsterER(monster, "Ranged"), p._getMonsterER(monster, "Magic")}
local evaR = {p._getMonsterER(monster, "Melee"), p._getMonsterER(monster, "Ranged"), p._getMonsterER(monster, "Magic")}
local currVal = 0
local gpTxt = nil
if monster.currencyDrops ~= nil and not monster.currencyDrops[1] ~= nil then
if monster.gpDrops.min >= monster.gpDrops.max then
local firstDrop = monster.currencyDrops[1]
gpTxt = Shared.formatnum(monster.gpDrops.min)
currVal = (firstDrop.min + firstDrop.max) / 2
else
gpTxt = Shared.formatnum(monster.gpDrops.min) .. ' - ' .. Shared.formatnum(monster.gpDrops.max)
end
end
local currText = Common.getCostString({ ["currencies"] = monster.currencyDrops })
local bones = p._getMonsterBones(monster)
local bones = p._getMonsterBones(monster)
local boneTxt = (bones ~= nil and Icons.Icon({bones.item.name, type='item', notext=true})) or 'None'
local boneTxt = (bones ~= nil and Icons.Icon({bones.item.name, type='item', notext=true})) or 'None'
Line 1,733: Line 1,742:
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. evaR[3] .. '" |' .. Shared.formatnum(evaR[3]))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. evaR[3] .. '" |' .. Shared.formatnum(evaR[3]))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. dr .. '" |' .. dr..'%')
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. dr .. '" |' .. dr..'%')
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. (monster.gpDrops.min + monster.gpDrops.max) / 2 .. '" |' .. gpTxt)
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. currVal .. '" |' .. currText)
table.insert(tableParts, '\r\n|style="text-align:center" |' .. boneTxt)
table.insert(tableParts, '\r\n|style="text-align:center" |' .. boneTxt)
table.insert(tableParts, '\r\n|style="text-align:right;width:190px" |' .. p._getMonsterAreas(monster, hideDungeons))
table.insert(tableParts, '\r\n|style="text-align:right;width:190px" |' .. p._getMonsterAreas(monster, hideDungeons))