模块:MaterialReaction/PreData
跳到导航
跳到搜索
此模块的文档可以在模块:MaterialReaction/PreData/doc创建
--完成了,用于预处理材料反应数据,以此提升性能
local result = {}
local IDtoTable = {} --材料ID转数据表
for _, v in pairs(mw.loadData("Module:DataQuery/Materials")["Materials"]) do --初始化id对应表
IDtoTable[v.herd] = v
end
--- 移除前后空格,换行
local function strip(s)
if s == nil then
return ''
end
return s:gsub("^%s+", ""):gsub("%s+$", ""):gsub("%c", "")
end
--构造一个用于判断的表
local function split(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[ct] = true
end
return result
end
local raw_data = require("Module:MaterialReaction/data")
for i, v1 in pairs(raw_data.children) do --遍历元素
--获得材料输入和输出
local tempInputT = { nil, nil, nil } --nil用于占位,提供一个合适的数组大小,避免hash操作带来的性能损失
local tempOutputT = { nil, nil, nil } --nil用于占位,提供一个合适的数组大小,避免hash操作带来的性能损失
local HasMaterialT = {} --此表用于标记已写入材料
local k = 1 --用于遍历元素的属性
local cmpStr = "input_cell" .. tostring(k)
while (v1.attr[cmpStr] ~= nil) do --解析输入材料
tempInputT[k] = v1.attr[cmpStr]
k = k + 1
cmpStr = "input_cell" .. tostring(k)
end
k = 1
local cmpStr = "output_cell" .. tostring(k)
while (v1.attr[cmpStr] ~= nil) do --解析输出材料
tempOutputT[k] = v1.attr[cmpStr]
k = k + 1
cmpStr = "output_cell" .. tostring(k)
end
--构建返回值的表的函数 可能没问题 谁知道呢()
local function SetResult(InputTable)
for j = 1, #InputTable do
local this = InputTable[j]
if not HasMaterialT[this] then --如果没被标记过
local continue = true --牛魔5.1没有goto,真麻烦啊
if string.byte(this, 1, 1) ~= 91 then --91为[ 如果等于则是tag,正常保存,是id要判断,这里是为了避免在MaterialReaction中加载重复反应
local hasTags = split(IDtoTable[this].tags, ",") --分割出来判断表
local has = false --判断变量
local iTag = 1
while (not has) and iTag <= #tempInputT do --遍历判断是不是存在此tag
has = hasTags[tempInputT[iTag]]
iTag = iTag + 1
end
iTag = 1
while (not has) and iTag <= #tempOutputT do --遍历判断是不是存在此tag
has = hasTags[tempOutputT[iTag]]
iTag = iTag + 1
end
if has then
continue = false
end
end
if continue then
if not result[this] then --如果不存在id索引或tag索引
--第一个表中元素和第二个表中元素同一个下标索引则为同一反应
result[this] = { {}, {}, { "0" }, { "0" } } --数组第一个表为输入材料,第二个为输出材料,第三个表为速率,第四个表为快速反应
--这里直接插入输入和输出的内容和速率,快速反应
table.insert(result[this][1], tempInputT)
table.insert(result[this][2], tempOutputT)
result[this][3][1] = v1.attr.probability --反应速率
if v1.attr.fast_reaction ~= nil then --解析反应是否快速
if v1.attr.fast_reaction == "1" then
result[this][4][1] = "是"
else
result[this][4][1] = "否"
end
else
result[this][4][1] = "否"
end
else --反之如果存在
--这里直接构建输入和输出的内容和速率,快速反应
--插入表
table.insert(result[this][1], tempInputT)
table.insert(result[this][2], tempOutputT)
table.insert(result[this][3], v1.attr.probability) --反应速率
if v1.attr.fast_reaction ~= nil then --解析反应是否快速
if v1.attr.fast_reaction == "1" then
table.insert(result[this][4], "是")
else
table.insert(result[this][4], "否")
end
else
table.insert(result[this][4], "否")
end
end
end
HasMaterialT[this] = true --标记这个材料被记录过
end
end
end
--输入表格
SetResult(tempInputT)
SetResult(tempOutputT)
end
--继承反应实现
for i, matT in pairs(IDtoTable) do
local tempMat = matT
while tempMat ~= nil and tempMat.parent ~= "" and tempMat.inheritsReactions == "1" do --看看有没有材料,然后判断是否有父类和是否有继承反应
local tempReaction = result[tempMat.parent]
if tempReaction ~= nil then --如果有反应
local hasTags = split(matT.tags, ",") --分割出来判断表
for t_i = 1, #tempReaction[1] do --解析反应数据,并进行适当的深/浅拷贝
--四个数组等长,只需要知道一个长度即可
local hasReaction = false
local Input = { nil, nil, nil }
local Output = { nil, nil, nil }
local ReactionMat = {}
local has = false --用于判断当前材料是否参与了它有的tag的反应
for _, str in pairs(tempReaction[1][t_i]) do
has = hasTags[str]
if str == tempMat.parent then
hasReaction = true
table.insert(Input, i)
ReactionMat[i] = true
else
table.insert(Input, str)
ReactionMat[str] = true
end
end
if hasReaction then
if result[i] == nil then
result[i] = { { nil }, { nil }, { nil }, { nil } }
end
for _, str in pairs(tempReaction[2][t_i]) do
has = hasTags[str]
if str == tempMat.parent then
table.insert(Output, i)
ReactionMat[i] = true
else
table.insert(Output, str)
ReactionMat[str] = true
end
end
if has then --如果当前材料参与了它有的tag的反应,那么就把当前材料从添加表移除,防止重复
ReactionMat[i] = nil
end
for ID, _ in pairs(ReactionMat) do --添加表
table.insert(result[ID][1], Input)
table.insert(result[ID][2], Output)
table.insert(result[ID][3], tempReaction[3][t_i])
table.insert(result[ID][4], tempReaction[4][t_i])
end
end
end
end
tempMat = IDtoTable[tempMat.parent] --更新父类
end
end
return result