此站点为镜像站,如有编辑wiki的意愿请前往主站进行编辑
加入Noita中文维基群获取更多wiki编辑上的帮助。
→加入游戏社区|Noita魔法群|Noita交流群|Noita贴吧|与更多玩家一起游玩Noita。
此站点为镜像站,如有编辑wiki的意愿请前往主站进行编辑。
加入Noita中文维基群获取更多wiki编辑上的帮助。
→加入游戏社区|Noita魔法群|
|Noita交流群|Noita贴吧|
与更多玩家一起游玩Noita。
模块:DataQuery
该脚本使用的数据来源于模块:DataQuery/Enemies、模块:DataQuery/Materials和模块:DataQuery/Spells 一般来讲该模块只应使用于模板中。
使用
参数
参数 | 描述 |
---|---|
q?tables |
查询数据表,目前可用的为"Spells、Enemies和Materials" |
combineResultAsRow |
行转列,主要用于Infobox |
default |
当查询结果为空时,返回的数据 |
intro |
拼接到结果之前的wiki文本 |
outro |
拼接到结果之后的wiki文本 |
template |
渲染每一行数据的模板 |
q?tier |
(法术专用)法术等级, 过滤方式为AND |
q?id |
(法术专用)用法术id查询法术 |
q?noProbabilityZero |
(法术专用),当值为true时将过滤对应等级下生成权重为0的法术,注意因为这个原因,只有在指定搜索等级时才有用。 |
q?groupKey |
(法术和敌人)用于筛选一类法术或敌人, 过滤方式为AND |
q?link |
(材料专用)用于筛选一类材料, 过滤方式为AND |
q?tags |
(材料专用),用tag筛选一类材料,过滤方式为AND |
q?name |
(法术、敌人和材料)查询名称,可使用半角逗号分隔以查询多个,可使用值为英文名、官方中文名;排他参数。 |
q?type |
(法术、敌人和材料)查询类型,可使用半角逗号分隔以查询多个;投射物(Projectile), 静态投射物(Static projectile), 被动(Passive), 实用(Utility), 投射修正(Projectile modifier), 材料(Material), 多重释放(Multicast);指定该参数时仍将应用其他过滤条件。敌人可查询类型为:杂项类,亡灵类,粘液类,蜘蛛类,席西类,机械类,支援类,炼金术师,元素魔物,法师类,游魂类,蠕虫类,被动生物,最终BOSS,小BOSS,BOSS召唤的小怪,平行世界的幻影,你,其他。材料可查询类型为:fire,static,sand,liquid,gas,plant,box2d,special,badjokes,hax。 |
q?herd |
(敌人、材料)查询对应herd的敌人,其实材料查询id也用了这个,算是一个名称不对实际效果的代码复用,过滤方式为AND |
delimiter |
在你所筛选的数据当中穿插文字。 |
示例
{{#invoke:DataQuery|main |q?tables=Spells |q?type=其他 |intro={{{!}} class="mw-collapsible" style="width:100%;" {{!}}+ {{!}} <div style="display:flex;column-gap:0.8rem;row-gap:0.8rem;justify-content:center;flex-wrap:wrap"> |outro=</div> {{!}}} |template=SpellQuery/row2 |default=''There are no spells of the specified query.'' }} {{#invoke:DataQuery|main |q?tables=Enemies |q?type= |q?herd=slimes |intro={{{!}} class="mw-collapsible" style="width:100%;" {{!}}+ {{!}} <div style="display:flex;column-gap:0.5rem;row-gap:0.5rem;justify-content:center;flex-wrap:wrap"> |outro=</div> {{!}}} |template=EnemyQuery/row |default=''未查询到数据'' }} {{#invoke:DataQuery|main |q?tables=Enemies |q?type=杂项类 |intro= |outro= |delimiter={{*}} |template=EnemyNav/List |default=''未查询到数据'' {{#invoke:DataQuery|main |q?tables=Materials |q?tags=sand_other,burnable |intro= |outro= |delimiter={{*}} |template=MaterialNav/List |default=''未查询到数据'' }} {{#invoke:DataQuery|main |q?tables=Materials |q?link=砖块 |combineResultAsRow=1 |template=Infobox material}} }}
[[|一分为十]] 施放魔杖中下一个法术的复制品十次 [[File:|link=|alt=遁入虚空|48px]] [[|遁入虚空]] 施法者进入无界之界 |
Happonuljaska
哈波努利亚斯卡 Heikko happonuljaska
海科·哈波努利亚斯卡 Äitinuljaska
埃提奴利亚斯加 Heikko äitinuljaska
海科·埃提奴利亚斯加 Kiukkumöykky
久库墨库 Limanuljaska
利马努利亚斯卡 Heikko limanuljaska
海科·利马努利亚斯卡 Pikkuturso
皮库图尔索 Jättikonna
甲提客尔娜 Varjokupla
瓦吉奥库普勒 Helvetin sylkijä
黑勒瓦汀苏拉基亚 Helvetinkatse
黑勒瓦汀卡特瑟 Taivaankatse
代万恩卡忒斯 Pienkätyri
皮焉噶杜里 Kolmisilmä
科尔密斯尔玛 Kolmisilmän sydän
三眼赛旦 Kolmisilmän apuri
三眼阿波里 |
<infobox theme="material">
<panel> </panel>
</infobox>
local p = {
}
function p.main(frame)--主函数
local args = frame
if frame == mw.getCurrentFrame() then
args = require('Module:ProcessArgs').merge(true)
else
frame = mw.getCurrentFrame()
end
-- error(mw.dumpObject(args))
local query = {}
for k, v in pairs(args) do--k为字符串
if string.sub(k, 0, 2) == 'q?' then--如果开头两个字符为q?
query[string.sub(k, 3)] = v--那么将截取之后的字符串作为一个key值,赋值为v(参数)
end
end
local result = p.queryData(query.tables, query)
if result[1] == nil then
-- metatable似乎被删除了,因此#result的结果是0
--if not next(result) then
return frame:preprocess(args.default or '')
end
if args.combineResultAsRow ~= nil then
result = combineResultAsRow(result)
end
local tbl = {}
for _, row in ipairs(result) do
tbl[#tbl + 1] = frame:expandTemplate { title = args.template, args = row }
end
local intro = frame:preprocess(args.intro or '')
local outro = frame:preprocess(args.outro or '')
return intro .. table.concat(tbl, args.delimiter or '') .. outro
end
--- 移除前后空格
local function strip(s)
if s == nil then
return ''
end
return s:gsub("^%s+", ""):gsub("%s+$", "")
end
local function isNotEmpty(s)
return s ~= nil and s ~= ''
end
---split
---根据指定的分隔符分隔, 返回table, 内容会经过小写转换及删除前后空格
---@param s string
---@param delim string
local function split(s, delim)
if string.find(s, delim) == nil then
return {
strip(s):lower()
}
end
local result = {}
for ct in string.gmatch(s, '([^' .. delim .. ']+)') do
ct = strip(ct):lower()
result[#result + 1] = ct
end
return result
end
---splitNolower
---根据指定的分隔符分隔, 返回table, 会删除前后空格
---@param s string
---@param delim string
local function splitNolower(s, delim)
if string.find(s, delim) == nil then
return {
strip(s)
}
end
local result = {}
for ct in string.gmatch(s, '([^' .. delim .. ']+)') do
ct = strip(ct)
result[#result + 1] = ct
end
return result
end
--- 将所有结果合为一个, 后边加数字区分, 比如 { name, img, name2, img2 }
--- 不适合太大的结果集
function combineResultAsRow(result)
if #result == 1 then
return result
end
local r = {}
for i, row in ipairs(result) do
local suffix = ''
if i > 1 then
suffix = tostring(i)
end
for k, v in pairs(row) do
r[k .. suffix] = v
end
end
return { r }
end
-- 返回是否需要过滤结果集,用于提升性能
local function hasAnyFilter(query)
if isNotEmpty(query.tier) then
return true
end
if isNotEmpty(query.groupKey) then
query.groupKey = query.groupKey:lower()
return true
end
return false
end
--- 返回给定的行是否是符合条件的数据
local function isAvailableRow(t, v, query)
local noProZero = false
if query.noProbabilityZero == "true" then
noProZero = true
--ProTable = split(v.spawnProbability, ',')
end
if isNotEmpty(query.tier) then
anyFind = false
local Exit = false
for _, ct in pairs(query.tier) do
if noProZero then--先判断排除权重0
local tempTier = split(v.spellTier,",")--获得等级表
for k,v2 in pairs(tempTier)do--遍历它
if v2 == ct then--当到需要判断的等级的时候
local ProTable = split(v.spawnProbability, ',')--获取权重表
if ProTable[k] == "0"then--如果是0
Exit = true
break--直接退出循环
end
end
end
end
if Exit then
break
end
if string.find(v['spellTierPrepared'], '#' .. ct .. '#') ~= nil then
anyFind = true
break
end
end
if not anyFind then
return false
end
end
if isNotEmpty(query.groupKey) then--如果有groupKey
if string.find(v['sortKey'], query.groupKey) == nil then--判断是否有这个sortKey
return false
end
end
--if isNotEmpty(query.type) then
-- if v['type'] ~= query.type then
-- return false
-- end
--end
return true
end
local function filter(t, query)
if not hasAnyFilter(query) then--此函数返回真假值,真代表有query.tier或query.groupKey,此时if为假,即不返回t
return t
end
local result = {}
if (t == nil) then--如果t是空的,返回空结果
return result
end
for _, v in pairs(t) do
if isAvailableRow(t, v, query) then
result[#result + 1] = v
end
end
return result
end
--- 查询并过滤数据, 结果集未排序, 需要外部排序
function p.queryData(tables, query)--query为参数表
local temp = mw.title.makeTitle("Module", "DataQuery/"..query.tables)--判断数据库是否存在
if not temp.exists then--不存在返回空列表
return {}
end
local raw_data = mw.loadData("Module:DataQuery/"..query.tables)--读取指定数据库,该模块返回一个表
local all_data_table = raw_data[tables]--从指定表索引中找到数据
if isNotEmpty(query.tier) then--isNotEmpty为判空函数,如果不为空返回真,此举是在判断是否有tier
query.tier = split(query.tier, ',')--将参数分割为表
end
if isNotEmpty(query.AnyMat) then
local result = {}
local AnyMat = query.AnyMat
query.AnyMat = nil
if AnyMat == "any_liquid" then
for _,v1 in pairs(all_data_table)do
if v1.liquidSand == "0" and v1.cellType == "liquid" then
table.insert(result,v1)
end
end
elseif AnyMat == "any_powder" then
--[[
for _,v1 in pairs(all_data_table)do
end]]
end
return result
end
--tags
if isNotEmpty(query.tags) then
local result = {}
local tags = query.tags
query.tags = nil
local tagsQuery = split(tags,',')
for _,v1 in pairs(all_data_table)do--原数据是一个二维表,因此要for循环两次
if v1["tags"] ~= nil then
local TagsList = split(v1["tags"],',')
for _,queryKey in pairs(tagsQuery)do
for _,TagsElm in pairs(TagsList)do
if(TagsElm == queryKey)then
result[#result + 1] = v1
end
end
end
end
end
return result
end
if isNotEmpty(query.name) then
local result = {}
local table_by_name = raw_data[tables .. '_Name']
for _, ct in pairs(split(query.name, ',')) do
result[#result + 1] = table_by_name[ct]
end
return result
end
if isNotEmpty(query.id) then
local result = {}
local table_by_id = raw_data[tables .. '_ID']
for _, ct in pairs(splitNolower(query.id, ',')) do
result[#result + 1] = table_by_id[ct]
end
return result
end
if isNotEmpty(query.type) then
local type = query.type
query.type = nil
if string.find(type, ',') == nil then
return filter(raw_data[tables .. '_Type'][strip(type):lower()], query)
end
local result = {}
for _, ct in pairs(split(type, ',')) do
local tree_table = raw_data[tables .. '_Type'][ct]
if tree_table == nil then
error("can't find type: '" .. ct .. "'")
end
for _, v in pairs(filter(tree_table, query)) do
result[#result + 1] = v
end
end
return result
end
if isNotEmpty(query.herd) then
local herd = query.herd
query.herd = nil
if string.find(herd, ',') == nil then
return filter(raw_data[tables .. '_Herd'][strip(herd):lower()], query)
end
local result = {}
for _, ct in pairs(split(herd, ',')) do
local tree_table = raw_data[tables .. '_Herd'][ct]
if tree_table == nil then
error("can't find herd: '" .. ct .. "'")
end
for _, v in pairs(filter(tree_table, query)) do
result[#result + 1] = v
end
end
return result
end
if isNotEmpty(query.link) then
local link = query.link
query.link = nil
if string.find(link, ',') == nil then
return filter(raw_data[tables .. '_Link'][strip(link):lower()], query)
end
local result = {}
for _, ct in pairs(split(link, ',')) do
local tree_table = raw_data[tables .. '_Link'][ct]
if tree_table == nil then
error("can't find link: '" .. ct .. "'")
end
for _, v in pairs(filter(tree_table, query)) do
result[#result + 1] = v
end
end
return result
end
return filter(all_data_table, query)
end
return p