Difference between revisions of "Module:Infobox Monster"
Jump to navigation
Jump to search
m (bug) |
m (Make zones and dps optional) |
||
| Line 1: | Line 1: | ||
| − | local p ={} | + | local p = {} |
local findId = require("Module:FindId") | local findId = require("Module:FindId") | ||
local infoboxModule = require('Module:Infobox') | local infoboxModule = require('Module:Infobox') | ||
| Line 8: | Line 8: | ||
local labelCount = 1 | local labelCount = 1 | ||
local dataCount = 1 | local dataCount = 1 | ||
| − | local defaultAffinities = { | + | local defaultAffinities = {{ |
| − | + | Melee = 1 | |
| − | + | }, { | |
| − | + | Magic = 1 | |
| − | + | }, { | |
| − | + | Range = 1 | |
| − | + | }, { | |
| − | + | Piercing = 1 | |
| − | + | }, { | |
| − | + | Blunt = 1 | |
| − | + | }, { | |
| − | + | Slashing = 1 | |
| − | + | }, { | |
| − | } | + | Fire = 1 |
| + | }, { | ||
| + | Ice = 1 | ||
| + | }, { | ||
| + | Nature = 1 | ||
| + | }, { | ||
| + | Chaos = 1 | ||
| + | }, { | ||
| + | Posion = 1 | ||
| + | }, { | ||
| + | Lightning = 1 | ||
| + | }} | ||
local affinitiesIcon = { | local affinitiesIcon = { | ||
| − | + | [1] = "[[File:Melee splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [2] = "[[File:Magic splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [3] = "[[File:Range splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [4] = "[[File:Stab splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [5] = "[[File:Crush splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [6] = "[[File:Slash splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [7] = "[[File:Fire_splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [8] = "[[File:Ice_splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [9] = "[[File:Nature_splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [10] = "[[File:Chaos_splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [11] = "[[File:Poison_splash.png|20px|link=Combat#Affinities]]", | |
| − | + | [12] = "[[File:Lightning_splash.png|20px|link=Combat#Affinities]]" | |
} | } | ||
-- Convert from CSV string to table (converts a single line of a CSV file) | -- Convert from CSV string to table (converts a single line of a CSV file) | ||
local function fromCSV(s) | local function fromCSV(s) | ||
| − | + | if string.sub(s, -1) ~= ',' then | |
| − | + | s = s .. ',' -- ending comma | |
| − | + | end | |
| − | + | s = string.gsub(s, "[%[%]]", ""):gsub(",%s", ",") | |
| − | + | local t = {} -- table to collect fields | |
| − | + | local fieldstart = 1 | |
| − | + | repeat | |
| − | + | local nexti = string.find(s, ',', fieldstart) | |
| − | + | table.insert(t, string.sub(s, fieldstart, nexti - 1)) | |
| − | + | fieldstart = nexti + 1 | |
| − | + | until fieldstart > string.len(s) | |
| − | + | return t | |
end | end | ||
local function pairsByKeys(t, f) | local function pairsByKeys(t, f) | ||
| − | + | local a = {} | |
| − | + | local orgi_key_type | |
| − | + | local orgi_key_numbered | |
| − | + | for n in pairs(t) do | |
| − | + | if tonumber(n) == nil then | |
| − | + | table.insert(a, n) | |
| − | + | orgi_key_type = "word" | |
| − | + | elseif type(n) == "number" then | |
| − | + | table.insert(a, n) | |
| − | + | orgi_key_type = "int" | |
| − | + | elseif type(n) == "string" and type(tonumber(n) == "number") then | |
| − | + | orgi_key_type = "number" | |
| − | + | table.insert(a, tonumber(n)) | |
| − | |||
end | end | ||
| − | + | end | |
| − | + | table.sort(a, f) | |
| − | + | local key | |
| − | + | local value | |
| − | + | local i = 0 -- iterator variable | |
| − | + | local iter = function() -- iterator function | |
| − | + | i = i + 1 | |
| − | + | if a[i] == nil then | |
| − | + | return nil | |
| − | + | elseif orgi_key_type == "word" or orgi_key_type == "int" then | |
| − | + | key = a[i] | |
| − | + | value = t[a[i]] | |
| − | + | elseif orgi_key_type == "number" then | |
| − | + | key = tostring(a[i]) | |
| − | + | value = t[tostring(a[i])] | |
| − | |||
end | end | ||
| − | return iter | + | return key, value |
| + | end | ||
| + | return iter | ||
end | end | ||
local function tchelper(first, rest) | local function tchelper(first, rest) | ||
| − | + | return first:upper() .. rest:lower() | |
end | end | ||
local function capitalize(s) | local function capitalize(s) | ||
| − | + | s = s:gsub("(%a)([%w_']*)", tchelper):gsub(" Of ", " of "):gsub(" The ", " the "):gsub("Ii", "II") | |
| − | + | return s | |
end | end | ||
local function tablelength(T) | local function tablelength(T) | ||
| − | + | local count = 0 | |
| − | + | for _ in pairs(T) do | |
| − | + | count = count + 1 | |
| + | end | ||
| + | return count | ||
end | end | ||
local function h() | local function h() | ||
| − | + | local s = "header" .. headerCount | |
| − | + | headerCount = headerCount + 1 | |
| − | + | labelCount = headerCount | |
| − | + | dataCount = headerCount | |
| − | + | return s | |
end | end | ||
local function sbreak() | local function sbreak() | ||
| − | + | local s = "sbreak" .. headerCount | |
| − | + | headerCount = headerCount + 1 | |
| − | + | labelCount = headerCount | |
| − | + | dataCount = headerCount | |
| − | + | return s | |
end | end | ||
local function l() | local function l() | ||
| − | + | local s = "label" .. labelCount | |
| − | + | dataCount = labelCount | |
| − | + | labelCount = labelCount + 1 | |
| − | + | headerCount = labelCount | |
| − | + | return s | |
end | end | ||
local function d() | local function d() | ||
| − | + | local s = "data" .. dataCount | |
| − | + | dataCount = dataCount + 1 | |
| − | + | headerCount = dataCount | |
| − | + | labelCount = dataCount | |
| − | + | return s | |
end | end | ||
local function sl() | local function sl() | ||
| − | + | local s = "s" .. l {} | |
| − | + | return s | |
end | end | ||
local function sd() | local function sd() | ||
| − | + | local s = "s" .. d {} | |
| − | + | return s | |
end | end | ||
local function rc() | local function rc() | ||
| − | + | local s = "rowclass" .. labelCount | |
| − | + | return s | |
end | end | ||
| Line 155: | Line 168: | ||
---@return table|nil | ---@return table|nil | ||
local function getMonster(id) | local function getMonster(id) | ||
| − | + | local mosnter = monstersData[tostring(id)] | |
| − | + | if mosnter then | |
| − | + | return mosnter | |
| − | + | end | |
| − | + | return nil | |
end | end | ||
local function getMonsterStats(id) | local function getMonsterStats(id) | ||
| − | + | local mosnterStats = normalMonsters[tostring(id)] | |
| − | + | if not mosnterStats then | |
| − | + | mosnterStats = dungeonMonsters[tostring(id)] | |
| − | + | if not mosnterStats then | |
| − | + | return nil | |
| − | + | end | |
| − | + | end | |
| − | + | return mosnterStats | |
end | end | ||
local function calcThreat(monster) | local function calcThreat(monster) | ||
| − | + | local damageThreat = 2 | |
| − | + | local weaponThreat = 3 | |
| − | + | local armorThreat = 5 | |
| − | + | local attackSpeedThreat = 3 | |
| − | + | local attackSpeedThreatLevel = 2.4 / monster.attackSpeed | |
| − | + | local attackSpeedThreatFinal = attackSpeedThreatLevel * attackSpeedThreat | |
| − | + | local potentialDamageThreatFinal = (monster.attack + monster.strength + monster.magic + monster.range) * damageThreat | |
| − | + | local weaponThreatFinal = (monster.weapon.dexterity + monster.weapon.intellect + monster.weapon.strength) * | |
| − | + | weaponThreat | |
| − | + | local targetArmorRating = monster.armor.protection + monster.armor.resistance + monster.armor.agility * 1.5 | |
| − | + | local armorThreatFinal = (targetArmorRating + monster.defense * 10) * armorThreat | |
| − | + | local baseThreat = (potentialDamageThreatFinal + weaponThreatFinal) * attackSpeedThreatFinal + armorThreatFinal | |
| − | + | return math.floor(baseThreat) | |
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
end | end | ||
local function fullUrl(url) | local function fullUrl(url) | ||
| − | + | local newUrl = url | |
| − | + | if url:sub(1, 5) == "https" then | |
| − | + | return newUrl | |
| − | + | end | |
| − | + | if url:sub(1, 1) ~= "/" then | |
| − | + | newUrl = "/" .. newUrl | |
| − | + | end | |
| − | + | newUrl = "https://www.play.idlescape.com" .. newUrl | |
| − | + | return newUrl | |
end | end | ||
local function createImgTag(monster) | local function createImgTag(monster) | ||
| − | + | local url = fullUrl(monster.image) | |
| − | + | local attrs = { | |
| − | + | src = fullUrl(monster.image), | |
| − | + | alt = monster.name, | |
| − | + | width = "150px" | |
| − | + | } | |
| − | + | local img = mw.html.create('img'):attr(attrs) | |
| − | + | return tostring(img) | |
end | end | ||
local function createOffAffinity(args, monsterStats) | local function createOffAffinity(args, monsterStats) | ||
| − | + | for index, value in pairsByKeys(defaultAffinities) do | |
| − | + | for affinity, affinityValue in pairs(value) do | |
| − | + | if monsterStats.offensiveDamageAffinity[affinity] then | |
| − | + | affinityValue = monsterStats.offensiveDamageAffinity[affinity] | |
| − | + | args[sl()] = affinitiesIcon[index] | |
| − | + | if affinityValue > 1 then | |
| − | + | args[sd()] = "<span style=\"color:#4caf50\">" .. (affinityValue - 1) * 100 .. "%<span/>" | |
| − | + | elseif affinityValue < 1 then | |
| − | + | args[sd()] = "<span style=\"color:#f44336\">" .. (affinityValue - 1) * 100 .. "%<span/>" | |
| − | + | else | |
| − | + | args[sd()] = (affinityValue - 1) * 100 .. "%" | |
| − | + | end | |
| − | + | else | |
| − | + | args[sl()] = affinitiesIcon[index] | |
| − | + | args[sd()] = (affinityValue - 1) * 100 .. "%" | |
| − | + | end | |
| − | + | if index % 3 == 0 then | |
| − | + | args["bodyclass"] = "equal-space" | |
| − | + | args[sbreak()] = "yes" | |
| − | + | end | |
| − | + | end | |
| − | + | end | |
| − | + | return args | |
end | end | ||
local function createDeffAffinity(args, monsterStats) | local function createDeffAffinity(args, monsterStats) | ||
| − | + | for index, value in pairsByKeys(defaultAffinities) do | |
| − | + | for affinity, affinityValue in pairs(value) do | |
| − | + | if monsterStats.defensiveDamageAffinity[affinity] then | |
| − | + | affinityValue = monsterStats.defensiveDamageAffinity[affinity] | |
| − | + | args[sl()] = affinitiesIcon[index] | |
| − | + | if affinityValue > 1 then | |
| − | + | args[sd()] = "<span style=\"color:#4caf50\">" .. (affinityValue - 1) * 100 .. "%<span/>" | |
| − | + | elseif affinityValue < 1 then | |
| − | + | args[sd()] = "<span style=\"color:#f44336\">" .. (affinityValue - 1) * 100 .. "%<span/>" | |
| − | + | else | |
| − | + | args[sd()] = (affinityValue - 1) * 100 .. "%" | |
| − | + | end | |
| − | + | else | |
| − | + | args[sl()] = affinitiesIcon[index] | |
| − | + | args[sd()] = (affinityValue - 1) * 100 .. "%" | |
| − | + | end | |
| − | + | if index % 3 == 0 then | |
| − | + | args["bodyclass"] = "equal-space" | |
| − | + | args[sbreak()] = "yes" | |
| − | + | end | |
| − | + | end | |
| − | + | end | |
| − | + | return args | |
end | end | ||
local function getZonesLink(zones) | local function getZonesLink(zones) | ||
| − | + | local s = "" | |
| − | + | if zones then | |
| − | + | for index, value in ipairs(zones) do | |
| − | + | s = s .. "[[" .. capitalize(value) .. "]]" | |
| − | + | if tablelength(zones) > index then | |
| − | + | s = s .. ", " | |
| − | + | end | |
| − | + | end | |
| − | + | end | |
| − | + | return s | |
end | end | ||
local function createInfobox(monster, monsterStats, zones, dps) | local function createInfobox(monster, monsterStats, zones, dps) | ||
| − | + | local args = {} | |
| − | + | args.autoheaders = "y" | |
| − | + | args.subbox = "no" | |
| − | + | args.bodystyle = " " | |
| − | + | args.title = monster.name | |
| − | + | args.image = createImgTag(monster) | |
| − | + | args[l()] = "Zones" | |
| − | + | args[d()] = getZonesLink(zones) | |
| − | + | args[h()] = "Offensive Stats" | |
| − | + | args[sl()] = "Attack Speed" | |
| − | + | args[sd()] = tostring(monsterStats.attackSpeed) | |
| − | + | args[sl()] = "DPS" | |
| − | + | args[sd()] = tostring(dps) | |
| − | + | args[sl()] = "Crit Chance" | |
| − | + | args[sd()] = tostring(monsterStats.offensiveCritical.chance * 100) .. "%" | |
| − | + | args[sl()] = "Crit Multiplier" | |
| − | + | args[sd()] = tostring(monsterStats.offensiveCritical.damageMultiplier * 100) .. "%" | |
| − | + | args[h()] = "Offensive Affinities" | |
| − | + | createOffAffinity(args, monsterStats) | |
| − | + | args[h()] = "Defensive Stats" | |
| − | + | args[sl()] = "Threat" | |
| − | + | args[sd()] = calcThreat(monsterStats) | |
| − | + | args[sl()] = "Crit Avoidance" | |
| − | + | args[sd()] = tostring(monsterStats.defensiveCritical.chance * 100) .. "%" | |
| − | + | args[sl()] = "Crit Reduction" | |
| − | + | args[sd()] = tostring(monsterStats.defensiveCritical.damageMultiplier * 100) .. "%" | |
| − | + | args[h()] = "Defensive Affinities" | |
| − | + | createDeffAffinity(args, monsterStats) | |
| − | + | for key, data in pairs(args) do | |
| − | + | if string.find(key, "data") then | |
| − | + | args[key] = tostring(data) | |
| − | + | end | |
| − | + | end | |
| − | + | return infoboxModule.infobox(args) | |
end | end | ||
| − | function | + | function p.infoboxMonster(frame) |
| − | + | local args = frame:getParent().args | |
| − | + | return p._infoboxMonster(args) | |
end | end | ||
function p._infoboxMonster(_args) | function p._infoboxMonster(_args) | ||
| − | + | local dps | |
| − | + | local zones | |
| − | local name | + | if _args["zones"] then |
| − | + | zones = fromCSV(_args["zones"]) | |
| − | + | end | |
| − | + | if _args["DPS"] then | |
| − | + | dps = _args["DPS"] | |
| − | + | else | |
| − | + | dps = "-" | |
| − | + | end | |
| − | + | local name | |
| − | + | local id | |
| − | + | local monster | |
| − | + | local monsterStats | |
| − | + | local infobox | |
| − | + | if _args[1] then | |
| − | + | name = _args[1] | |
| − | + | else | |
| − | + | name = mw.title.getCurrentTitle().text | |
| − | + | end | |
| − | + | id = findId._findId({name, "monster"}) | |
| − | + | if not id then | |
| − | + | return "<div style=\"color:red\"> No monster named '" .. name .. | |
| − | + | "'</div>. The Module:Monsters Ids/data maybe outdated." | |
| − | + | end | |
| − | + | monster = getMonster(id) | |
| + | if not monster then | ||
| + | return "<div style=\"color:red\"> No monster named '" .. name .. "'</div>. The Module:Monsters/data maybe outdated." | ||
| + | end | ||
| + | monsterStats = getMonsterStats(id) | ||
| + | if not monsterStats then | ||
| + | return "<div style=\"color:red\"> No monster named '" .. name .. | ||
| + | "'</div>. Module:Monsters stats normal/data and Module:Monsters stats dungeon/data maybe outdated." | ||
| + | end | ||
| + | infobox = createInfobox(monster, monsterStats, zones, dps) | ||
| + | return infobox | ||
end | end | ||
return p | return p | ||
Revision as of 02:26, 14 December 2024
local p = {}
local findId = require("Module:FindId")
local infoboxModule = require('Module:Infobox')
local monstersData = mw.loadData("Module:Monsters/data")
local normalMonsters = mw.loadData("Module:Monsters stats normal/data")
local dungeonMonsters = mw.loadData("Module:Monsters stats dungeon/data")
local headerCount = 1
local labelCount = 1
local dataCount = 1
local defaultAffinities = {{
Melee = 1
}, {
Magic = 1
}, {
Range = 1
}, {
Piercing = 1
}, {
Blunt = 1
}, {
Slashing = 1
}, {
Fire = 1
}, {
Ice = 1
}, {
Nature = 1
}, {
Chaos = 1
}, {
Posion = 1
}, {
Lightning = 1
}}
local affinitiesIcon = {
[1] = "[[File:Melee splash.png|20px|link=Combat#Affinities]]",
[2] = "[[File:Magic splash.png|20px|link=Combat#Affinities]]",
[3] = "[[File:Range splash.png|20px|link=Combat#Affinities]]",
[4] = "[[File:Stab splash.png|20px|link=Combat#Affinities]]",
[5] = "[[File:Crush splash.png|20px|link=Combat#Affinities]]",
[6] = "[[File:Slash splash.png|20px|link=Combat#Affinities]]",
[7] = "[[File:Fire_splash.png|20px|link=Combat#Affinities]]",
[8] = "[[File:Ice_splash.png|20px|link=Combat#Affinities]]",
[9] = "[[File:Nature_splash.png|20px|link=Combat#Affinities]]",
[10] = "[[File:Chaos_splash.png|20px|link=Combat#Affinities]]",
[11] = "[[File:Poison_splash.png|20px|link=Combat#Affinities]]",
[12] = "[[File:Lightning_splash.png|20px|link=Combat#Affinities]]"
}
-- Convert from CSV string to table (converts a single line of a CSV file)
local function fromCSV(s)
if string.sub(s, -1) ~= ',' then
s = s .. ',' -- ending comma
end
s = string.gsub(s, "[%[%]]", ""):gsub(",%s", ",")
local t = {} -- table to collect fields
local fieldstart = 1
repeat
local nexti = string.find(s, ',', fieldstart)
table.insert(t, string.sub(s, fieldstart, nexti - 1))
fieldstart = nexti + 1
until fieldstart > string.len(s)
return t
end
local function pairsByKeys(t, f)
local a = {}
local orgi_key_type
local orgi_key_numbered
for n in pairs(t) do
if tonumber(n) == nil then
table.insert(a, n)
orgi_key_type = "word"
elseif type(n) == "number" then
table.insert(a, n)
orgi_key_type = "int"
elseif type(n) == "string" and type(tonumber(n) == "number") then
orgi_key_type = "number"
table.insert(a, tonumber(n))
end
end
table.sort(a, f)
local key
local value
local i = 0 -- iterator variable
local iter = function() -- iterator function
i = i + 1
if a[i] == nil then
return nil
elseif orgi_key_type == "word" or orgi_key_type == "int" then
key = a[i]
value = t[a[i]]
elseif orgi_key_type == "number" then
key = tostring(a[i])
value = t[tostring(a[i])]
end
return key, value
end
return iter
end
local function tchelper(first, rest)
return first:upper() .. rest:lower()
end
local function capitalize(s)
s = s:gsub("(%a)([%w_']*)", tchelper):gsub(" Of ", " of "):gsub(" The ", " the "):gsub("Ii", "II")
return s
end
local function tablelength(T)
local count = 0
for _ in pairs(T) do
count = count + 1
end
return count
end
local function h()
local s = "header" .. headerCount
headerCount = headerCount + 1
labelCount = headerCount
dataCount = headerCount
return s
end
local function sbreak()
local s = "sbreak" .. headerCount
headerCount = headerCount + 1
labelCount = headerCount
dataCount = headerCount
return s
end
local function l()
local s = "label" .. labelCount
dataCount = labelCount
labelCount = labelCount + 1
headerCount = labelCount
return s
end
local function d()
local s = "data" .. dataCount
dataCount = dataCount + 1
headerCount = dataCount
labelCount = dataCount
return s
end
local function sl()
local s = "s" .. l {}
return s
end
local function sd()
local s = "s" .. d {}
return s
end
local function rc()
local s = "rowclass" .. labelCount
return s
end
---fetches an monster object from monsters/data module
---@param id number
---@return table|nil
local function getMonster(id)
local mosnter = monstersData[tostring(id)]
if mosnter then
return mosnter
end
return nil
end
local function getMonsterStats(id)
local mosnterStats = normalMonsters[tostring(id)]
if not mosnterStats then
mosnterStats = dungeonMonsters[tostring(id)]
if not mosnterStats then
return nil
end
end
return mosnterStats
end
local function calcThreat(monster)
local damageThreat = 2
local weaponThreat = 3
local armorThreat = 5
local attackSpeedThreat = 3
local attackSpeedThreatLevel = 2.4 / monster.attackSpeed
local attackSpeedThreatFinal = attackSpeedThreatLevel * attackSpeedThreat
local potentialDamageThreatFinal = (monster.attack + monster.strength + monster.magic + monster.range) * damageThreat
local weaponThreatFinal = (monster.weapon.dexterity + monster.weapon.intellect + monster.weapon.strength) *
weaponThreat
local targetArmorRating = monster.armor.protection + monster.armor.resistance + monster.armor.agility * 1.5
local armorThreatFinal = (targetArmorRating + monster.defense * 10) * armorThreat
local baseThreat = (potentialDamageThreatFinal + weaponThreatFinal) * attackSpeedThreatFinal + armorThreatFinal
return math.floor(baseThreat)
end
local function fullUrl(url)
local newUrl = url
if url:sub(1, 5) == "https" then
return newUrl
end
if url:sub(1, 1) ~= "/" then
newUrl = "/" .. newUrl
end
newUrl = "https://www.play.idlescape.com" .. newUrl
return newUrl
end
local function createImgTag(monster)
local url = fullUrl(monster.image)
local attrs = {
src = fullUrl(monster.image),
alt = monster.name,
width = "150px"
}
local img = mw.html.create('img'):attr(attrs)
return tostring(img)
end
local function createOffAffinity(args, monsterStats)
for index, value in pairsByKeys(defaultAffinities) do
for affinity, affinityValue in pairs(value) do
if monsterStats.offensiveDamageAffinity[affinity] then
affinityValue = monsterStats.offensiveDamageAffinity[affinity]
args[sl()] = affinitiesIcon[index]
if affinityValue > 1 then
args[sd()] = "<span style=\"color:#4caf50\">" .. (affinityValue - 1) * 100 .. "%<span/>"
elseif affinityValue < 1 then
args[sd()] = "<span style=\"color:#f44336\">" .. (affinityValue - 1) * 100 .. "%<span/>"
else
args[sd()] = (affinityValue - 1) * 100 .. "%"
end
else
args[sl()] = affinitiesIcon[index]
args[sd()] = (affinityValue - 1) * 100 .. "%"
end
if index % 3 == 0 then
args["bodyclass"] = "equal-space"
args[sbreak()] = "yes"
end
end
end
return args
end
local function createDeffAffinity(args, monsterStats)
for index, value in pairsByKeys(defaultAffinities) do
for affinity, affinityValue in pairs(value) do
if monsterStats.defensiveDamageAffinity[affinity] then
affinityValue = monsterStats.defensiveDamageAffinity[affinity]
args[sl()] = affinitiesIcon[index]
if affinityValue > 1 then
args[sd()] = "<span style=\"color:#4caf50\">" .. (affinityValue - 1) * 100 .. "%<span/>"
elseif affinityValue < 1 then
args[sd()] = "<span style=\"color:#f44336\">" .. (affinityValue - 1) * 100 .. "%<span/>"
else
args[sd()] = (affinityValue - 1) * 100 .. "%"
end
else
args[sl()] = affinitiesIcon[index]
args[sd()] = (affinityValue - 1) * 100 .. "%"
end
if index % 3 == 0 then
args["bodyclass"] = "equal-space"
args[sbreak()] = "yes"
end
end
end
return args
end
local function getZonesLink(zones)
local s = ""
if zones then
for index, value in ipairs(zones) do
s = s .. "[[" .. capitalize(value) .. "]]"
if tablelength(zones) > index then
s = s .. ", "
end
end
end
return s
end
local function createInfobox(monster, monsterStats, zones, dps)
local args = {}
args.autoheaders = "y"
args.subbox = "no"
args.bodystyle = " "
args.title = monster.name
args.image = createImgTag(monster)
args[l()] = "Zones"
args[d()] = getZonesLink(zones)
args[h()] = "Offensive Stats"
args[sl()] = "Attack Speed"
args[sd()] = tostring(monsterStats.attackSpeed)
args[sl()] = "DPS"
args[sd()] = tostring(dps)
args[sl()] = "Crit Chance"
args[sd()] = tostring(monsterStats.offensiveCritical.chance * 100) .. "%"
args[sl()] = "Crit Multiplier"
args[sd()] = tostring(monsterStats.offensiveCritical.damageMultiplier * 100) .. "%"
args[h()] = "Offensive Affinities"
createOffAffinity(args, monsterStats)
args[h()] = "Defensive Stats"
args[sl()] = "Threat"
args[sd()] = calcThreat(monsterStats)
args[sl()] = "Crit Avoidance"
args[sd()] = tostring(monsterStats.defensiveCritical.chance * 100) .. "%"
args[sl()] = "Crit Reduction"
args[sd()] = tostring(monsterStats.defensiveCritical.damageMultiplier * 100) .. "%"
args[h()] = "Defensive Affinities"
createDeffAffinity(args, monsterStats)
for key, data in pairs(args) do
if string.find(key, "data") then
args[key] = tostring(data)
end
end
return infoboxModule.infobox(args)
end
function p.infoboxMonster(frame)
local args = frame:getParent().args
return p._infoboxMonster(args)
end
function p._infoboxMonster(_args)
local dps
local zones
if _args["zones"] then
zones = fromCSV(_args["zones"])
end
if _args["DPS"] then
dps = _args["DPS"]
else
dps = "-"
end
local name
local id
local monster
local monsterStats
local infobox
if _args[1] then
name = _args[1]
else
name = mw.title.getCurrentTitle().text
end
id = findId._findId({name, "monster"})
if not id then
return "<div style=\"color:red\"> No monster named '" .. name ..
"'</div>. The Module:Monsters Ids/data maybe outdated."
end
monster = getMonster(id)
if not monster then
return "<div style=\"color:red\"> No monster named '" .. name .. "'</div>. The Module:Monsters/data maybe outdated."
end
monsterStats = getMonsterStats(id)
if not monsterStats then
return "<div style=\"color:red\"> No monster named '" .. name ..
"'</div>. Module:Monsters stats normal/data and Module:Monsters stats dungeon/data maybe outdated."
end
infobox = createInfobox(monster, monsterStats, zones, dps)
return infobox
end
return p