Anonymous

Module:Monsters: Difference between revisions

From Melvor Idle
Added handling for a few more types of max hit for monsters
(triple indenting curse descriptions)
(Added handling for a few more types of max hit for monsters)
(2 intermediate revisions by the same user not shown)
Line 343: Line 343:
end
end


function p.getSpecAttackMaxHit(specAttack, normalMaxHit)
function p.getSpecAttackMaxHit(specAttack, normalMaxHit, monsterDR)
local result = 0
local result = 0
for i, dmg in pairs(specAttack.damage) do
for i, dmg in pairs(specAttack.damage) do
if dmg.maxRoll == 'Fixed' then
if dmg.damageType == 'Normal' then
--Account for special attacks that include a normal attack hit
local result = normalMaxHit
if dmg.amplitude ~= nil then
result = result * (dmg.amplitude / 100)
end
return result
elseif dmg.maxRoll == 'Fixed' then
result = dmg.maxPercent * 10
result = dmg.maxPercent * 10
elseif dmg.maxRoll == 'MaxHit' then
elseif dmg.maxRoll == 'MaxHit' then
Line 355: Line 362:
result = dmg.maxPercent * normalMaxHit * 0.01
result = dmg.maxPercent * normalMaxHit * 0.01
end
end
elseif Shared.contains(dmg.maxRoll, "Fixed100") then
--Handles attacks that are doubled when conditions are met like Trogark's double damage if the player is burning
result = dmg.maxPercent * 20
elseif dmg.maxRoll == 'MaxHitScaledByHP2x' then
result = normalMaxHit * 2
elseif dmg.maxRoll == 'PoisonMax35' then
result = normalMaxHit * 1.35
elseif dmg.maxRoll == "MaxHitDR" then
result = normalMaxHit * dmg.maxPercent * 0.01 * (1 + monsterDR * 0.01)
elseif Shared.contains({'Bleeding', 'Poisoned'}, dmg.maxRoll) then
elseif Shared.contains({'Bleeding', 'Poisoned'}, dmg.maxRoll) then
-- TODO: This is limited in that there is no verification that bleed/poison
-- TODO: This is limited in that there is no verification that bleed/poison
Line 402: Line 418:
normalChance = normalChance - specAttack.defaultChance
normalChance = normalChance - specAttack.defaultChance
end
end
local thisMax = p.getSpecAttackMaxHit(specAttack, normalMaxHit)
local thisMax = p.getSpecAttackMaxHit(specAttack, normalMaxHit, p._getMonsterStat(monster, 'damageReduction'))
if not canStun and p.canSpecAttackApplyEffect(specAttack, 'Stun') then canStun = true end
if not canStun and p.canSpecAttackApplyEffect(specAttack, 'Stun') then canStun = true end
if not canSleep and p.canSpecAttackApplyEffect(specAttack, 'Sleep') then canSleep = true end
if not canSleep and p.canSpecAttackApplyEffect(specAttack, 'Sleep') then canSleep = true end
Line 972: Line 988:


