打开/关闭搜索
搜索
打开/关闭菜单
1K
5.2K
4
8.2K
星砂岛百科
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
上传文件
打开/关闭外观设置菜单
通知
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
创建账号
登录
本站正在进行早期测试,目前仍存在许多内容的缺失。
查看“︁模块:Machine”︁的源代码
来自星砂岛百科
查看
阅读
查看源代码
查看历史
associated-pages
模块
讨论
更多操作
←
模块:Machine
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:已验证邮箱用户
您没有权限编辑
模块
命名空间内的页面。
您必须确认您的电子邮件地址才能编辑页面。请通过
参数设置
设置并确认您的电子邮件地址。
您可以查看和复制此页面的源代码。
local common = require('Module:Common') local item_common = require('Module:ItemCommon') local item = require('Module:Item') local css = require('Module:CSS') local p = {} local FIELD_MAP = { type = 't', type_display = 'td', item_level = 'lv', rarity = 'r', sell_price = 'sp', base_value = 'bv', max_stack = 'ms', max_quality = 'mq', tags = 'g', origin = 'o', locked_origin = 'lo', use_description = 'ud', unlock_title = 'ut', construct_template = 'ct', construction_template_count = 'ctc', energy_capacity = 'ec', production_formula = 'pf', production_formula_origin = 'pfo', craft = 'c', upgrade = 'u', prev_machine = 'pm', next_machine = 'nm', } local data_cache local mapping_cache local function is_empty(value) if value == nil then return true end for _ in pairs(value) do return false end return true end local function load_data() if data_cache then return end local raw_data raw_data, mapping_cache = item_common.loadDomainData('数据:Machine/machine_index.json') if type(raw_data) == 'table' and type(raw_data.records) == 'table' then data_cache = raw_data.records else data_cache = raw_data or {} end end local function find_record(key) load_data() return item_common.findRecord(data_cache, mapping_cache, key) end local function get_short_field(field) return FIELD_MAP[field] or field end local function get_record_field(record, key, field) if type(record) ~= 'table' then return nil end local short_key = get_short_field(field) if record[short_key] ~= nil then return record[short_key] end if record[field] ~= nil then return record[field] end if field == 'id' or field == 'name' or field == 'name_en' then return item_common.getIdentityField(record, key, field) end return nil end local function get_craft_field(craft, short_key, long_key) if type(craft) ~= 'table' then return nil end if craft[short_key] ~= nil then return craft[short_key] end return craft[long_key] end local function format_time(seconds) seconds = tonumber(seconds) or 0 if seconds <= 0 then return '' end if seconds < 60 then return tostring(math.floor(seconds)) .. '秒' end local minutes = math.floor(seconds / 60) local remain = math.floor(seconds % 60) if remain == 0 then return tostring(minutes) .. '分' end return tostring(minutes) .. '分' .. tostring(remain) .. '秒' end local function render_materials(frame, materials) if is_empty(materials) then return '' end local parts = {} for item_id, count in pairs(materials) do parts[#parts + 1] = frame:expandTemplate{ title = 'Item', args = { item_id, tostring(count), class = 'block' }, } end return table.concat(parts, '') end local function render_item_template(frame, item_id) local resolved_id = common.trim(item_id or '') if resolved_id == '' then return '' end local css_out = css.quickCall('Item') or '' return css_out .. item.renderItemWithArgs(frame, { resolved_id }) end local function render_craft_table(title_text, station_label, station_value, materials_label, materials_value, time_label, time_value, exp_label, exp_value) local out = {} out[#out + 1] = '<table class="wikitable machine-craft-table">' out[#out + 1] = '<tr><th colspan="2">' .. title_text .. '</th></tr>' out[#out + 1] = '<tr><th>' .. station_label .. '</th><td>' .. station_value .. '</td></tr>' out[#out + 1] = '<tr><th>' .. materials_label .. '</th><td>' .. materials_value .. '</td></tr>' if time_value ~= '' then out[#out + 1] = '<tr><th>' .. time_label .. '</th><td>' .. time_value .. '</td></tr>' end if exp_value ~= '' then out[#out + 1] = '<tr><th>' .. exp_label .. '</th><td>' .. exp_value .. '</td></tr>' end out[#out + 1] = '</table>' return table.concat(out, '\n') end local function is_array_table(value) if type(value) ~= 'table' then return false end local count = 0 for key in pairs(value) do if type(key) ~= 'number' then return false end count = count + 1 end if count == 0 then return false end for index = 1, count do if value[index] == nil then return false end end return true end local function normalize_material_options(materials) if type(materials) ~= 'table' then return {} end if is_array_table(materials) then local options = {} for _, option in ipairs(materials) do if type(option) == 'table' and not is_empty(option) then options[#options + 1] = option end end return options end if is_empty(materials) then return {} end return { materials } end local function render_material_option(frame, materials) if type(materials) ~= 'table' or is_empty(materials) then return '' end local item_ids = {} for item_id in pairs(materials) do item_ids[#item_ids + 1] = item_id end table.sort(item_ids) local parts = {} for _, item_id in ipairs(item_ids) do parts[#parts + 1] = item.renderItemWithArgs(frame, { item_id, tostring(materials[item_id]), class = 'block' }) end return table.concat(parts, '') end local function render_recipe_materials(frame, materials) local options = normalize_material_options(materials) if #options == 0 then return '' end if #options == 1 then return render_material_option(frame, options[1]) end local out = {} out[#out + 1] = '<div>任选其一:</div>' out[#out + 1] = '<ul>' for _, option in ipairs(options) do out[#out + 1] = '<li>' .. render_material_option(frame, option) .. '</li>' end out[#out + 1] = '</ul>' return table.concat(out, '') end local function material_counts_for_item(materials, item_id) local counts = {} local seen = {} for _, option in ipairs(normalize_material_options(materials)) do local count = tonumber(option[item_id]) or 0 if count > 0 and not seen[count] then seen[count] = true counts[#counts + 1] = count end end table.sort(counts) return counts end local function render_material_count_list(counts) if #counts == 0 then return '' end if #counts == 1 then return tostring(counts[1]) end local out = { '<ul>' } for _, count in ipairs(counts) do out[#out + 1] = '<li>' .. tostring(count) .. '</li>' end out[#out + 1] = '</ul>' return table.concat(out, '') end local function render_recipe_usage_note() return '<p><small>说明:每一行代表一类配方;同一行普通并列材料都需要满足。若材料栏显示列表,则列表中的每一项代表一套可选方案,任选其一即可;若同一产物出现多行,则表示仍有多套不同配方。</small></p>' end function p.getField(frame) local key = common.getArg(frame, 1, '') local field = common.getArg(frame, 2, '') if field == '' then return '' end local record = find_record(key) if not record then return '' end local craft = get_record_field(record, key, 'craft') if field == 'craft_machine' and craft then local machine_id = get_craft_field(craft, 'm', 'machine') if machine_id and machine_id ~= '' then return render_item_template(frame, machine_id) end return '' end if field == 'craft_time' and craft then return format_time(get_craft_field(craft, 't', 'time')) end if field == 'craft_exp' and craft then return common.toText(get_craft_field(craft, 'e', 'exp')) end local upgrade = get_record_field(record, key, 'upgrade') if field == 'upgrade_from' and upgrade then local from_id = get_craft_field(upgrade, 'f', 'from_machine') if from_id and from_id ~= '' then local from_name = item.getNameByKey(from_id) if from_name and from_name ~= '' then return '[[' .. from_name .. ']]' end end return '' end if field == 'upgrade_time' and upgrade then return format_time(get_craft_field(upgrade, 't', 'time')) end if field == 'upgrade_exp' and upgrade then return common.toText(get_craft_field(upgrade, 'e', 'exp')) end if field == 'construction_template_count' then local value = tonumber(get_record_field(record, key, field)) or 0 if value <= 0 then return '' end return tostring(value) end if field == 'energy_capacity' then local value = tonumber(get_record_field(record, key, field)) or 0 if value <= 0 then return '' end return tostring(value) end if field == 'prev_machine' then local prev_id = get_record_field(record, key, 'prev_machine') if prev_id and prev_id ~= '' then return render_item_template(frame, prev_id) end return '' end if field == 'next_machine' then local next_id = get_record_field(record, key, 'next_machine') if next_id and next_id ~= '' then return render_item_template(frame, next_id) end return '' end return common.toText(get_record_field(record, key, field)) end function p.ingredientList(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local craft = get_record_field(record, key, 'craft') if not craft then return '' end return render_materials(frame, get_craft_field(craft, 'mat', 'materials')) end function p.upgradeIngredientList(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local upgrade = get_record_field(record, key, 'upgrade') if not upgrade then return '' end return render_materials(frame, get_craft_field(upgrade, 'mat', 'materials')) end function p.craftInfo(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local out = {} local craft = get_record_field(record, key, 'craft') local craft_materials = get_craft_field(craft, 'mat', 'materials') if craft and not is_empty(craft_materials) then local machine_id = get_craft_field(craft, 'm', 'machine') local machine_display = '—' if machine_id and common.trim(machine_id) ~= '' then local machine_name = item.getNameByKey(machine_id) if machine_name and machine_name ~= '' then machine_display = '[[' .. machine_name .. ']]' end end out[#out + 1] = render_craft_table( '制造配方', '制造站', machine_display, '材料', render_materials(frame, craft_materials), '时间', format_time(get_craft_field(craft, 't', 'time')), '经验', common.toText(get_craft_field(craft, 'e', 'exp')) ) end local upgrade = get_record_field(record, key, 'upgrade') local upgrade_materials = get_craft_field(upgrade, 'mat', 'materials') if upgrade and not is_empty(upgrade_materials) then local from_id = get_craft_field(upgrade, 'f', 'from_machine') local from_display = '—' if from_id and common.trim(from_id) ~= '' then local from_name = item.getNameByKey(from_id) if from_name and from_name ~= '' then from_display = '[[' .. from_name .. ']]' end end out[#out + 1] = render_craft_table( '升级配方', '升级自', from_display, '材料', render_materials(frame, upgrade_materials), '时间', format_time(get_craft_field(upgrade, 't', 'time')), '经验', common.toText(get_craft_field(upgrade, 'e', 'exp')) ) end return table.concat(out, '\n') end local recipe_cache local recipe_list local field_map local function load_recipes() if recipe_cache then return end local data = common.loadJsonData('数据:Machine/machine_recipes.json') or {} recipe_list = data.recipes or {} recipe_cache = data.by_machine or {} field_map = (data._meta or {}).field_map or { result = 'r', result_count = 'rc', materials = 'm', time = 't', machine = 'mc' } end function p.recipeList(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end -- 获取机器ID local machine_id = get_record_field(record, key, 'id') if not machine_id then return '' end local machine_key = mw.ustring.lower(machine_id) load_recipes() local recipe_ids = recipe_cache[machine_key] if not recipe_ids then return '该机器暂无独有配方。' end -- 检查是否有配方需要显示时间 local has_time = false for _, rid in ipairs(recipe_ids) do local recipe = recipe_list[rid + 1] if recipe and recipe[field_map.time] and recipe[field_map.time] > 0 then has_time = true break end end -- 构建HTML表格 local out = {} out[#out + 1] = '<table class="wikitable">' out[#out + 1] = '<tr><th>产物</th><th>材料</th>' if has_time then out[#out + 1] = '<th>时间</th>' end out[#out + 1] = '</tr>' for _, rid in ipairs(recipe_ids) do local recipe = recipe_list[rid + 1] if recipe then out[#out + 1] = '<tr>' local result_count = recipe[field_map.result_count] or 1 if result_count > 1 then out[#out + 1] = '<td>' .. item.renderItemWithArgs(frame, {recipe[field_map.result], tostring(result_count), class = 'block'}) .. '</td>' else out[#out + 1] = '<td>' .. item.renderItemWithArgs(frame, {recipe[field_map.result], class = 'block'}) .. '</td>' end -- 渲染材料 out[#out + 1] = '<td>' .. render_recipe_materials(frame, recipe[field_map.materials]) .. '</td>' -- 渲染时间 if has_time then local time_str = '' if recipe[field_map.time] and recipe[field_map.time] > 0 then time_str = format_time(recipe[field_map.time]) end out[#out + 1] = '<td>' .. time_str .. '</td>' end out[#out + 1] = '</tr>' end end out[#out + 1] = '</table>' local css_out = css.quickCall('Item') or '' return css_out .. table.concat(out, '\n') end local item_recipe_cache local function load_item_recipes() if item_recipe_cache then return end load_recipes() local data = common.loadJsonData('数据:Machine/machine_recipes.json') or {} item_recipe_cache = data.by_item or {} end function p.itemRecipes(frame) local item_key = common.getArg(frame, 1, '') if item_key == '' then item_key = common.getCurrentTitleText() end -- 获取物品ID local item_id = item.getIdByKey(item_key) if not item_id or item_id == '' then return '' end local normalized_id = mw.ustring.lower(item_id) load_item_recipes() local item_data = item_recipe_cache[normalized_id] if not item_data then return '' end local product_ids = item_data.p or {} local ingredient_ids = item_data.i or {} -- 计算数组长度(处理有metatable的情况) local function count_array(arr) local count = 0 for _ in pairs(arr) do count = count + 1 end return count end local product_count = count_array(product_ids) local ingredient_count = count_array(ingredient_ids) if product_count == 0 and ingredient_count == 0 then return '' end local out = {} out[#out + 1] = render_recipe_usage_note() -- 作为产物 if product_count > 0 then out[#out + 1] = '<h3>制作配方</h3>' out[#out + 1] = '<table class="wikitable">' out[#out + 1] = '<tr><th>产物</th><th>机器</th><th>所需材料</th><th>时间</th></tr>' for _, rid in ipairs(product_ids) do local recipe = recipe_list[rid + 1] if recipe then out[#out + 1] = '<tr>' out[#out + 1] = '<td>' .. item.renderItemWithArgs(frame, {recipe[field_map.result], class = 'block'}) .. '</td>' out[#out + 1] = '<td>' .. item.renderItemWithArgs(frame, {recipe[field_map.machine], class = 'block'}) .. '</td>' out[#out + 1] = '<td>' .. render_recipe_materials(frame, recipe[field_map.materials]) .. '</td>' local time_str = '' if recipe[field_map.time] and recipe[field_map.time] > 0 then time_str = format_time(recipe[field_map.time]) end out[#out + 1] = '<td>' .. time_str .. '</td>' out[#out + 1] = '</tr>' end end out[#out + 1] = '</table>' end -- 作为材料 if ingredient_count > 0 then if #out > 0 then out[#out + 1] = '' end out[#out + 1] = '<h3>用于制作</h3>' out[#out + 1] = '<table class="wikitable">' out[#out + 1] = '<tr><th>产物</th><th>所需材料</th><th>机器</th></tr>' for _, rid in ipairs(ingredient_ids) do local recipe = recipe_list[rid + 1] if recipe then out[#out + 1] = '<tr>' out[#out + 1] = '<td>' .. item.renderItemWithArgs(frame, {recipe[field_map.result], class = 'block'}) .. '</td>' -- 渲染材料 out[#out + 1] = '<td>' .. render_recipe_materials(frame, recipe[field_map.materials]) .. '</td>' out[#out + 1] = '<td>' .. item.renderItemWithArgs(frame, {recipe[field_map.machine], class = 'block'}) .. '</td>' out[#out + 1] = '</tr>' end end out[#out + 1] = '</table>' end local css_out = css.quickCall('Item') or '' return css_out .. table.concat(out, '\n') end function p.machineAsIngredient(frame) local key = common.getArg(frame, 1, '') local record = find_record(key) if not record then return '' end local machine_id = get_record_field(record, key, 'id') if not machine_id then return '' end local machine_key = mw.ustring.lower(machine_id) load_item_recipes() local item_data = item_recipe_cache[machine_key] if not item_data or not item_data.i or #item_data.i == 0 then return '' end local out = {} out[#out + 1] = '=== 用于制作 ===' out[#out + 1] = '<table class="wikitable">' out[#out + 1] = '<tr><th>产物</th><th>所需数量</th></tr>' for _, rid in ipairs(item_data.i) do local recipe = recipe_list[rid + 1] if recipe then local counts = material_counts_for_item(recipe[field_map.materials], machine_id) if #counts > 0 then out[#out + 1] = '<tr>' out[#out + 1] = '<td>' .. item.renderItemWithArgs(frame, {recipe[field_map.result]}) .. '</td>' out[#out + 1] = '<td>' .. render_material_count_list(counts) .. '</td>' out[#out + 1] = '</tr>' end end end out[#out + 1] = '</table>' local css_out = css.quickCall('Item') or '' return css_out .. table.concat(out, '\n') end return p
该页面嵌入的页面:
模板:Tl
(
查看源代码
)
模块:ArgsUtil
(
查看源代码
)
模块:Machine/doc
(
查看源代码
)
模块:Template link
(
查看源代码
)
返回
模块:Machine
。
查看“︁模块:Machine”︁的源代码
来自星砂岛百科