Module:Enemy
Jump to navigation
Jump to search
Documentation for this module may be created at Module:Enemy/doc
local p = {}
-- Helper functions
local function has_value(tab, val)
if tab == nil then
return false
end
for index, value in pairs(tab) do
if value == val then
return true
end
end
return false
end
local function has_key(tab, val)
if tab == nil then
return false
end
for index, value in pairs(tab) do
if value == val then
return true
end
end
return false
end
-- End
-- Module will signal an error if data is requested for fields other than these
local functionStats = {"HP", "ATK", "DEF", "MSPD"}
local staticStats = {"name", "card", "drops", "level", "enemytype", "elitetype", "sprite"}
local cardDetails = {"sprite", "description", "dropchance"}
local functionFormat = {"none", "eliteWrap"}
local table = mw.loadData('Module:EnemyStats/data')
function p.data(frame)
local enemy = frame.args[1]
local stat = frame.args[2]
if not(table) then
return "Fatal Error: enemyStats is nil"
end
if not(enemy and stat) then
return "Error: Invalid enemy / stat parameters"
end
-- If true, stat needs to be calculated from function table
local bCall = has_value(functionStats, stat)
if bCall then
---- Call respective function and determine stats based on difficulty and elite status---------
local functions = require('Module:EnemyFunctionTable')
-- Nil checks for validation
if not functions then
return "Fatal Error: enemyFunctionsTable is nil"
end
if not functions[enemy] then
return "Error: nil entry for " .. enemy .. " in enemyFunctionStats"
end
if not functions[enemy][stat] then
-- Hide stat
return ""
end
local diff = tonumber(frame.args[3])
local elite = tonumber(frame.args[4])
if not(diff and elite) then
return "Error: Invalid diff / elite parameters"
end
-- Return an empty string if the enemy doesn't have HasElite tag and elite = 1
-- (AKA can't be elite, or is "empowered" instead and doesn't benefit from elite
-- stat changes and player count HP scaling)
if elite == 1 and not(has_value(table[enemy]["tags"], "HasElite")) then
return ""
end
-- Get calculated value
local returnValue = functions[enemy][stat](diff, elite)
-- Do additonal processing based on stat
if stat == "MSPD" then
returnValue = (returnValue * 100) .. "%"
elseif stat == "HP" then
local ratio = 0.1
if has_value(table[enemy]["tags"], "Boss") then
ratio = 0.35
elseif has_value(table[enemy]["tags"], "MiniBoss") then
ratio = 0.3
end
returnValue = math.floor(returnValue + 0.5) * (1 + ratio * diff)
end
-- Return result or blank text if somehow ended up with a nil value (unimplemented stat?)
-- Result is rounded (unless it's not a number anymore)
if stat ~= "MSPD" then
returnValue = math.floor(returnValue + 0.5)
end
-- Check for format param
local format = frame.args[5] or "none"
if not has_value(functionFormat, format) then
format = "none"
end
-- Do format (unless returnValue is nil for some reason, just in case)
if returnValue ~= nil then
if format == "eliteWrap" and elite == 1 then
returnValue = " <b>( " .. returnValue .. " )</b>"
end
end
return returnValue or ""
else
--------- Grab information from stats table ---------------------------------------------------
-- Integrity check (nil card and drop stats is acceptable)
if not table[enemy] then
return "Error: nil entry for " .. enemy .. " in enemyStats"
end
if not has_value(staticStats, stat) then
return "Error: Requested data for invalid stat " .. stat
end
-- Get information
local returnValue = table[enemy][stat]
-- Do additional processing based on stat
if stat == "card" then
if returnValue == nil then
-- Hide stat if card section is nil
return ""
end
-- Grab third parameter
local detail = frame.args[3]
if not detail then
return "Error: Invalid detail parameter"
end
if not has_value(cardDetails, detail) then
return "Error: Requested data for invalid detail " .. detail
end
-- Process aliases (in particular, card drop chance)
if detail == "dropchance" then
returnValue = returnValue["dropchanceinverse"]
else
returnValue = returnValue[detail]
end
-- Nil check: if card section is not nil, details must have data
if not returnValue then
if stat == "sprite" then
-- Effectively an error image
return "Placeholder.png"
else
return "Error: nil value for " .. enemy .. ":card:" .. detail
end
end
-- Do additional processing based on detail
if detail == "dropchance" then
returnValue = 100.0 / returnValue
returnValue = math.floor(returnValue * 1000) / 1000
returnValue = returnValue .. "%"
end
-- Result goes out of if chain
elseif stat == "drops" then
if returnValue == nil then
-- Hide stat if drop section is nil
return ""
end
-- This stat is processed into the required wikitext
-- value[1] = item ID, value[2] = drop chance, value[3] = (optional) duplicate entry count
-- N duplicate entries means that the game rolls for another N-1 items of the same type with the same chance
-- Read each entry and create an ItemLink with data to the right, inside a list
local wikitext = ""
for index, value in ipairs(returnValue) do
-- Appends list wikitext and ItemLink
wikitext = wikitext .. "* " .. frame:expandTemplate{title = "ItemLink", args = {id = value[1]}}
-- Appends (chance%), optionally (N items rolled), then a newline
wikitext = wikitext .. " (" .. value[2] .. "%)"
if value[3] ~= nil then
wikitext = wikitext .. " (" .. value[3] .. " items rolled)"
end
wikitext = wikitext .. "\n"
end
-- Swap reference by the power of the holy garbage collector
returnValue = wikitext
elseif stat == "enemytype" then
returnValue = returnValue or "Regular"
if has_value(table[enemy]["tags"], "Boss") then
returnValue = "Boss"
elseif has_value(table[enemy]["tags"], "MiniBoss") then
returnValue = "Miniboss"
end
elseif stat == "elitetype" then
returnValue = "No"
if has_value(table[enemy]["tags"], "HasElite") then
returnValue = "Yes"
elseif has_value(table[enemy]["tags"], "HasPseudoElite") then
returnValue = "No (but is Empowered)"
end
end
-- Return result or blank text if somehow ended up with a nil value (unimplemented stat?)
return returnValue or ""
end
-----------------------------------------------------------------------------------------------
-- Error message in case I suck at coding
return "Error: Module exited processing code"
end
return p