Module:Enemies: Difference between revisions
From Valheim Wiki
No edit summary |
No edit summary |
||
| Line 977: | Line 977: | ||
local result_ext_count | local result_ext_count | ||
for _, row in ipairs(result) do | for _, row in ipairs(result) do | ||
print "cool" | print("cool") | ||
rows_count = rows_count + 1 | rows_count = rows_count + 1 | ||
-- table row: | -- table row: | ||
Revision as of 19:00, 20 December 2022
Documentation for this module may be created at Module:Enemies/doc
-- Table is registered at /Template:Enemies
local item_link = require('Module:Item').go
local is_crafting_station = require('Module:Item').is_crafting_station
local trim = mw.text.trim
local cargo = mw.ext.cargo
local cache = require 'mw.ext.LuaCache'
local currentFrame -- global cache for current frame object.
local inputArgs -- global args cache.
local lang -- cache current lang.
local resultanchor
local l10n = function(key)
return key
end
local extCols_stationBefore = nil
local extCols_stationAfter = nil
local extCols_A = nil
local extCols_B = nil
local extCols_C = nil
local extCols_D = nil
local countStationCells = 0
function getArg(key)
local v = trim(inputArgs[key] or '')
if v == '' then
return nil
else
return v
end
end
function firstToUpper(str)
return (str:gsub("^%l", string.upper))
end
local enemyLink = (function()
local cache = {}
return function(name, args)
local key = name.."|"
if args then
for k, v in pairs(args) do
key = key..k..'='..tostring(v)..'|'
end
end
if not cache[key] then
local args = args and mw.clone(args) or {}
args[1] = name
if (not args[2]) or args[2]=='' then
args[2] = currentFrame:expandTemplate{ title = 'tr', args = {name, lang=lang} }
end
args['small'] = 'y'
args['lang'] = lang or 'en'
args['nolink'] = args['nolink'] and 'y' or nil
cache[key] = item_link(currentFrame, args)
end
return cache[key]
end
end)()
-- credit: http://richard.warburton.it
-- this version is with trim.
local explode = function(div,str)
if (div=='') then return false end
local pos,arr = 0,{}
-- for each divider found
for st,sp in function() return string.find(str,div,pos,true) end do
table.insert(arr, trim(string.sub(str,pos,st-1))) -- Attach chars left of current divider
pos = sp + 1 -- Jump past current divider
end
table.insert(arr, trim(string.sub(str,pos))) -- Attach chars right of last divider
return arr
end
-- retuan a array of itemname, split xxx/yyy to item1=xxx, item2=yyy. If it's something like "Lead/Iron Bar", it will normalize as item1 = Iron Bar, item2 = Lead Bar.
local split = (function()
local metals = {
['Copper/Tin'] = 1,
['Tin/Copper'] = 2,
}
return function(name)
local count = select(2, name:gsub("/", "/", 2))
if count == 0 then
-- only 1 item
return { trim(name) }
elseif count == 1 then
-- 2 items
local item1a, item1b, item2a, item2b = name:match("^%s*(%S+)%s*(.-)/%s*(%S+)%s*(.-)$")
local x = metals[item1a..'/'..item2a]
if tostring(item1b) == '' and x then
item1b = item2b
end
if x == 2 then
return {trim(item2a..' '..item2b), trim(item1a..' '..item1b)}
else
return {trim(item1a..' '..item1b), trim(item2a..' '..item2b)}
end
else
-- 3 or more items
return explode('/', name)
end
end
end)()
-- return 1 or 2 value(s), when input is name[note], return item, note.
local itemname = function(str)
local item, note = str:match("^(.-)(%b[])$")
if item then
return item, note
else
return str
end
end
-- normalize ingredient name input, Lead Bar=>¦Lead Bar¦, Iron/Lead Bar => ¦Iron Bar¦Lead Bar¦, Lead/Iron Bar => ¦Iron Bar¦Lead Bar¦ ....
local normalize = function(name)
local result = '¦'
for k, v in ipairs(split(name)) do
result = result .. itemname(v) .. '¦'
end
return result
end
local escape = function(str)
return str:gsub("'", "\\'"):gsub("'", "\\'")
end
local enclose = function(str)
return "'" .. escape(str) .. "'"
end
local getItemGroupName = function(item)
if item == 'Wood' or item == 'Wood2' or item == 'Wood3' then
return 'Any Wood'
elseif item == 'Copper Bar' or item == 'Tin Bar' then
return 'Any Bar'
end
end
local normalizeStation = function(station)
if station == 'Altar' then
station = 'Altar2'
end
return station
end
local normalizeVersion = function(_version)
return ''
end
local criStr = function(args)
local constraints = {}
-- station = ? and station != ?
local _station = trim(args['station'] or '')
local _stationnot = trim(args['stationnot'] or '')
local str = ''
if _station ~= '' then
for _, v in ipairs(explode('/', _station)) do
if str ~= '' then
str = str .. ' OR '
end
str = str .. "station = " .. enclose(normalizeStation(v))
end
end
if _stationnot ~= '' then
if str ~= '' then
str = '(' .. str .. ')'
end
for _, v in ipairs(explode('/', _stationnot)) do
if str ~= '' then
str = str .. ' AND '
end
str = str .. 'station <> ' .. enclose(normalizeStation(v))
end
end
constraints['station'] = str
local _enemy = trim(args['enemy'] or '')
local _enemynot = trim(args['enemynot'] or '')
local str = ''
if _enemy ~= '' then
for _, v in ipairs(explode('/', _enemy)) do
if str ~= '' then
str = str .. ' OR '
end
if mw.ustring.sub(v, 1, 5) == 'LIKE ' then
str = str .. "enemy LIKE " .. enclose(trim(mw.ustring.sub(v, 6)))
else
str = str .. 'enemy=' .. enclose(v)
end
end
end
if _enemynot ~= '' then
if str ~= '' then
str = '(' .. str .. ')'
end
for _, v in ipairs(explode('/', _enemynot)) do
if str ~= '' then
str = str .. ' AND '
end
if mw.ustring.sub(v, 1, 5) == 'LIKE ' then
str = str .. "enemy NOT LIKE " .. enclose(trim(mw.ustring.sub(v, 6)))
else
str = str .. 'enemy <> ' .. enclose(v)
end
end
end
if str ~= '' then
constraints['enemy'] = str
end
-- ingredient = ?
local _ingredient = trim(args['ingredient'] or '')
if _ingredient ~= '' then
local str = ''
for _, v in ipairs(explode('/', _ingredient)) do
if str ~= '' then
str = str .. ' OR '
end
if mw.ustring.sub(v, 1, 1) == '#' then
str = str .. "ingredients HOLDS LIKE '%¦" .. escape(mw.ustring.sub(v, 2)) .. "¦%'"
elseif mw.ustring.sub(v, 1, 5) == 'LIKE ' then
str = str .. "ingredients HOLDS LIKE '%¦" .. escape(trim(mw.ustring.sub(v, 6))) .. "¦%'"
else
str = str .. "ingredients HOLDS LIKE '%¦" .. escape(v) .. "¦%'"
-- any xxx
local group = getItemGroupName(v)
if group then
str = str .. " OR ingredients HOLDS LIKE '%¦" .. escape(group) .. "¦%'"
end
end
end
constraints['ingredient'] = str
end
--versions
local _version = normalizeVersion(args['version'] or args['versions'] or '')
if _version ~= '' then
constraints['version'] = 'version = '..enclose(_version)
end
--factions
local _faction = args['faction'] or ''
if _faction ~= '' then
constraints['faction'] = 'faction = '..enclose(_faction)
end
--charactergroup
local _charactergroup = args['charactergroup'] or ''
if _charactergroup ~= '' then
constraints['charactergroup'] = 'charactergroup = '..enclose(_charactergroup)
end
local where = ''
if constraints['station'] then
where = constraints['station']
end
if constraints['enemy'] then
if where ~= '' then
where = where .. ' AND '
end
where = where .. '(' .. constraints['enemy'] .. ')'
end
if constraints['ingredient'] then
if where ~= '' then
where = where .. ' AND '
end
where = where .. '(' .. constraints['ingredient'] .. ')'
end
if constraints['version'] then
if where ~= '' then
where = where .. ' AND '
end
where = where .. '(' .. constraints['version'] .. ')'
end
if constraints['faction'] then
if where ~= '' then
where = where .. ' AND '
end
where = where .. '(' .. constraints['faction'] .. ')'
end
if constraints['charactergroup'] then
if where ~= '' then
where = where .. ' AND '
end
where = where .. '(' .. constraints['charactergroup'] .. ')'
end
return where
end
local resultCell = function(row, showResultId, needLink, noVersion, template)
local enemy, star, health = row['enemy'], row['star'], row['health']
local str = ''
local args = {anchor = resultanchor, nolink = not needLink, class='multi-line'}
if showResultId then
args['id'] = resultid
end
if resultimage then
args['image'] = resultimage
end
if resulttext then
args[2] = resulttext
end
if quality ~= '' then
args['icons'] = 'n'
end
str = str .. enemyLink(enemy, args)
if template then
local template_str = currentFrame:expandTemplate{ title = template, args = {
link = needLink, showid = showResultId, noversion = noVersion,
enemy=enemy, star=star, health=health,
} }
str = template_str:gsub('@@@@', str)
end
return str
end
local ingredientsCell = function(args)
local str = '<ul>'
for _, v in ipairs(explode('^', args)) do
str = str .. '<li>'
local item, amount = v:match('^(.-)¦(.-)$')
local s
for _, itemname in ipairs(split(item)) do
if s then
s = s .. l10n('ingredients_sep') .. enemyLink(itemname)
else
s = enemyLink(itemname)
end
end
str = str .. s
if amount ~= '1' then
str = str .. ' <span class="note-text">('..amount..')</span>'
end
str = str .. '</li>'
end
str = str .. '</ul>'
return str
end
local stationLevelLink = function(station, level)
return '<div class="station-level-container" title="' .. l10n('Required station level') .. '">'
.. '[[File:Crafting Station Level Star.png|link=' .. station .. ']]'
.. '<span>' .. level .. '</span>'
.. '</div>'
end
local stationCell = function(station, level, options)
options = options or {wrap = 'y', suffixLinkWithItemTag = false}
if station == 'By Hand' then
return l10n('By Hand')
elseif true == is_crafting_station(station) then
-- station == 'Workbench' or station == 'Forge' or station == 'Cauldron' or station == 'Fermenter' then
local linkItem = enemyLink(station, options)
if (level or '') ~= '' then
linkItem = linkItem .. '<br>' .. stationLevelLink(station, level)
end
return linkItem
-- return enemyLink(station, options)
elseif station == "Station One and Station Two" then
return enemyLink("Station One", options) .. l10n('And').. enemyLink('Station Two', {mode = 'text'})
else
return station
end
end
-- for extract.
local compactStation = function(station)
if station == 'By Hand' then
return ''
else
return l10n('compact_before') .. station .. l10n('compact_after')
end
end
local propCell = function(prop)
if prop == 'args' then
return 'Ingredients'
elseif prop == 'stationlevel' then
return 'Station level'
elseif prop == 'blockpower' then
return 'Blocking power'
elseif prop == 'movementspeed' then
return 'Movement speed'
elseif prop == 'parrybonus' then
return 'Parry bonus'
elseif prop == 'parryforce' then
return 'Parry force'
end
return firstToUpper(prop)
end
local getFlags = function(args)
local needCate = 1
local needLink = true
local _cate = trim(args['cate'] or '')
if _cate == 'force' or _cate == 'all' then
needCate = 2
elseif _cate == 'n' or _cate == 'no' then
needCate = nil
end
local _link = trim(args['link'] or '')
if _link == 'y' or _link == 'yes' or _link == 'force' then
needLink = true
elseif _link == 'n' or _link == 'no' then
needLink = false
end
return needCate, needLink
end
local addCate, cateStr -- for table body. init in p.query
local tableStart = function(title, withStation)
local header_
local str = '<div class="crafts enemies '.. (getArg('class') or '')
local _id = (getArg('id') or '')
if _id ~= '' then
str = str .. '" id="'.. _id
end
local _css = (getArg('css') or getArg('style') or '')
if _css ~= '' then
str = str .. '" style="'.. _css
end
str = str .. '"><div class="wrap"><table '
if (getArg('sortable') or 'y'):sub(1,1) ~= 'n' then
str = str .. 'class="sortable" '
end
str = str .. 'cellpadding="0" cellspacing="0">'
local _title = title or ''
if _title ~= '' then
str = str .. '<caption>' .. _title .. '</caption>'
end
local _i, _field
str = str .. '<tr>'
_i = 1
_field = 'col-A-1'
while getArg(_field) do
if not extCols_A then
extCols_A = {}
end
table.insert(extCols_A, _field)
str = str .. '<th>'.. getArg(_field) ..'</th>'
_i = _i + 1
_field = 'col-A-' .. _i
end
str = str .. '<th class="result">' .. (getArg('header-result') or l10n('Result')) .. '</th>'
_i = 1
_field = 'col-B-1'
while getArg(_field) do
if not extCols_B then
extCols_B = {}
end
table.insert(extCols_B, _field)
str = str .. '<th>'.. getArg(_field) ..'</th>'
_i = _i + 1
_field = 'col-B-' .. _i
end
str = str .. '<th class="ingredients">' .. (getArg('header-ingredients') or l10n('Ingredients')) .. '</th>'
_i = 1
_field = 'col-C-1'
while getArg(_field) do
if not extCols_C then
extCols_C = {}
end
table.insert(extCols_C, _field)
str = str .. '<th>'.. getArg(_field) ..'</th>'
_i = _i + 1
_field = 'col-C-' .. _i
end
if withStation then
_i = 1
_field = 'station-col-before-1'
while getArg(_field) do
if not extCols_stationBefore then
extCols_stationBefore = {}
end
table.insert(extCols_stationBefore, _field)
str = str .. '<th class="station">'.. getArg(_field) ..'</th>'
_i = _i + 1
_field = 'station-col-before-' .. _i
end
str = str .. '<th class="station">' .. (getArg('header-station') or l10n('Crafting Station')) .. '</th>'
_i = 1
_field = 'station-col-after-1'
while getArg(_field) do
if not extCols_stationAfter then
extCols_stationAfter = {}
end
table.insert(extCols_stationAfter, _field)
str = str .. '<th class="station">'.. getArg(_field) ..'</th>'
_i = _i + 1
_field = 'station-col-after-' .. _i
end
end
_i = 1
_field = 'col-D-1'
while getArg(_field) do
if not extCols_D then
extCols_D = {}
end
table.insert(extCols_D, _field)
str = str .. '<th>'.. getArg(_field) ..'</th>'
_i = _i + 1
_field = 'col-D-' .. _i
end
str = str .. '</tr>'
return str
end
local tableEnd = function(rows_count, expectedrows)
local str = '</table><div style="display: none">total: '..rows_count..' row(s)</div></div></div>'
if expectedrows and rows_count ~= expectedrows then
str = str .. '[[Category:'.. l10n('cate_unexpected_rows_count') .. ']]'
end
if not expectedrows and rows_count == 0 then
str = str .. '[[Category:'.. l10n('cate_no_row') .. ']]'
end
return str
end
local tableBodyUpgrades = function(noResultsText, result, showResultId, withStation, needGroup, needCate, needLink, rootpagename, title, expectedrows, template, stationGroup)
if next(result) == nil then
return "''" .. (noResultsText or 'No results') .. "''"
end
propertyOrder = {
enemy = 10,
star = 40,
charactergroup = 50,
faction = 60,
health = 70,
damage_blunt = 190,
damage_slash = 200,
damage_pierce = 210,
damage_chop = 220,
damage_pickaxe = 230,
damage_fire = 240,
damage_frost = 250,
damage_lightning = 260,
damage_poison = 270,
damage_spirit = 280
}
-- inputArgs = {} -- @TODO: Mave
-- matches the definition and order in Template:Enemies
properties = {
'enemy',
'star',
'charactergroup',
'faction',
'health',
'damage_blunt',
'damage_slash',
'damage_pierce',
'damage_chop',
'damage_pickaxe',
'damage_fire',
'damage_frost',
'damage_lightning',
'damage_poison',
'damage_spirit',
}
local count = 0
local output = {}
-- local output2 = {}
-- local iOutput = 0;
for _, row in ipairs(result) do
count = count + 1
for _, prop in ipairs(properties) do
arg = row[prop] or ''
local k = {}
output[prop] = (output[prop] or '') .. 'xxxyyyzzz' .. arg
-- k["prop"] = prop
-- k["value"] = output[prop]
-- output2[iOutput] = k
-- iOutput = iOutput + 1
end
end
local countToCompare = count - 1
emptyString = ''
for i=1, countToCompare do
emptyString = emptyString .. 'xxxyyyzzz'
end
local tableStart = tableStart()
local tableContents = ''
lastOrder = 800
for prop, str in pairs(output) do
-- for _, var in ipairs(output2) do
-- prop = var["prop"]
-- str = var["value"]
stringContents = string.sub(str, 10)
if stringContents ~= emptyString then
if prop == 'quality' then
tableStart = tableStart .. str:gsub('xxxyyyzzz', '</th><th>')
else
order = (propertyOrder[prop] or lastOrder)
lastOrder = lastOrder - 1
tableContents = tableContents .. '<tr data-prop="' .. prop .. '" data-order="' .. order .. '>'
local td = '<td'
local class = prop
if prop == 'args' then
class = 'ingredients'
end
td = td .. ' class="' .. class .. '"'
td = td .. ' data-prop="' .. prop .. '"'
td = td .. '>'
-- local replaced, _ = str:gsub('xxxyyyzzz', '</td>' .. td)
local rowContents = ''
for _, v in ipairs(explode('xxxyyyzzz', str)) do
if v ~= '' then
if prop == 'station' then
v = stationCell(v)
end
rowContents = rowContents .. td .. v .. '</td>'
end
end
-- local rowContents = replaced
tableContents = tableContents .. '<td data-propHeader="' .. prop .. '">'
.. propCell(prop)
.. '</td>'
.. rowContents
tableContents = tableContents .. '</tr>'
end
end
end
return tableStart .. tableContents .. tableEnd(-1, -1)
end
local tableRow = function(str, row, current_station, station_count, rows_count, showResultId, withStation, needCate, needLink, needGroup, current_result, result_count, current_result_ext, result_ext_count, template, stationGroup)
local str_w = '' -- before result col
local str_x = '' -- between result and ingredients cols
local str_y = '' -- between ingredients and station cols
local str_z = '' -- after station
local str_resultCell = ''
local result_index = getArg('result-index-#'..rows_count) or getArg('result-index-'..row['enemy']) or getArg('result-index-'..row['enemy'])
str = str .. '<tr data-rowid="'..tostring(rows_count)..'">'
if needGroup then
local result = row['enemy']..'|'..row['star']
-- grouping result col
if current_result == result then -- is same group ??
result_count = result_count + 1
else
--new group:
-- rowspan value for prev group, if needed.
if result_count then
str = str:gsub("yyyrowspanyyy", tostring(result_count))
end
-- begin this group
current_result = result
result_count = 1
str_resultCell = '<td class="result" rowspan="yyyrowspanyyy">'.. resultCell(row, showResultId, needLink, false, template).. '</td>'
end
-- grouping ext cols
if result_index and (current_result_ext == result_index) then -- is same group ??
result_ext_count = result_ext_count + 1
else
--new group:
-- rowspan value for prev group, if needed.
if result_ext_count then
str = str:gsub("zzzrowspanzzz", tostring(result_ext_count))
end
-- begin this group
current_result_ext = result_index
result_ext_count = 1
if extCols_A then
for _, v in ipairs(extCols_A) do
if result_index then
str_w = str_w .. '<td class="'..v..'" rowspan="zzzrowspanzzz">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_w = str_w .. '<td class="'..v..'" rowspan="zzzrowspanzzz"></td>'
end
end
end
if extCols_B then
for _, v in ipairs(extCols_B) do
if result_index then
str_x = str_x .. '<td class="'..v..'" rowspan="zzzrowspanzzz">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_x = str_x .. '<td class="'..v..'" rowspan="zzzrowspanzzz"></td>'
end
end
end
if extCols_C then
for _, v in ipairs(extCols_C) do
if result_index then
str_y = str_y .. '<td class="'..v..'" rowspan="zzzrowspanzzz">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_y = str_y .. '<td class="'..v..'" rowspan="zzzrowspanzzz"></td>'
end
end
end
if extCols_D then
for _, v in ipairs(extCols_D) do
if result_index then
str_z = str_z .. '<td class="'..v..'" rowspan="zzzrowspanzzz">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_z = str_z .. '<td class="'..v..'" rowspan="zzzrowspanzzz"></td>'
end
end
end
end
else
if extCols_A then
for _, v in ipairs(extCols_A) do
if result_index then
str_w = str_w .. '<td class="'..v..'">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_w = str_w .. '<td class="'..v..'"></td>'
end
end
end
if extCols_B then
for _, v in ipairs(extCols_B) do
if result_index then
str_x = str_x .. '<td class="'..v..'">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_x = str_x .. '<td class="'..v..'"></td>'
end
end
end
if extCols_C then
for _, v in ipairs(extCols_C) do
if result_index then
str_y = str_y .. '<td class="'..v..'">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_y = str_y .. '<td class="'..v..'"></td>'
end
end
end
if extCols_D then
for _, v in ipairs(extCols_D) do
if result_index then
str_z = str_z .. '<td class="'..v..'">' .. (getArg(result_index .. '-row-' .. v) or '') .. '</td>'
else
str_z = str_z .. '<td class="'..v..'"></td>'
end
end
end
str_resultCell = '<td class="result">'.. resultCell(row, showResultId, needLink, false, template).. '</td>'
end
-- str = str .. str_w .. str_resultCell .. str_x .. '<td class="ingredients">' .. ingredientsCell(row['args']).. '</td>' .. str_y
if withStation then
local stationName = row['station'] or ''
local stationLevel = row['stationlevel'] or ''
local station = stationName .. stationLevel -- @TODO: Mave
if stationGroup then
if current_station == station then -- is same group ??
station_count = station_count + 1
else
--new group:
-- rowspan value for prev group, if needed.
if station_count then
str = str:gsub("xxxrowspanxxx", tostring(station_count))
end
-- begin this group
current_station = station
station_count = 1
local station_index = getArg('station-index-'..station)
-- station before:
if extCols_stationBefore then
for _, v in ipairs(extCols_stationBefore) do
if station_index then
str = str .. '<td class="station station-7 station- '..v..'" rowspan="xxxrowspanxxx">' .. (getArg(station_index .. '-row-' .. v) or '') .. '</td>'
else
str = str .. '<td class="station station-8 '..v..'" rowspan="xxxrowspanxxx"></td>'
end
end
end
str = str .. '<td class="station station-15" data-station="' .. stationName .. '" data-stationlevel="' .. stationLevel .. '" rowspan="xxxrowspanxxx">'.. stationCell(stationName, stationLevel) ..'</td>'
-- station after:
if extCols_stationAfter then
for _, v in ipairs(extCols_stationAfter) do
if station_index then
str = str .. '<td class="station station-9 '..v..'" rowspan="xxxrowspanxxx">' .. (getArg(station_index .. '-row-' .. v) or '') .. '</td>'
else
str = str .. '<td class="station station-10 '..v..'" rowspan="xxxrowspanxxx"></td>'
end
end
end
end
else
if current_station == station then -- is same group ??
station_count = station_count + 1
else
current_station = station
station_count = 1
end
local station_index = getArg('station-index-'..station)
-- station before:
if extCols_stationBefore then
for _, v in ipairs(extCols_stationBefore) do
if station_index then
str = str .. '<td class="station station-11 '..v..'">' .. (getArg(station_index .. '-row-' .. v) or '') .. '</td>'
else
str = str .. '<td class="station station-12 '..v..'"></td>'
end
end
end
str = str .. '<td class="station station-1">'.. stationCell(stationName, stationLevel) ..'</td>'
-- station after:
if extCols_stationAfter then
for _, v in ipairs(extCols_stationAfter) do
if station_index then
str = str .. '<td class="station station-13 '..v..'">' .. (getArg(station_index .. '-row-' .. v) or '') .. '</td>'
else
str = str .. '<td class="station station-14 '..v..'"></td>'
end
end
end
end
end
str = str .. str_z ..'</tr>'
return str, current_station, station_count, current_result, result_count, current_result_ext, result_ext_count
end
local extRows = function(withStation, isTop)
local prefix
if isTop then
prefix = 'topextrow-'
else
prefix = 'extrow-'
end
local returnstr = ''
local valid = true
local p
local str
local _i = 1
local temp
while valid do
local i = tostring(_i) .. '-'
p = prefix .. i
valid = false
str = '<tr data-'..prefix..'id="'..tostring(_i)..'">'
if extCols_A then
for _, v in ipairs(extCols_A) do
temp = getArg(p..v)
if temp then
valid = true
str = str .. '<td class="'..v..'">' .. temp .. '</td>'
else
str = str .. '<td class="'..v..'"></td>'
end
end
end
temp = getArg(p..'col-result')
if temp then
valid = true
str = str .. '<td class="result">' .. temp .. '</td>'
else
str = str .. '<td class="result"></td>'
end
if extCols_B then
for _, v in ipairs(extCols_B) do
temp = getArg(p..v)
if temp then
valid = true
str = str .. '<td class="'..v..'">' .. temp .. '</td>'
else
str = str .. '<td class="'..v..'"></td>'
end
end
end
temp = getArg(p..'col-ingredients')
if temp then
valid = true
str = str .. '<td class="ingredients">' .. temp .. '</td>'
else
str = str .. '<td class="ingredients"></td>'
end
if extCols_C then
for _, v in ipairs(extCols_C) do
temp = getArg(p..v)
if temp then
valid = true
str = str .. '<td class="'..v..'">' .. temp .. '</td>'
else
str = str .. '<td class="'..v..'"></td>'
end
end
end
if withStation then
-- station before:
if extCols_stationBefore then
for _, v in ipairs(extCols_stationBefore) do
temp = getArg(p..v)
if temp then
valid = true
str = str .. '<td class="station station-1 '..v..'">' .. temp .. '</td>'
else
str = str .. '<td class="station station-2 '..v..'"></td>'
end
end
end
temp = getArg(p..'col-station')
if temp then
valid = true
str = str .. '<td class="station station-3">' .. temp .. '</td>'
else
str = str .. '<td class="station station-4"></td>'
end
-- station after:
if extCols_stationAfter then
for _, v in ipairs(extCols_stationAfter) do
temp = getArg(p..v)
if temp then
valid = true
str = str .. '<td class="station station-5 '..v..'">' .. temp .. '</td>'
else
str = str .. '<td class="station station-6 '..v..'"></td>'
end
end
end
end
if extCols_D then
for _, v in ipairs(extCols_D) do
temp = getArg(p..v)
if temp then
valid = true
str = str .. '<td class="'..v..'">' .. temp .. '</td>'
else
str = str .. '<td class="'..v..'"></td>'
end
end
end
str = str .. '</tr>'
if valid then
_i = _i + 1
returnstr = returnstr .. str
end
end
return returnstr
end
local tableBody = function(result, showResultId, withStation, needGroup, needCate, needLink, rootpagename, title, expectedrows, template, stationGroup)
local str = tableStart()
-- top ext rows:
str = str .. extRows(withStation, true)
-- main rows:
local current_station
local station_count
local rows_count = 0
local current_result
local result_count
local current_result_ext
local result_ext_count
for _, row in ipairs(result) do
print("cool")
rows_count = rows_count + 1
-- table row:
-- str, current_station, station_count, current_result, result_count, current_result_ext, result_ext_count = tableRow(str, row, current_station, station_count, rows_count, showResultId, withStation, needCate, needLink, needGroup, current_result, result_count, current_result_ext, result_ext_count, template, stationGroup)
str2 = tableRow(str, row, current_station, station_count, rows_count, showResultId, withStation, needCate, needLink, needGroup, current_result, result_count, current_result_ext, result_ext_count, template, stationGroup)
-- cate:
-- if needCate then
-- if needCate == 2 or rootpagename == currentFrame:expandTemplate{ title = 'tr', args = {row['result'], lang=lang} } then
-- addCate(row['station'])
-- end
-- end
end
-- -- rowspan value for last station group and result group
-- if withStation and station_count and stationGroup then
-- str = str:gsub("xxxrowspanxxx", tostring(station_count))
-- end
-- if needGroup then
-- str = str:gsub("yyyrowspanyyy", tostring(result_count))
-- str = str:gsub("zzzrowspanzzz", tostring(result_ext_count))
-- end
-- -- ext rows:
-- str = str .. extRows(withStation)
-- -- table end
str2 = str2 .. tableEnd(rows_count, expectedrows)
-- cate
-- if needCate then
-- str = str .. cateStr()
-- end
return str2
end
-----------------------------------------------------------------
local p = {}
-- for {{Enemies/register}}
p.register = function(frame)
local args = frame:getParent().args
--store
frame:callParserFunction('#cargo_store:_table=Enemies', {
enemy = trim(args['enemy'] or ''),
enemyid = trim(args['enemyid'] or ''),
enemyprefabname = trim(args['enemyprefabname'] or ''),
star = string.gsub(trim(args['star'] or ''), "%p", "%%%1"),
charactergroup = trim(args['charactergroup'] or ''),
faction = trim(args['faction'] or ''),
health = trim(args['health'] or ''),
weakness_blunt = trim(args['weakness_blunt'] or ''),
weakness_slash = trim(args['weakness_slash'] or ''),
weakness_pierce = trim(args['weakness_pierce'] or ''),
weakness_chop = trim(args['weakness_chop'] or ''),
weakness_pickaxe = trim(args['weakness_pickaxe'] or ''),
weakness_fire = trim(args['weakness_fire'] or ''),
weakness_frost = trim(args['weakness_frost'] or ''),
weakness_lightning = trim(args['weakness_lightning'] or ''),
weakness_poison = trim(args['weakness_poison'] or ''),
weakness_spirit = trim(args['weakness_spirit'] or ''),
damage_blunt = trim(args['damage_blunt'] or ''),
damage_slash = trim(args['damage_slash'] or ''),
damage_pierce = trim(args['damage_pierce'] or ''),
damage_chop = trim(args['damage_chop'] or ''),
damage_pickaxe = trim(args['damage_pickaxe'] or ''),
damage_fire = trim(args['damage_fire'] or ''),
damage_frost = trim(args['damage_frost'] or ''),
damage_lightning = trim(args['damage_lightning'] or ''),
damage_poison = trim(args['damage_poison'] or ''),
damage_spirit = trim(args['damage_spirit'] or ''),
})
end -- p.register
-- for {{Template:Enemies}}
p.query = function(frame)
currentFrame = frame -- global frame cache
local args = frame:getParent().args
inputArgs = args
lang = frame.args['lang'] or 'en'
resultanchor = trim(args['resultanchor'] or '')
addCate, cateStr = (function()
local cate = l10n('station_cate')
local cateCache = {}
local addCate = function(station)
cateCache[station] = true
end
local cateStr = function()
local str = ''
for station, _ in pairs(cateCache) do
str = str .. '[[Category:'..(cate[station] or frame:expandTemplate{ title = 'tr', args = {station, lang=lang, link='y'}})..']]'
end
if str ~= '' then
str = '[[Category:'.. l10n('cate_craftable').. ']]' .. str
end
return str
end
return addCate, cateStr
end)()
local where = trim(args['where'] or '')
if where == '' then
where = criStr(args)
end
-- no constraint no result.
if where == '' then
return '<span style="color:red;font-weight:bold;">Enemies: No constraint</span>'
end
-- format:
local needCate, needLink = getFlags(args)
local needGroup = true
if (getArg('grouping') or 'y'):sub(1,1) == 'n' then
needGroup = false
end
local showResultId = false
if trim(args['showresultid'] or '') ~= '' then
showResultId = true
end
local _title = trim(args['title'] or '')
local _expectedrows = trim(args['expectedrows'] or '')
if _expectedrows ~= '' then
_expectedrows = tonumber(_expectedrows)
else
_expectedrows = nil
end
local rootpagename = mw.title.getCurrentTitle().rootText
local noResultsText = 'No results'
if args['result'] or '' ~= '' then
noResultsText = 'This enemy cannot be enemied'
end
if trim(args['nostation'] or '') ~= '' then
-- no station
-- query, still need contain station field for cate.
local result = mw.ext.cargo.query('Enemies', 'enemy, star, charactergroup, faction, health', {
where = where,
groupBy = "enemy, star, charactergroup, faction",
orderBy = "enemy, star, charactergroup, faction", -- Don't order by station
limit = 2000,
})
return tableBody(result, showResultId, false, needGroup, needCate, needLink, rootpagename, _title, _expectedrows, getArg('resulttemplate'), false)
else
-- with station
local stationGroup = true
if (getArg('stationgrouping') or 'y'):sub(1,1) == 'n' then
stationGroup = false
end
-- query
local result = mw.ext.cargo.query('Enemies', 'enemy, star, charactergroup, faction, health', {
where = where,
groupBy = "enemy, star, charactergroup, faction",
orderBy = "enemy, star, charactergroup, faction", -- order by station first for station grouping.
limit = 2000,
})
return tableBody(result, showResultId, true, needGroup, needCate, needLink, rootpagename, _title, _expectedrows, getArg('resulttemplate'), stationGroup)
end
end -- p.query
-- for {{enemies/extract}}
p.extract = function(frame)
currentFrame = frame -- global frame cache
local args = frame:getParent().args
inputArgs = args
lang = frame.args['lang'] or 'en'
--l10n_table = l10n_info[lang] or l10n_info['en']
local where = trim(args['where'] or '')
if where == '' then
where = criStr(args)
end
-- no constraint no result.
if where == '' then
return '<span style="color:red;font-weight:bold;">Enemies/extract: No constraint</span>'
end
-- query:
local result = mw.ext.cargo.query('Enemies', 'enemy, enemyid, enemyprefabname, star, charactergroup, faction, health, weakness_blunt, weakness_slash, weakness_pierce, weakness_chop, weakness_pickaxe, weakness_fire, weakness_frost, weakness_lightning, weakness_poison, weakness_spirit, damage_blunt, damage_slash, damage_pierce, damage_chop, damage_pickaxe, damage_fire, damage_frost, damage_lightning, damage_poison, damage_spirit', {
where = where,
groupBy = "enemy, enemyid, star, charactergroup, faction",
orderBy = "star, enemy, enemyid, charactergroup, faction DESC", -- Don't order by station
limit = 20, -- enough.
})
-- output
local mode = getArg('mode')
local sep = getArg('sep') or getArg('seperator')
if not mode or mode == 'compact' or mode == '' then
--default mode = compact
local sep = sep or l10n('default_sep_compact')
local withResult = getArg('withresult')
local withStation = not getArg('nostation')
local withVersion = not getArg('noversion')
local str = nil
for _, row in ipairs(result) do
if str then
str = str .. sep
else
str = ''
end
str = str .. '<span class="recipe compact">'
if withVersion then
if row['version'] ~= '' then
str = str ..currentFrame:expandTemplate{ title = 'version icons', args = {row['version']} }..': '
end
end
local ingFlag = nil
for _, v in ipairs(explode('^', row['args'])) do
if ingFlag then
str = str .. ' + '
else
ingFlag = true
end
local item, amount = v:match('^(.-)¦(.-)$')
if amount ~= '1' then
str = str .. amount .. ' '
end
local s
for _, itemname in ipairs(split(item)) do
if s then
s = s .. " / " .. enemyLink(itemname, {mode='image'})
else
s = enemyLink(itemname, {mode='image'})
end
end
str = str .. s
end
if withResult then
str = str .. ' = '
if row['amount'] ~= '1' then
str = str .. row['amount'] .. ' '
end
local args = {mode='image'}
if row['resultimage'] then
args['image'] = row['resultimage']
end
str = str .. enemyLink(row['result'], args)
end
if withStation then
str = str .. compactStation(row['station'])
end
str = str..'</span>'
end
return str
elseif mode == 'ingredients' then
local sep = sep or l10n('default_sep_ingredients')
local str = ''
for _, row in ipairs(result) do
if str ~= '' then
str = str .. sep
end
str = str .. ingredientsCell(row['args'])
end
return '<div class="crafting-ingredients">'..str..'</div>'
elseif mode == 'station' then
-- only return first row.
for _, row in ipairs(result) do
return stationCell(row['station'], '', {})
end
elseif mode == 'result' then
-- only return first row.
local needCate, needLink = getFlags(args)
for _, row in ipairs(result) do
return resultCell(row, getArg('showresultid'), needLink, true, getArg('resulttemplate'))
end
elseif mode == 'ingredients-buy' then
-- only process first row.
for _, row in ipairs(result) do
local value = 0
for _, v in ipairs(explode('^', row['args'])) do
local item, amount = v:match('^(.-)¦(.-)$')
value = value + require('Module:Iteminfo').getItemStat( tonumber(currentFrame:expandTemplate{ title = 'itemIdFromName', args = {item, lang='en'} }) or 0, 'value' ) * amount
end
return value
end
elseif mode == 'ingredients-sell' then
-- only process first row.
for _, row in ipairs(result) do
local value = 0
for _, v in ipairs(explode('^', row['args'])) do
local item, amount = v:match('^(.-)¦(.-)$')
value = value + math.floor(require('Module:Iteminfo').getItemStat( tonumber(currentFrame:expandTemplate{ title = 'itemIdFromName', args = {item, lang='en'} }) or 0, 'value' )/5) * amount
end
return value
end
else
return '<span style="color:red;font-weight:bold;">Enemies/extract: Invalid mode</span>'
end
end -- p.extract
-- count
p.count = function(frame)
local args = frame:getParent().args
local where = trim(args['where'] or '')
if where == '' then
where = criStr(args)
end
-- no constraint no result.
if where == '' then
return
end
-- query: since we must use group by to eliminate duplicates, so we can not use COUNT() to get row count directly.
local result = mw.ext.cargo.query('Enemies', 'enemy, enemyid, enemyprefabname, star, charactergroup, faction, health, weakness_blunt, weakness_slash, weakness_pierce, weakness_chop, weakness_pickaxe, weakness_fire, weakness_frost, weakness_lightning, weakness_poison, weakness_spirit, damage_blunt, damage_slash, damage_pierce, damage_chop, damage_pickaxe, damage_fire, damage_frost, damage_lightning, damage_poison, damage_spirit', {
where = where,
groupBy = "enemy, enemyid, star, charactergroup, faction",
limit = 2000,
})
-- count
local count = 0
for _, row in ipairs(result) do
count = count + 1
end
return count
end -- p.count
-- return "yes" or ""
p.exist = function(frame)
local args = frame:getParent().args
local where = trim(args['where'] or '')
if where == '' then
where = criStr(args)
end
-- no constraint no result.
if where == '' then
return
end
-- query:
local result = mw.ext.cargo.query('Enemies', 'enemy', {
where = where,
limit = 1, -- enough.
})
-- output
for _, row in ipairs(result) do
return 'yes'
end
end -- p.exist
p.tableBody = tableBody
return p