此站点为镜像站,如有编辑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
                




















                    沪公网安备 31011002002714 号