1149 lines
36 KiB
Lua

local mod_gui = require("mod-gui")
SHOW_ALL = false -- Set to true to also display disabled recipes and recipes without technology.
function find_technology(recipe, player)
local disabled_unlocking_tech = {"not_found"}
for _,tech in pairs(player.force.technologies) do
if not tech.researched then
for _, effect in pairs(tech.effects) do
if effect.type == "unlock-recipe" and effect.recipe == recipe then
if tech.enabled then
return tech.localised_name
else
disabled_unlocking_tech = {"disabled_thing", tech.localised_name}
end
end
end
end
end
if SHOW_ALL then
return disabled_unlocking_tech
else
return false
end
end
function get_machines_for_recipe(recipe, player)
local factories = {}
local recipe_category = recipe.category
for _, entity in pairs(game.entity_prototypes) do
if entity.crafting_categories and entity.ingredient_count then
if entity.crafting_categories[recipe_category] and entity.ingredient_count >= #recipe.ingredients then
factories[entity.name] = entity
end
end
end
return factories
end
function sort_recipes(recipes, player)
function compare(l, r)
-- We want hidden recipes at the end
if l.hidden ~= r.hidden then
return r.hidden
end
if l.group.order ~= r.group.order then
return l.group.order < r.group.order
end
if l.subgroup.order ~= r.subgroup.order then
return l.subgroup.order < r.subgroup.order
end
if l.order ~= r.order then
return l.order < r.order
end
return l.name < r.name
end
table.sort(recipes, compare)
end
function add_recipe_to_list(recipe, table, player)
local from_research = recipe.enabled or find_technology(recipe.name, player)
if from_research then
table.add{type="sprite", name="wiiuf_recipe_sprite_"..recipe.name, sprite="recipe/"..recipe.name}
local label = table.add{
type="label", name="wiiuf_recipe_label_"..recipe.name, caption=recipe.localised_name,
single_line=false
}
label.style.minimal_height = 39
label.style.maximal_width = 249
label.style.vertical_align = "center"
if not recipe.enabled then
label.style = "invalid_label"
label.tooltip = {"behind_research", from_research}
elseif recipe.hidden then
label.style = "wiiuf_hidden_label_style"
end
return true
else
return false
end
end
function identify(item, player, side, recipe_name)
-- If it's not actually an item, do nothing
-- This can happen if you click the recipe name on the recipe pane
if not game.item_prototypes[item] and not game.fluid_prototypes[item] then
return
end
local ingredient_in = {}
local mined_from = {}
local pumped_from = {}
local looted_from = {}
local product_of = {}
for name, recipe in pairs(player.force.recipes) do
for _, ingredient in pairs(recipe.ingredients) do
if ingredient.name == item then
table.insert(ingredient_in, recipe)
break
end
end
for _, product in pairs(recipe.products) do
if product.name == item then
table.insert(product_of, recipe)
break
end
end
end
-- Sort both recipe lists
sort_recipes(ingredient_in, player)
sort_recipes(product_of, player)
for _, entity in pairs(game.entity_prototypes) do
if entity.loot then
for _,loot in pairs(entity.loot) do
if loot.item == item then
table.insert(looted_from, entity)
break
end
end
end
if ((entity.type == "resource" or entity.type == "tree") and
entity.mineable_properties and
entity.mineable_properties.products) then
for _, product in pairs(entity.mineable_properties.products) do
if product.name == item then
table.insert(
mined_from,
{ore=entity, fluid=entity.mineable_properties.required_fluid}
)
break
end
end
end
if entity.fluid and entity.fluid.name == item then
pumped_from[entity.name] = entity
end
end
local table_height = 350
if side then table_height = 250 end
local section_width = 300
-- GUI stuff
if player.gui.screen.wiiuf_center_frame then
player.gui.screen.wiiuf_center_frame.destroy()
end
local mod_frame_flow = mod_gui.get_frame_flow(player)
if side and mod_frame_flow.wiiuf_left_frame then
mod_frame_flow.wiiuf_left_frame.destroy()
end
-- Create center frame
local main_frame = {}
if not side then
main_frame = player.gui.screen.add{
type = "frame",
name = "wiiuf_center_frame",
direction = "vertical",
style = "wiiuf_frame_unspaced"
}
-- Register this frame as GUI so it will be closed by usual GUI close
-- controls
player.opened = main_frame
local location = {200, 100}
if global.wiiuf_frame_locations ~= nil then
if global.wiiuf_frame_locations[player.index] ~= nil then
location = global.wiiuf_frame_locations[player.index]
end
end
main_frame.location = location
else
main_frame = mod_gui.get_frame_flow(player).add{
type = "frame",
name = "wiiuf_left_frame",
direction = "vertical",
style = "wiiuf_frame_unspaced"
}
end
-- Title flow
local title_flow = main_frame.add{type = "flow", name = "wiiuf_title_flow", direction = "horizontal"}
local title_frame = title_flow.add{
type = "frame",
name = "wiiuf_title_frame"
}
local sprite = "questionmark"
local localised_name = item
if game.item_prototypes[item] then
sprite = "item/"..item
localised_name = game.item_prototypes[item].localised_name
elseif game.fluid_prototypes[item] then
sprite = "fluid/"..item
localised_name = game.fluid_prototypes[item].localised_name
end
local button_style = "wiiuf_small_slot_button"
local history = global.wiiuf_item_history[player.index]
if history.position > 1 then
title_frame.add{
type = "sprite-button",
name = "wiiuf_back",
sprite = "arrow-left",
style = button_style,
tooltip = {"back"}
}
end
if history.position < #history.list then
title_frame.add{
type = "sprite-button",
name = "wiiuf_forward",
sprite = "arrow-right",
style = button_style,
tooltip = {"forward"}
}
end
title_frame.add{type = "sprite", name = "wiiuf_title_sprite", sprite = sprite}
local title_label = title_frame.add{
type = "frame",
name = "wiiuf_title_label",
caption = localised_name,
style = "wiiuf_frame_borderless"
}
local title_rhs = title_flow.add{
type = "frame",
name = "wiiuf_title_rhs",
style = "wiiuf_frame_borderless"
}
title_rhs.style.horizontal_align = "right"
title_rhs.add{
type = "sprite-button",
name = "wiiuf_minimise_" .. item,
sprite = "arrow-box",
style = button_style,
tooltip = {"minimise"}
}
if side then
title_rhs.add{
type = "sprite-button",
name = "wiiuf_show_" .. item,
sprite = "arrow-right",
style = button_style,
tooltip = {"show", localised_name}
}
else
title_rhs.add{
type = "sprite-button",
name = "wiiuf_pin_" .. item,
sprite = "arrow-bar",
style = button_style,
tooltip = {"pin"}
}
end
title_rhs.add{
type = "sprite-button",
name = "wiiuf_close_3",
sprite = "close",
style = button_style,
tooltip = {"close"}
}
-- Body flow
local body_flow = {}
if side then
local body_scroll = main_frame.add{
type = "scroll-pane",
name = "wiiuf_body_scroll"
}
body_scroll.style.maximal_width = 250
body_scroll.vertical_scroll_policy = "never"
body_flow = body_scroll.add{
type = "flow",
name = "wiiuf_body_flow",
direction = "horizontal",
style = "slot_table_spacing_horizontal_flow"
}
else
body_flow = main_frame.add{
type = "flow",
name = "wiiuf_body_flow",
direction = "horizontal",
style = "slot_table_spacing_horizontal_flow"
}
end
-- mined from
if #mined_from > 0 then
local mined_frame = body_flow.add{
type = "frame",
name = "wiiuf_mined_frame",
caption = {"mined_from"}
}
local mined_scroll = mined_frame.add{
type = "scroll-pane",
name = "wiiuf_mined_scroll"
}
mined_scroll.style.minimal_height = table_height
mined_scroll.style.maximal_height = table_height
local mined_table = mined_scroll.add{
type = "table",
name = "wiiuf_mined_table",
column_count = 4
}
for i, entity in pairs(mined_from) do
local ore = entity.ore
local fluid = entity.fluid
mined_table.add{
type = "sprite",
name = "wiiuf_sprite_" .. i,
sprite = "entity/"..ore.name
}
local label = mined_table.add{
type = "label",
name = "wiiuf_label_" .. i,
caption = ore.localised_name
}
label.style.minimal_height = 34
label.style.vertical_align = "center"
if fluid then
mined_table.add{
type = "sprite",
name = "wiiuf_mined_fluid_sprite_"..i.."_"..fluid,
sprite = "fluid/"..fluid
}
mined_table.add{
type = "label",
name = "wiiuf_mined_fluid_label_"..i.."_"..fluid,
caption = game.fluid_prototypes[fluid].localised_name
}
else
mined_table.add{
type = "label",
name = "wiiuf_padding_label_a_"..i
}
mined_table.add{
type = "label",
name = "wiiuf_padding_label_b_"..i
}
end
end
end
-- looted from
if #looted_from > 0 then
local looted_frame = body_flow.add{type = "frame", name = "wiiuf_looted_frame", caption = {"looted_from"}}
local looted_scroll = looted_frame.add{type = "scroll-pane", name = "wiiuf_looted_scroll"}
looted_scroll.style.minimal_height = table_height
looted_scroll.style.maximal_height = table_height
local looted_table = looted_scroll.add{type = "table", name = "wiiuf_looted_table", column_count = 2}
for i, entity in pairs(looted_from) do
looted_table.add{type = "sprite", name = "wiiuf_sprite_" .. i, sprite = "entity/"..entity.name}
local label = looted_table.add{type = "label", name = "wiiuf_label_" .. i, caption = entity.localised_name}
label.style.minimal_height = 34
label.style.vertical_align = "center"
end
end
-- pumped from
if next(pumped_from) then
local pumped_frame = body_flow.add{
type = "frame", name = "wiiuf_pumped_frame", caption = {"pumped_from"}
}
local pumped_scroll = pumped_frame.add{
type = "scroll-pane", name = "wiiuf_pumped_scroll"
}
pumped_scroll.style.minimal_height = table_height
pumped_scroll.style.maximal_height = table_height
local pumped_table = pumped_scroll.add{
type = "table", name = "wiiuf_pumped_table", column_count = 2
}
machine_unlocks = get_item_unlocks(pumped_from, player)
for i, entity in pairs(pumped_from) do
local unlock = machine_unlocks[entity.name]
local caption = entity.localised_name
local tooltip = nil
local style = nil
if unlock ~= "already_unlocked" then
style = "invalid_label"
tooltip = {"behind_research", unlock}
end
if unlock == false then
style = "invalid_label"
tooltip = {"wiiuf_unavailable"}
caption = {"disabled_thing", caption}
end
pumped_table.add{
type = "sprite",
name = "wiiuf_sprite_" .. i,
sprite = "entity/"..entity.name,
tooltip = tooltip
}
local label = pumped_table.add{
type = "label",
name = "wiiuf_label_" .. i,
caption = caption,
style = style,
tooltip = tooltip
}
label.style.minimal_height = 34
label.style.vertical_align = "center"
end
end
function set_scroll_dimensions(scroll)
scroll.horizontal_scroll_policy = "never"
scroll.style.minimal_height = table_height
scroll.style.maximal_height = table_height
if not side then
scroll.style.minimal_width = section_width
scroll.style.maximal_width = section_width
end
end
-- ingredient in
local ingredient_frame = body_flow.add{type = "frame", name = "wiiuf_ingredient_frame", caption = {"ingredient_in"}}
local ingredient_scroll = ingredient_frame.add{type = "scroll-pane", name = "wiiuf_ingredient_scroll"}
set_scroll_dimensions(ingredient_scroll)
local ingredient_table = ingredient_scroll.add{type = "table", name = "wiiuf_ingredient_table", column_count = 2}
local is_ingredient = false
for i, recipe in pairs(ingredient_in) do
if add_recipe_to_list(recipe, ingredient_table, player) then
is_ingredient = true
end
end
if side and not is_ingredient then
ingredient_frame.destroy()
end
-- product of
local product_frame = body_flow.add{
type = "frame",
name = "wiiuf_product_frame",
caption = {"product_of"}
}
local product_scroll = product_frame.add{
type = "scroll-pane",
name = "wiiuf_product_scroll"
}
set_scroll_dimensions(product_scroll)
local product_table = product_scroll.add{
type = "table",
name = "wiiuf_product_table",
column_count = 2
}
local last_product_recipe = nil
local num_product_recipes = 0
for i, recipe in pairs(product_of) do
if add_recipe_to_list(recipe, product_table, player) then
last_product_recipe = recipe
num_product_recipes = num_product_recipes + 1
end
end
if side and num_product_recipes == 0 then
product_frame.destroy()
end
-- If we were given a recipe to show, then show it
if recipe_name then
show_recipe_details(recipe_name, player)
-- If there was only one recipe for making this item, then go ahead and show
-- it immediately
elseif num_product_recipes == 1 then
show_recipe_details(last_product_recipe.name, player)
else
-- Otherwise, add an empty recipe frame so that things don't shift when it's used later
local recipe_frame = body_flow.add{
type="frame", name="wiiuf_recipe_frame", caption={"wiiuf_recipe_details"}
}
local recipe_scroll = recipe_frame.add{type="scroll-pane", name="wiiuf_recipe_scroll"}
set_scroll_dimensions(recipe_scroll)
local label = recipe_scroll.add{
type="label", name="wiiuf_recipe_hint", caption={"wiiuf_recipe_hint"}, single_line=false
}
label.style.maximal_width = 249
end
if not side then
title_frame.drag_target = main_frame
title_label.drag_target = main_frame
for i, f in pairs(body_flow.children) do
f.drag_target = main_frame
end
end
end
function identify_and_add_to_history(
item, player, side, should_clear_history, recipe_name)
-- If it's not actually an item, do nothing
-- This can happen if you click the recipe name on the recipe pane
if not game.item_prototypes[item] and not game.fluid_prototypes[item] then
return
end
local history
if (should_clear_history or
global.wiiuf_item_history == nil or
global.wiiuf_item_history[player.index] == nil) then
clear_history(player)
history = global.wiiuf_item_history[player.index]
else
-- Truncate the history by deleting anything after the present entry
history = global.wiiuf_item_history[player.index]
while #history.list > history.position do
history.list[#history.list] = nil
end
end
-- Then add this to the end if it's not already there
if history.list[#history.list] ~= item then
table.insert(history.list, item)
history.position = history.position + 1
end
identify(item, player, side, recipe_name)
end
function get_item_unlocks(items, player)
local item_unlocks = {}
for name, recipe in pairs(player.force.recipes) do
for _, product in pairs(recipe.products) do
if items[product.name] then
if recipe.enabled then
item_unlocks[product.name] = "already_unlocked"
else
item_unlocks[product.name] = find_technology(recipe.name, player)
end
end
end
end
return item_unlocks
end
function show_recipe_details(recipe_name, player)
local recipe = player.force.recipes[recipe_name]
if not recipe then
return
end
local main_frame = player.gui.screen.wiiuf_center_frame
local side = false
if not main_frame then
side = true
main_frame = mod_gui.get_frame_flow(player).wiiuf_left_frame
if main_frame then
main_frame = main_frame.wiiuf_body_scroll
end
end
if not main_frame then
player.print("No main frame")
return
end
local body_flow = main_frame.wiiuf_body_flow
-- Remove any existing recipe entry
if body_flow.wiiuf_recipe_frame then
body_flow.wiiuf_recipe_frame.destroy()
end
-- TODO: table_height and section_width should probably be globals, and
-- maybe configurable
local table_height = 350
local section_width = 300
if side then table_height = 250 end
local recipe_frame = body_flow.add{
type="frame", name="wiiuf_recipe_frame", caption={"wiiuf_recipe_details"}
}
local recipe_scroll = recipe_frame.add{type="scroll-pane", name="wiiuf_recipe_scroll"}
recipe_scroll.style.minimal_height = table_height
recipe_scroll.style.maximal_height = table_height
recipe_scroll.style.minimal_width = section_width
recipe_scroll.style.maximal_width = section_width
-- A generic function for adding an item to the list in the recipe pane
function add_sprite_and_label(add_to, thing_to_add, with_amount, style, tooltip, sprite_dir, i, force_decimals)
if sprite_dir == "auto" then
if game.item_prototypes[thing_to_add.name] then
sprite_dir = "item"
elseif game.fluid_prototypes[thing_to_add.name] then
sprite_dir = "fluid"
else
player.print("Unknown sprite type for "..thing_to_add.name)
return
end
end
local localised_name = thing_to_add.localised_name
if sprite_dir == "item" then
if game.item_prototypes[thing_to_add.name] then
localised_name = game.item_prototypes[thing_to_add.name].localised_name
else
-- We were told it was an item but it wasn't. This can happen for
-- crafting entities sometimes. Just silently do nothing in this case
return
end
elseif sprite_dir == "fluid" then
localised_name = game.fluid_prototypes[thing_to_add.name].localised_name
end
local table = add_to.add{
type="table", name="wiiuf_recipe_table_"..i, column_count=2
}
-- In case the sprite does not exist we use pcall to catch the exception
-- and don't have a sprite (thanks to Helfima/Helmod for the trick).
local sprite = sprite_dir.."/"..thing_to_add.name
local sprite_options = {
type="sprite", name="wiiuf_recipe_item_sprite_"..thing_to_add.name, sprite=sprite
}
local ok, error = pcall(function()
table.add(sprite_options)
end)
if not(ok) then
player.print("Sprite missing: "..sprite)
end
local caption = localised_name
if with_amount then
local amount = nil
if with_amount ~= true then
amount = with_amount
elseif thing_to_add.amount then
amount = thing_to_add.amount
elseif thing_to_add.amount_min and thing_to_add.amount_max then
amount = (thing_to_add.amount_min + thing_to_add.amount_max) / 2
end
if (with_amount == true) and thing_to_add.probability then
amount = amount * thing_to_add.probability
end
if amount then
local formatted_amount = amount
if force_decimals or amount ~= math.floor(amount) then
formatted_amount = string.format("%.3f", amount)
end
caption = {"wiiuf_recipe_entry", formatted_amount, localised_name}
end
end
local label = table.add{
type="label", name="wiiuf_recipe_item_label_"..thing_to_add.name, caption=caption,
single_line=false
}
if style then
label.style = style
end
label.style.maximal_width = 244
if tooltip then
label.tooltip = tooltip
end
end
local i = 0
local recipe_style = nil
local unlock = nil
if not recipe.enabled then
unlock = find_technology(recipe.name, player)
recipe_style = "invalid_label"
end
add_sprite_and_label(
recipe_scroll, recipe, false, recipe_style, nil, "recipe", i
)
i = i + 1
if not recipe.enabled and unlock then
recipe_scroll.add{
type="label",
name="wiiuf_recipe_unlock_warning",
caption={"behind_research", unlock},
style="invalid_label"
}
end
-- First add ingredients
recipe_scroll.add{
type="label", name="wiiuf_recipe_ingredients_heading", caption={"wiiuf_recipe_ingredients_heading"},
style="bold_label"
}
for _, ingredient in pairs(recipe.ingredients) do
add_sprite_and_label(recipe_scroll, ingredient, true, nil, nil, "auto", i)
i = i + 1
end
-- Next add products
recipe_scroll.add{
type="label", name="wiiuf_recipe_products_heading", caption={"wiiuf_recipe_products_heading"},
style="bold_label"
}
for _, product in pairs(recipe.products) do
add_sprite_and_label(recipe_scroll, product, true, nil, nil, "auto", i)
i = i + 1
end
-- Finally add machines
recipe_scroll.add{
type="label", name="wiiuf_recipe_machines_heading", caption={"wiiuf_recipe_machines_heading"},
style="bold_label"
}
local machines = get_machines_for_recipe(recipe, player)
-- Figure out which machines are available at current tech
local machine_unlocks = get_item_unlocks(machines, player)
for _, machine in pairs(machines) do
local unlock = machine_unlocks[machine.name]
if unlock then
local tooltip = nil
local style = nil
if unlock ~= "already_unlocked" then
style = "invalid_label"
tooltip = {"behind_research", unlock}
end
local crafting_time = recipe.energy / machine.crafting_speed
add_sprite_and_label(
recipe_scroll, machine, crafting_time, style, tooltip, "item", i, true
)
i = i + 1
end
end
end
function minimise(item, player, from_side)
if not player.gui.left.wiiuf_item_flow then
local item_flow = player.gui.left.add{
type = "scroll-pane",
name = "wiiuf_item_flow",
style = "small_spacing_scroll_pane_style"
}
local item_table = item_flow.add{
type = "table",
column_count = 1,
name = "wiiuf_item_table",
style = "slot_table"
}
item_table.add{
type = "sprite-button",
name = "wiiuf_close_2",
sprite = "close",
style = "slot_button",
tooltip = {"close"}
}
item_flow.style.maximal_height = 350
end
local sprite = "questionmark"
local localised_name = item
if game.item_prototypes[item] then
sprite = "item/"..item
localised_name = game.item_prototypes[item].localised_name
elseif game.fluid_prototypes[item] then
sprite = "fluid/"..item
localised_name = game.fluid_prototypes[item].localised_name
end
if not player.gui.left.wiiuf_item_flow.wiiuf_item_table["wiiuf_show_" .. item] then
player.gui.left.wiiuf_item_flow.wiiuf_item_table.add{
type = "sprite-button",
name = "wiiuf_show_" .. item,
sprite = sprite,
tooltip = {"show", localised_name},
style = "slot_button"
}
end
if not from_side and player.gui.screen.wiiuf_center_frame then player.gui.screen.wiiuf_center_frame.destroy() end
local mod_frame_flow = mod_gui.get_frame_flow(player)
if from_side and mod_frame_flow.wiiuf_left_frame then mod_frame_flow.wiiuf_left_frame.destroy() end
end
function get_wiiuf_flow(player)
local button_flow = mod_gui.get_button_flow(player)
local flow = button_flow.wiiuf_flow
if not flow then
flow = button_flow.add{
type = "flow", name = "wiiuf_flow", direction = "horizontal"
}
end
return flow
end
function add_top_button(player)
if player.gui.top.wiiuf_flow then player.gui.top.wiiuf_flow.destroy() end -- remove the old flow
local flow = get_wiiuf_flow(player)
if flow["search_flow"] then flow["search_flow"].destroy() end
local search_flow = flow.add{type = "flow", name = "search_flow", direction = "horizontal"}
search_flow.add{
type = "flow",
name = "search_bar_placeholder",
direction = "vertical"
}
search_flow.add{
type = "sprite-button",
name = "looking-glass",
sprite = "looking-glass",
style = mod_gui.button_style,
tooltip = {"top_button_tooltip"}
}
end
function clear_history(player)
if global.wiiuf_item_history == nil then
global.wiiuf_item_history = {}
end
global.wiiuf_item_history[player.index] = {
position = 0,
list = {}
}
end
function ensure_translations_available(player_index)
if global.wiiuf_item_translations == nil then
global.wiiuf_item_translations = {}
end
if global.wiiuf_item_translations[player_index] == nil then
global.wiiuf_item_translations[player_index] = {}
end
end
function init_player(player)
add_top_button(player)
clear_history(player)
ensure_translations_available(player.index)
end
script.on_init(function()
global.n_fluids = 0
for _ in pairs(game.fluid_prototypes) do
global.n_fluids = global.n_fluids +1
end
global.wiiuf_item_history = {}
global.wiiuf_item_translations = {}
for _, player in pairs(game.players) do
init_player(player)
end
end)
script.on_configuration_changed(function()
global.n_fluids = 0
for _ in pairs(game.fluid_prototypes) do
global.n_fluids = global.n_fluids +1
end
for _, player in pairs(game.players) do add_top_button(player) end
end)
script.on_event(defines.events.on_player_created, function(event)
local player = game.players[event.player_index]
init_player(player)
end)
script.on_event(defines.events.on_gui_click, function(event)
local player = game.players[event.player_index]
local flow = get_wiiuf_flow(player)
-- There was a report that the search flow spontaneously vanished during a
-- game (possibly another mod messed with it?). Check for that and recreate
-- as necessary
if not flow.search_flow then
add_top_button(player)
end
if event.element.name == "looking-glass" then
if player.cursor_stack.valid_for_read then
identify_and_add_to_history(player.cursor_stack.name, player, false, true)
else
if flow.fluids_table then flow.fluids_table.destroy()
else
local fluids_table = flow.add{type = "table", column_count = math.ceil(global.n_fluids/10), name = "fluids_table", style = "slot_table"}
for _, fluid in pairs(game.fluid_prototypes) do
fluids_table.add{type = "sprite-button", name = "wiiuf_fluid_" .. fluid.name, sprite = "fluid/"..fluid.name, style = "slot_button", tooltip = fluid.localised_name}
end
end
end
--Label for fluid in search results. Check it before root "wiiuf_fluid_"
elseif event.element.name:find("wiiuf_fluid_label_") then
identify_and_add_to_history(event.element.name:sub(19), player, false, true)
--Sprite for fluid in search results
elseif event.element.name:find("wiiuf_fluid_") then
identify_and_add_to_history(event.element.name:sub(13), player, false, true)
if flow.fluids_table then flow.fluids_table.destroy() end
elseif event.element.name == "wiiuf_close_2" then
event.element.parent.parent.destroy()
elseif event.element.name == "wiiuf_close_3" then
event.element.parent.parent.parent.destroy()
elseif event.element.name:find("wiiuf_minimise_") then
minimise(event.element.name:sub(16), player, event.element.parent.parent.name == "wiiuf_left_frame")
-- Unminimizing button
elseif event.element.name:find("wiiuf_show_") then
identify_and_add_to_history(
event.element.name:sub(12), player, false, false)
if event.element.parent.name == "wiiuf_item_table" then
event.element.destroy()
if #player.gui.left.wiiuf_item_flow.wiiuf_item_table.children_names == 1 then
player.gui.left.wiiuf_item_flow.destroy()
end
else
mod_gui.get_frame_flow(player).wiiuf_left_frame.destroy()
end
elseif event.element.name:find("wiiuf_pin_") then
identify_and_add_to_history(
event.element.name:sub(11), player, true, false)
--Sprite for item in search results
elseif event.element.name:find("wiiuf_item_sprite_") then
identify_and_add_to_history(
event.element.name:sub(19), player, false, true)
flow.search_flow.search_bar_placeholder.search_bar_scroll.destroy()
flow.search_flow.search_bar_placeholder.wiiuf_search_bar_textfield.destroy()
--Label for item in search results
elseif event.element.name:find("wiiuf_item_label_") then
identify_and_add_to_history(
event.element.name:sub(18), player, false, true)
flow.search_flow.search_bar_placeholder.search_bar_scroll.destroy()
flow.search_flow.search_bar_placeholder.wiiuf_search_bar_textfield.destroy()
-- Sprite for recipe in list
elseif event.element.name:find("wiiuf_recipe_sprite_") then
show_recipe_details(event.element.name:sub(21), player)
-- Label for recipe in list
elseif event.element.name:find("wiiuf_recipe_label_") then
show_recipe_details(event.element.name:sub(20), player)
-- Sprite for item in recipe view
elseif event.element.name:find("wiiuf_recipe_item_sprite_") then
identify_and_add_to_history(
event.element.name:sub(26), player, false, false)
-- Label for item in recipe view
elseif event.element.name:find("wiiuf_recipe_item_label_") then
identify_and_add_to_history(
event.element.name:sub(25), player, false, false)
-- Sprite for fluid in mined_from view
elseif event.element.name:find("wiiuf_mined_fluid_sprite_") then
local number_and_name = event.element.name:sub(26)
local name = number_and_name:sub(number_and_name:find("_")+1)
identify_and_add_to_history(name, player, false, false)
-- Label for fluid in mined_from view
elseif event.element.name:find("wiiuf_mined_fluid_label_") then
local number_and_name = event.element.name:sub(25)
local name = number_and_name:sub(number_and_name:find("_")+1)
identify_and_add_to_history(name, player, false, false)
-- Back through item history
elseif event.element.name == "wiiuf_back" then
local history = global.wiiuf_item_history[player.index]
if history.position > 1 then
history.position = history.position - 1
end
identify(history.list[history.position], player)
-- Forward through item history
elseif event.element.name == "wiiuf_forward" then
local history = global.wiiuf_item_history[player.index]
if history.position < #history.list then
history.position = history.position + 1
end
identify(history.list[history.position], player)
end
end)
script.on_event("inspect_item", function(event)
local player = game.players[event.player_index]
local flow = get_wiiuf_flow(player)
if player.cursor_stack.valid_for_read then
clear_history(player)
identify_and_add_to_history(player.cursor_stack.name, player, true)
else
if flow.search_flow.search_bar_placeholder.wiiuf_search_bar_textfield then
flow.search_flow.search_bar_placeholder.wiiuf_search_bar_textfield.destroy()
if flow.search_flow.search_bar_placeholder.search_bar_scroll then
flow.search_flow.search_bar_placeholder.search_bar_scroll.destroy()
end
else
local text_field = flow.search_flow.search_bar_placeholder.add{
type = "textfield", name = "wiiuf_search_bar_textfield"
}
text_field.focus()
end
end
end)
function get_or_request_translation(player, localised_name, count)
local translations = global.wiiuf_item_translations[player.index]
local key = localised_name[1] or localised_name
local translation = translations[key]
if translation == nil then
if count < 100 then
player.request_translation(localised_name)
end
return "", count + 1
end
return translation, count
end
script.on_event(defines.events.on_gui_text_changed, function(event)
if event.element.name == "wiiuf_search_bar_textfield" then
local player = game.players[event.player_index]
local flow = get_wiiuf_flow(player)
if flow.search_flow.search_bar_placeholder.search_bar_scroll then
flow.search_flow.search_bar_placeholder.search_bar_scroll.destroy()
end
if string.len(event.element.text) < 2 then return end
local scroll_pane = flow.search_flow.search_bar_placeholder.add{
type = "scroll-pane",
name = "search_bar_scroll",
style = "small_spacing_scroll_pane_style"
}
scroll_pane.style.maximal_height = 250
local results_table = scroll_pane.add{
type = "table",
name = "results_table_"..math.random(100),
column_count = 2,
style = "row_table_style"
}
-- The first row of the table is regarded as the table headers and don't
-- get the table style applied to them
-- We don't want this however, so we fill it in with blanks.
results_table.add{type = "label", name = "wiiuf_filler_label_1"}
results_table.add{type = "label", name = "wiiuf_filler_label_2"}
-- remove capitals, and for internal names also purge special characters
-- and replace spaces with -
local text = event.element.text:lower()
local internal_text = text:gsub("([%^%$%(%)%%%.%[%]%*%+%-%?])", "%%%1")
internal_text = internal_text:gsub(" ", "%%-")
ensure_translations_available(player.index)
local translation_count = 0
for _, item in pairs(game.item_prototypes) do
translation, translation_count = get_or_request_translation(
player, item.localised_name, translation_count)
if item.name:lower():find(internal_text, 1, true) or
translation:lower():find(text, 1, true) then
results_table.add{
type = "sprite",
name = "wiiuf_item_sprite_" .. item.name,
sprite = "item/"..item.name
}
local label = results_table.add{
type = "label",
name = "wiiuf_item_label_" .. item.name,
caption = item.localised_name
}
label.style.minimal_height = 34
label.style.minimal_width = 101
label.style.vertical_align = "center"
end
end
for _, item in pairs(game.fluid_prototypes) do
translation, translation_count = get_or_request_translation(
player, item.localised_name, translation_count)
if item.name:lower():find(internal_text, 1, true) or
translation:lower():find(text, 1, true) then
results_table.add{
type = "sprite",
name = "wiiuf_fluid_" .. item.name,
sprite = "fluid/"..item.name
}
local label = results_table.add{
type = "label",
name = "wiiuf_fluid_label_" .. item.name,
caption = item.localised_name
}
label.style.minimal_height = 34
label.style.minimal_width = 101
label.style.vertical_align = "center"
end
end
end
end)
script.on_event(defines.events.on_gui_location_changed, function(event)
if event.element.name == "wiiuf_center_frame" then
if global.wiiuf_frame_locations == nil then
global.wiiuf_frame_locations = {}
end
global.wiiuf_frame_locations[event.player_index] = event.element.location
end
end)
script.on_event(defines.events.on_gui_closed, function(event)
-- If our window was the currently open window, we need to destroy it on
-- close
if event.gui_type == defines.gui_type.custom and event.element and
event.element.name == "wiiuf_center_frame" then
event.element.destroy()
end
end)
script.on_event(defines.events.on_string_translated, function(event)
-- This can be triggered by a different mod requesting translpations, so we
-- need to ensure that the translations are available
ensure_translations_available(event.player_index)
local translations = global.wiiuf_item_translations[event.player_index]
local key = event.localised_string[1] or event.localised_string
translations[key] = event.result
end)
-- Interface for other mods to open WIIRUF window
-- version - returns API version of this interface.
-- open_item - opens the WIIRUF GUI examining the given item. player_index and
-- item_name are mandatory. recipe_name is optional; if given then it will
-- open that recipe in the recipe pane. The recipe should probably be related
-- to the given item, but it doesn't technically have to be.
remote.add_interface("wiiuf", {
version=function()
return 1
end,
open_item=function(player_index, item_name, recipe_name)
player = game.players[player_index]
identify_and_add_to_history(item_name, player, false, true, recipe_name)
end
})
-- vim:et:ts=2:sw=2