Module:Monsters stats table
Jump to navigation
Jump to search
local p = {} local findId = require("Module:FindId") local monsters_stats = mw.loadData("Module:Monsters stats/data") 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} } -- Convert from CSV string to table (converts a single line of a CSV file) local function fromCSV(s) s = s .. ',' -- ending comma 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 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 baseThreat end local function genDefensiveTable(monsters) local defensiveAffinties = {} local s = "{|class=\"wikitable sortable hover-highlight\"\n" s = s .. "!rowspan=2 colspan=2|Monster\n" s = s .. "!rowspan=2|Base<br/>Threat\n" s = s .. "!rowspan=2|Crit<br/>Avoidance\n" s = s .. "!rowspan=2|Crit<br/>Reduction\n" s = s .. "!colspan=12 style=\"text-align:center\"|Affinities\n" s = s .. "|-\n" s = s .. "![[File:Melee splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Magic splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Range splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Stab splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Crush splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Slash splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Fire_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Ice_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Nature_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Chaos_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Poison_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Lightning_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "|-\n" for _, monster in ipairs(monsters) do for index, value in pairsByKeys(defaultAffinities) do for affinity, affinityValue in pairs(value) do if monster.defensiveDamageAffinity[affinity] then defensiveAffinties[index] = {affinity = monster.defensiveDamageAffinity[affinity]} else defensiveAffinties[index] = {affinity = affinityValue} end end end s = s .. "|{{img|" .. monster["name"] .. "|42}}\n" s = s .. "|[[" .. monster["name"] .. "]]\n" s = s .. "| " .. calcThreat(monster) .. "\n" s = s .. "|" .. tostring(monster.defensiveCritical.chance * 100) .. "%\n" s = s .. "|" .. tostring(monster.defensiveCritical.damageMultiplier * 100) .. "%\n" for _, value in pairsByKeys(defensiveAffinties) do for affinity, affinityValue in pairs(value) do if affinityValue > 1 then s = s .. "|<span style=\"color:#4caf50\">" .. tonumber((affinityValue - 1) * 100) .. "%<span/>\n" elseif affinityValue == 1 then s =s .. "|" .. tonumber((affinityValue - 1) * 100) .. "%\n" else s = s .. "|<span style=\"color:#f44336\">" .. tonumber((affinityValue - 1) * 100) .. "%<span/>\n" end end end s = s .. "|-\n" end s = s .. "|}" return s end local function genOffensiveTable(monsters) local offensiveAffinties = {} local s = "{|class=\"wikitable sortable hover-highlight\"\n" s = s .. "!rowspan=2 colspan=2|Monster\n" s = s .. "!rowspan=2|Crit<br/>Chance\n" s = s .. "!rowspan=2|Crit<br/>Multiplier\n" s = s .. "!colspan=12 style=\"text-align:center\"|Affinities\n" s = s .. "|-\n" s = s .. "![[File:Melee splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Magic splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Range splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Stab splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Crush splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Slash splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Fire_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Ice_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Nature_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Chaos_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Poison_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "![[File:Lightning_splash.png|20px|link=Combat#Affinities]]\n" s = s .. "|-\n" for _, monster in ipairs(monsters) do for index, value in pairsByKeys(defaultAffinities) do for affinity, affinityValue in pairs(value) do if monster.offensiveDamageAffinity[affinity] then offensiveAffinties[index] = {affinity = monster.offensiveDamageAffinity[affinity]} else offensiveAffinties[index] = {affinity = affinityValue} end end end s = s .. "|{{img|" .. monster["name"] .. "|42}}\n" s = s .. "|[[" .. monster["name"] .. "]]\n" s = s .. "|" .. tostring(monster.offensiveCritical.chance * 100) .. "%\n" s = s .. "|" .. tostring(monster.offensiveCritical.damageMultiplier * 100) .. "%\n" for _, value in pairsByKeys(offensiveAffinties) do for affinity, affinityValue in pairs(value) do if affinityValue > 1 then s = s .. "|<span style=\"color:#4caf50\">" .. tonumber((affinityValue - 1) * 100) .. "%<span/>\n" elseif affinityValue == 1 then s =s .. "|" .. tonumber((affinityValue - 1) * 100) .. "%\n" else s = s .. "|<span style=\"color:#f44336\">" .. tonumber((affinityValue - 1) * 100) .. "%<span/>\n" end end end s = s .. "|-\n" end s = s .. "|}" return s end function p.monsters_stats_table(frame) return p._monsters_stats_table(frame:getParent().args) end function p._monsters_stats_table(_args) local monstersName = fromCSV(_args[1]) local monsters = {} local style = _args[2] local s = "" for _, value in ipairs(monstersName) do table.insert(monsters, monsters_stats[tostring(findId._findId({ value, "monster" }))]) end if style == "defensive" then return genDefensiveTable(monsters) elseif style == "offensive" then return genOffensiveTable(monsters) else return "wrong style" end end return p