local tableTxt = '{| class="wikitable sortable"'
local tableTxt = '{| class="wikitable sortable"'
tableTxt = tableTxt..'\r\n! Name !! Combat Level !! Hitpoints !! Max Hit !! [[Combat Triangle|Combat Style]]'
tableTxt = tableTxt..'\r\n! Name !! Combat Level !! Hitpoints !! colspan=2| Max Hit !! [[Combat Triangle|Combat Style]]'
for i, monsterID in ipairs(area.monsterIDs) do
for i, monsterID in ipairs(area.monsterIDs) do
local monster = p.getMonsterByID(monsterID)
local monster = p.getMonsterByID(monsterID)
Line 978: Line 994:
tableTxt = tableTxt..'||'..p._getMonsterCombatLevel(monster)
tableTxt = tableTxt..'||'..p._getMonsterCombatLevel(monster)
tableTxt = tableTxt..'||'..Shared.formatnum(p._getMonsterHP(monster))
tableTxt = tableTxt..'||'..Shared.formatnum(p._getMonsterHP(monster))
tableTxt = tableTxt..'||'..Shared.formatnum(p._getMonsterMaxHit(monster))
local drReduction = p._getMonsterDrReduction(monster)
local maxHit = p._getMonsterMaxHit(monster)
if drReduction > 0 then
tableTxt = tableTxt..'||style="text-align:right" data-sort-value="'..maxHit..'"| -'..drReduction..'% DR'
tableTxt = tableTxt..'||style="text-align:right"|'..Shared.formatnum(maxHit)
else
tableTxt = tableTxt..'||style="text-align:right" colspan="2" data-sort-value="'..maxHit..'"|'..Shared.formatnum(maxHit)
end
tableTxt = tableTxt..'||'..p._getMonsterStyleIcon({monster, nolink=true})
tableTxt = tableTxt..'||'..p._getMonsterStyleIcon({monster, nolink=true})
end
end
Line 1,006: Line 1,029:
-- Declare function for building table rows to avoid repeating code
-- Declare function for building table rows to avoid repeating code
local buildRow = function(entityID, monsterCount, specialType)
local buildRow = function(entityID, monsterCount, specialType)
local monIcon, monLevel, monHP, monMaxHit, monStyle, monCount
local monIcon, monLevel, monHP, monMaxHit, monStyle, monCount, monDrReduce
local monData = {}
local monData = {}
if specialType ~= nil and Shared.contains({'Afflicted', 'Spider', 'SlayerArea'}, specialType) then
if specialType ~= nil and Shared.contains({'Afflicted', 'Spider', 'SlayerArea'}, specialType) then
Line 1,013: Line 1,036:
local iconQ = Icons.Icon({'Into the Mist', notext=true, nolink=true, img='Question'})
local iconQ = Icons.Icon({'Into the Mist', notext=true, nolink=true, img='Question'})
monIcon = Icons.Icon({'Into the Mist', 'Afflicted Monster', nolink=true, img='Question'})
monIcon = Icons.Icon({'Into the Mist', 'Afflicted Monster', nolink=true, img='Question'})
monLevel, monHP, monMaxHit, monStyle, monCount = iconQ, iconQ, iconQ, iconQ, monsterCount
monLevel, monHP, monMaxHit, monDrReduce, monStyle, monCount = iconQ, iconQ, iconQ, iconQ, iconQ, monsterCount
elseif specialType == 'Spider' then
elseif specialType == 'Spider' then
local iconQ = Icons.Icon({'', notext=true, nolink=true, img='Question'})
local iconQ = Icons.Icon({'', notext=true, nolink=true, img='Question'})
Line 1,024: Line 1,047:
end
end
monIcon = table.concat(monIconPart, '<br/>')
monIcon = table.concat(monIconPart, '<br/>')
monLevel, monHP, monMaxHit, monStyle, monCount = iconQ, iconQ, iconQ, iconQ, monsterCount
monLevel, monHP, monMaxHit, monDrReduce, monStyle, monCount = iconQ, iconQ, iconQ, iconQ, iconQ, monsterCount
elseif specialType == 'SlayerArea' then
elseif specialType == 'SlayerArea' then
-- entityID corresponds to a slayer area
-- entityID corresponds to a slayer area
Line 1,032: Line 1,055:
monHP = {p.getLowHighStat(area.monsterIDs, function(monster) return p._getMonsterHP(monster) end)}
monHP = {p.getLowHighStat(area.monsterIDs, function(monster) return p._getMonsterHP(monster) end)}
local lowMaxHit, highMaxHit = p.getLowHighStat(area.monsterIDs, function(monster) return p._getMonsterMaxHit(monster) end)
local lowMaxHit, highMaxHit = p.getLowHighStat(area.monsterIDs, function(monster) return p._getMonsterMaxHit(monster) end)
local lowDrReduce, highDrReduce = p.getLowHighStat(area.monsterIDs, function(monster) return p._getMonsterDrReduction(monster) end)
monMaxHit = highMaxHit
monMaxHit = highMaxHit
monDrReduce = highDrReduce
monStyle = Icons.Icon({area.name, area.name, notext=true, nolink=true, img='Question'})
monStyle = Icons.Icon({area.name, area.name, notext=true, nolink=true, img='Question'})
monCount = monsterCount
monCount = monsterCount
Line 1,042: Line 1,067:
monLevel = p._getMonsterCombatLevel(monster)
monLevel = p._getMonsterCombatLevel(monster)
monHP = p._getMonsterHP(monster)
monHP = p._getMonsterHP(monster)
monDrReduce = p._getMonsterDrReduction(monster)
monMaxHit = p._getMonsterMaxHit(monster)
monMaxHit = p._getMonsterMaxHit(monster)
monStyle = p._getMonsterStyleIcon({monster})
monStyle = p._getMonsterStyleIcon({monster})
Line 1,075: Line 1,101:
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. getValSort(monLevel) .. '"| ' .. getValText(monLevel))
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. getValSort(monLevel) .. '"| ' .. getValText(monLevel))
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. getValSort(monHP) .. '"| ' .. getValText(monHP))
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. getValSort(monHP) .. '"| ' .. getValText(monHP))
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. getValSort(monMaxHit) .. '"| ' .. getValText(monMaxHit))
if type(monDrReduce) == 'number' and monDrReduce > 0 then
table.insert(resultPart, '\r\n|style="text-align:right" data-sort-value="'..getValSort(monMaxHit)..'"| -'..monDrReduce..'% DR')
table.insert(resultPart, '\r\n|style="text-align:right"|'..getValText(monMaxHit))
else
table.insert(resultPart, '\r\n|style="text-align:right" colspan="2" data-sort-value="'..getValSort(monMaxHit)..'"|'..getValText(monMaxHit))
end
table.insert(resultPart, '\r\n| ' .. monStyle)
table.insert(resultPart, '\r\n| ' .. monStyle)
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. getValSort(monCount) .. '"| ' .. getValText(monCount))
table.insert(resultPart, '\r\n|style="text-align:right;" data-sort-value="' .. getValSort(monCount) .. '"| ' .. getValText(monCount))
Line 1,083: Line 1,114:
local returnPart = {}
local returnPart = {}
table.insert(returnPart, '{| class="wikitable sortable"')
table.insert(returnPart, '{| class="wikitable sortable"')
table.insert(returnPart, '\r\n! Name !! Combat Level !! Hitpoints !! Max Hit !! [[Combat Triangle|Combat Style]] !! Count')
table.insert(returnPart, '\r\n! Name !! Combat Level !! Hitpoints !! colspan="2" | Max Hit !! [[Combat Triangle|Combat Style]] !! Count')
-- Special handing for Impending Darkness event
-- Special handing for Impending Darkness event
-- TODO needs to be revised once there is a better understanding of how the event works
-- TODO needs to be revised once there is a better understanding of how the event works
Line 1,334: Line 1,365:
table.insert(tableParts, '{| class="wikitable sortable stickyHeader"')
table.insert(tableParts, '{| class="wikitable sortable stickyHeader"')
-- First header row
-- First header row
table.insert(tableParts, '\r\n|- class="headerRow-0"\r\n! colspan="5" | !! colspan="4" |Offensive Stats !! colspan="3" |Evasion Rating !! colspan="4" |')
table.insert(tableParts, '\r\n|- class="headerRow-0"\r\n! colspan="5" | !! colspan="5" |Offensive Stats !! colspan="3" |Evasion Rating !! colspan="4" |')
-- Second header row
-- Second header row
table.insert(tableParts, '\r\n|- class="headerRow-1"\r\n!Monster !!Name !!Combat Level ')
table.insert(tableParts, '\r\n|- class="headerRow-1"\r\n!Monster !!Name !!Combat Level ')
table.insert(tableParts, '!!style="padding:0 1em 0 0"|' .. Icons.Icon({'Hitpoints', type='skill'}))
table.insert(tableParts, '!!style="padding:0 1em 0 0"|' .. Icons.Icon({'Hitpoints', type='skill'}))
table.insert(tableParts, '!!Attack Speed (s) !!colspan="2"|Max Hit !!Accuracy ')
table.insert(tableParts, '!!Attack Speed (s) !!colspan="3"|Max Hit !!Accuracy ')
table.insert(tableParts, '!!style="padding:0 1em 0 0"|' .. Icons.Icon({'Defence', type='skill', notext=true}))
table.insert(tableParts, '!!style="padding:0 1em 0 0"|' .. Icons.Icon({'Defence', type='skill', notext=true}))
table.insert(tableParts, '!!style="padding:0 1em 0 0"|' .. Icons.Icon({'Ranged', type='skill', notext=true}))
table.insert(tableParts, '!!style="padding:0 1em 0 0"|' .. Icons.Icon({'Ranged', type='skill', notext=true}))
Line 1,354: Line 1,385:
local atkSpeed = p._getMonsterAttackSpeed(monster)
local atkSpeed = p._getMonsterAttackSpeed(monster)
local maxHit = p._getMonsterMaxHit(monster)
local maxHit = p._getMonsterMaxHit(monster)
local drReduce = p._getMonsterDrReduction(monster)
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")}
Line 1,371: Line 1,403:
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. p._getMonsterHP(monster) .. '" |' .. Shared.formatnum(p._getMonsterHP(monster)))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. p._getMonsterHP(monster) .. '" |' .. Shared.formatnum(p._getMonsterHP(monster)))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. atkSpeed .. '" |' .. Shared.round(atkSpeed, 1, 1))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. atkSpeed .. '" |' .. Shared.round(atkSpeed, 1, 1))
table.insert(tableParts, '\r\n|style="text-align:center;border-right:hidden" |' .. p._getMonsterStyleIcon({monster, notext=true}))
if drReduce > 0 then
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. maxHit .. '" |' .. Shared.formatnum(maxHit))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. maxHit .. '"| -' .. drReduce..'% DR')
table.insert(tableParts, '\r\n|style="text-align:right;border-right:hidden" |' .. p._getMonsterStyleIcon({monster, notext=true}))
table.insert(tableParts, '\r\n|style="text-align:right" |' .. Shared.formatnum(maxHit))
else
table.insert(tableParts, '\r\n|style="text-align:right;border-right:hidden" colspan="2" data-sort-value="' .. maxHit .. '"|' .. p._getMonsterStyleIcon({monster, notext=true}))
table.insert(tableParts, '\r\n|style="text-align:right"|' .. Shared.formatnum(maxHit))
end
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. accR .. '" |' .. Shared.formatnum(accR))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. accR .. '" |' .. Shared.formatnum(accR))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. evaR[1] .. '" |' .. Shared.formatnum(evaR[1]))
table.insert(tableParts, '\r\n|style="text-align:right" data-sort-value="' .. evaR[1] .. '" |' .. Shared.formatnum(evaR[1]))