384 lines
17 KiB
Lua
384 lines
17 KiB
Lua
local function get_transmutation_buttons(player, page, x, y)
|
|
local pages = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation")) or {}
|
|
if page > #pages then page = #pages end
|
|
if page < 1 then page = 1 end
|
|
if not pages[page] and page == 1 then
|
|
pages[page] = {}
|
|
end
|
|
local buttons = ""
|
|
for i = 0, 15 do
|
|
local itemstring = pages[page][i+1]
|
|
local column = (i%4)
|
|
local row = math.floor(i/4)
|
|
if itemstring then
|
|
buttons = buttons.."item_image_button["..tostring(x+column)..","..tostring(y+row)..";1,1;"..itemstring..";"..itemstring..";]"
|
|
else
|
|
buttons = buttons.."image_button["..tostring(x+column)..","..tostring(y+row)..";1,1;blank.png;empty_button"..tostring(i)..";]"
|
|
end
|
|
end
|
|
buttons = buttons.."label[5.75,5.25;"..tostring(page).."/"..tostring(#pages).."]"
|
|
player:get_meta():set_int("exchangeclone_transmutation_page", page)
|
|
return buttons
|
|
end
|
|
|
|
--<copied from MineClone>
|
|
local function filter_item(name, description, lang, filter)
|
|
local desc
|
|
if not lang then
|
|
desc = string.lower(description)
|
|
else
|
|
desc = string.lower(minetest.get_translated_string(lang, description))
|
|
end
|
|
return string.find(name, filter, nil, true) or string.find(desc, filter, nil, true)
|
|
end
|
|
|
|
function exchangeclone.reload_transmutation_list(player, search)
|
|
local meta = player:get_meta()
|
|
local player_energy = exchangeclone.get_player_energy(player)
|
|
local items_to_show = minetest.deserialize(meta:get_string("exchangeclone_transmutation_learned_items")) or {}
|
|
local lang = minetest.get_player_information(player:get_player_name()).lang_code
|
|
local pages = {}
|
|
local page_num = 1
|
|
local i = 0
|
|
if not search or search == "" then search = player:get_meta():get_string("exchangeclone_transmutation_search") or "" end
|
|
if search and search ~= "" then
|
|
local filtered_items = {}
|
|
for _,name in ipairs(items_to_show) do
|
|
local def = minetest.registered_items[name]
|
|
if def and (not def.groups.not_in_creative_inventory or def.groups.not_in_creative_inventory == 0) and def.description and def.description ~= "" then
|
|
if filter_item(string.lower(def.name), def.description, lang, search) then
|
|
table.insert(filtered_items, name)
|
|
end
|
|
end
|
|
items_to_show = table.copy(filtered_items)
|
|
end
|
|
end
|
|
for _, item in ipairs(items_to_show) do
|
|
local energy_value = exchangeclone.get_item_energy(item)
|
|
if energy_value <= player_energy and energy_value > 0 then
|
|
page_num = math.floor(i/16) + 1
|
|
if not pages[page_num] then pages[page_num] = {} end
|
|
pages[page_num][(i % 16) + 1] = item
|
|
i = i + 1
|
|
end
|
|
end
|
|
player:get_meta():set_string("exchangeclone_transmutation", minetest.serialize(pages))
|
|
return pages
|
|
end
|
|
|
|
local function add_to_output(player, amount, show)
|
|
local item = player:get_meta():get_string("exchangeclone_transmutation_selection")
|
|
if minetest.registered_items[item] then
|
|
local energy_value = exchangeclone.get_item_energy(item)
|
|
local player_energy = exchangeclone.get_player_energy(player)
|
|
local stack_max = ItemStack(item):get_stack_max()
|
|
if amount == true then amount = stack_max end
|
|
local max_amount = math.min(amount, stack_max, math.floor(player_energy/energy_value))
|
|
local inventory = minetest.get_inventory({type = "detached", name = "exchangeclone_transmutation_"..player:get_player_name()})
|
|
local added_amount = max_amount - inventory:add_item("output", ItemStack(item.." "..max_amount)):get_count()
|
|
exchangeclone.set_player_energy(player, player_energy - (energy_value * added_amount))
|
|
if show then exchangeclone.show_transmutation_table_formspec(player) end
|
|
end
|
|
end
|
|
|
|
local function handle_inventory(player, inventory, to_list, to_index, stack)
|
|
if to_list == "learn" then
|
|
local list = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation_learned_items")) or {}
|
|
if stack:get_name() == "exchangeclone:alchemical_tome" then
|
|
list = {}
|
|
local i = 0
|
|
for name, def in pairs(minetest.registered_items) do
|
|
if exchangeclone.get_item_energy(name) > 0 and not def.groups.not_in_creative_inventory then
|
|
i = i + 1
|
|
list[i] = name
|
|
end
|
|
end
|
|
table.sort(list)
|
|
player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list))
|
|
else
|
|
local individual_energy_value = exchangeclone.get_item_energy(stack:get_name())
|
|
if individual_energy_value <= 0 then return end
|
|
local energy_value = individual_energy_value * stack:get_count()
|
|
if stack:get_name() == "exchangeclone:exchange_orb" then
|
|
energy_value = energy_value + exchangeclone.get_orb_itemstack_energy(stack)
|
|
end
|
|
local player_energy = exchangeclone.get_player_energy(player)
|
|
local result = player_energy + energy_value
|
|
if result < 0 or result > 2147483647 then return end
|
|
exchangeclone.set_player_energy(player, exchangeclone.get_player_energy(player) + energy_value)
|
|
local item_index = table.indexof(list, stack:get_name())
|
|
if item_index == -1 then
|
|
list[#list+1] = stack:get_name()
|
|
table.sort(list)
|
|
player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list))
|
|
end
|
|
end
|
|
inventory:set_stack(to_list, to_index, nil)
|
|
exchangeclone.show_transmutation_table_formspec(player)
|
|
elseif to_list == "forget" then
|
|
-- end
|
|
elseif to_list == "charge" then
|
|
local player_energy = exchangeclone.get_player_energy(player)
|
|
local orb_energy = exchangeclone.get_orb_itemstack_energy(stack)
|
|
local charge_amount = math.min(exchangeclone.energy_max - orb_energy, player_energy)
|
|
if charge_amount > 0 then
|
|
exchangeclone.set_player_energy(player, player_energy - charge_amount)
|
|
exchangeclone.set_orb_energy(inventory, to_list, to_index, orb_energy + charge_amount)
|
|
exchangeclone.show_transmutation_table_formspec(player)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function check_for_table(player, inv)
|
|
if minetest.is_creative_enabled(player:get_player_name()) then return true end
|
|
if inv and inv:get_location().name ~= "exchangeclone_transmutation_"..player:get_player_name() then return false end
|
|
local def = player:get_wielded_item():get_definition()
|
|
local range = def and def.range
|
|
if not range then range = player:get_inventory():get_stack("hand", 1):get_definition().range end
|
|
if range then range = range + 1 else range = 5 end
|
|
if player:get_wielded_item():get_name() ~= "exchangeclone:transmutation_tablet"
|
|
and not minetest.find_node_near(player:get_pos(), range, "exchangeclone:transmutation_table", true) then return false end
|
|
return true
|
|
end
|
|
|
|
local function allow_inventory_action(player, stack, to_list, count, move, inventory)
|
|
if not check_for_table(player, inventory) then return 0 end
|
|
if to_list == "output" then
|
|
return 0
|
|
elseif to_list == "charge" and stack:get_name() ~= "exchangeclone:exchange_orb" then
|
|
return 0
|
|
elseif to_list == "learn" then
|
|
if stack:get_name() == "exchangeclone:alchemical_tome" then return count end
|
|
local name = stack:get_name()
|
|
local energy_value = exchangeclone.get_item_energy(stack:get_name())
|
|
local def = minetest.registered_items[name]
|
|
if energy_value <= 0 or def.groups.not_in_creative_inventory == 1 then
|
|
return 0
|
|
else
|
|
return count
|
|
end
|
|
elseif to_list == "forget" then
|
|
-- Kind of a weird way of doing this, but I couldn't make it work in the "on_inventory_* functions"
|
|
local list = minetest.deserialize(player:get_meta():get_string("exchangeclone_transmutation_learned_items")) or {}
|
|
local item_index = table.indexof(list, stack:get_name())
|
|
if item_index > -1 then
|
|
list[item_index] = list[#list]
|
|
list[#list] = nil
|
|
table.sort(list)
|
|
player:get_meta():set_string("exchangeclone_transmutation_learned_items", minetest.serialize(list))
|
|
local selection = player:get_meta():get_string("exchangeclone_transmutation_selection")
|
|
if selection == stack:get_name() then
|
|
player:get_meta():set_string("exchangeclone_transmutation_selection", "")
|
|
end
|
|
end
|
|
exchangeclone.show_transmutation_table_formspec(player)
|
|
return 0
|
|
else
|
|
return count
|
|
end
|
|
end
|
|
|
|
function exchangeclone.show_transmutation_table_formspec(player, data)
|
|
exchangeclone.reload_transmutation_list(player, data and data.search)
|
|
if not data then data = {} end
|
|
local player_energy = exchangeclone.get_player_energy(player)
|
|
local selection = data.selection or player:get_meta():get_string("exchangeclone_transmutation_selection")
|
|
local player_name = player:get_player_name()
|
|
local inventory_name = "detached:exchangeclone_transmutation_"..player_name
|
|
local label = "Transmutation\n"..tostring(player_energy).." energy"
|
|
|
|
local formspec =
|
|
"size[9,11]"..
|
|
"label[0,0;"..label.."]"..
|
|
"list["..inventory_name..";charge;0,1;1,1]"..
|
|
"label[0,2;Charge]"..
|
|
"list["..inventory_name..";forget;1,1;1,1]"..
|
|
"label[1,2;Forget]"..
|
|
"list["..inventory_name..";learn;2,1;1,1]"..
|
|
"label[2,2;Learn]"..
|
|
"list["..inventory_name..";output;2,3.5;2,2]"..
|
|
"label[2.5,3;Output]"..
|
|
get_transmutation_buttons(player, (data.page or player:get_meta():get_int("exchangeclone_transmutation_page")), 4, 1)..
|
|
"button[4,5;1,1;left_arrow;<]"..
|
|
"button[7,5;1,1;right_arrow;>]"..
|
|
"button[0,3.5;1,1;plus1;+1]"..
|
|
"button[1,3.5;1,1;plus5;+5]"..
|
|
"button[0,4.5;1,1;plus10;+10]"..
|
|
"button[1,4.5;1,1;plusstack;+Stack]"..
|
|
"field[4.25,0.25;4,1;search_box;;"..(data.search or player:get_meta():get_string("exchangeclone_transmutation_search") or "").."]"..
|
|
"field_close_on_enter[search_box;false]"..
|
|
"button[8,0;1,1;search_button;Search]"..
|
|
exchangeclone.inventory_formspec(0,6.25)..
|
|
"listring["..inventory_name..";output]"..
|
|
"listring[current_player;main]"..
|
|
"listring["..inventory_name..";learn]"..
|
|
"listring[current_player;main]"
|
|
|
|
if minetest.registered_items[selection] then
|
|
formspec = formspec.."item_image[0.5,2.5;0.8,0.8;"..selection.."]"
|
|
end
|
|
|
|
if exchangeclone.mineclone then
|
|
formspec = formspec..
|
|
mcl_formspec.get_itemslot_bg(0,1,1,1)..
|
|
mcl_formspec.get_itemslot_bg(1,1,1,1)..
|
|
mcl_formspec.get_itemslot_bg(2,1,1,1)..
|
|
mcl_formspec.get_itemslot_bg(2,3.5,2,2)
|
|
end
|
|
|
|
minetest.show_formspec(player_name, "exchangeclone_transmutation_table", formspec)
|
|
end
|
|
|
|
minetest.register_on_joinplayer(function(player, last_login)
|
|
local playername = player:get_player_name()
|
|
minetest.create_detached_inventory("exchangeclone_transmutation_"..playername, {
|
|
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
|
local stack = inv:get_stack(from_list, from_index)
|
|
stack:set_count(count)
|
|
return allow_inventory_action(player, stack, to_list, count, true, inv)
|
|
end,
|
|
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
|
local stack = inv:get_stack(to_list, to_index)
|
|
handle_inventory(player, inv, to_list, to_index, stack)
|
|
end,
|
|
allow_put = function(inv, listname, index, stack, player)
|
|
local count = stack:get_count()
|
|
return allow_inventory_action(player, stack, listname, count, false, inv)
|
|
end,
|
|
on_put = function(inv, listname, index, stack, player)
|
|
handle_inventory(player, inv, listname, index, stack)
|
|
end
|
|
}, playername)
|
|
local inventory = minetest.get_inventory({type = "detached", name = "exchangeclone_transmutation_"..playername})
|
|
inventory:set_size("charge", 1)
|
|
inventory:set_size("output", 4)
|
|
inventory:set_width("output", 2)
|
|
inventory:set_size("learn", 1)
|
|
inventory:set_size("forget", 1)
|
|
exchangeclone.reload_transmutation_list(player)
|
|
end)
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname == "exchangeclone_transmutation_table" then
|
|
if not check_for_table(player) then return end
|
|
for field, value in pairs(fields) do
|
|
if field == "search_box" or field == "quit" then
|
|
-- do nothing
|
|
elseif field == "right_arrow" then
|
|
exchangeclone.show_transmutation_table_formspec(player, {page = player:get_meta():get_int("exchangeclone_transmutation_page") + 1})
|
|
elseif field == "left_arrow" then
|
|
exchangeclone.show_transmutation_table_formspec(player, {page = player:get_meta():get_int("exchangeclone_transmutation_page") - 1})
|
|
elseif field == "search_button" or (field == "key_enter_field" and value == "search_box") then
|
|
local search = fields.search_box or ""
|
|
player:get_meta():set_string("exchangeclone_transmutation_search", search)
|
|
exchangeclone.show_transmutation_table_formspec(player)
|
|
elseif field == "plus1" then
|
|
add_to_output(player, 1, true)
|
|
elseif field == "plus5" then
|
|
add_to_output(player, 5, true)
|
|
elseif field == "plus10" then
|
|
add_to_output(player, 10, true)
|
|
elseif field == "plusstack" then
|
|
add_to_output(player, true, true)
|
|
elseif minetest.registered_items[field] then
|
|
player:get_meta():set_string("exchangeclone_transmutation_selection", field)
|
|
exchangeclone.show_transmutation_table_formspec(player, {selection = field})
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_tool("exchangeclone:transmutation_tablet", {
|
|
description = "Transmutation Tablet",
|
|
groups = {disable_repair = 1, fire_immune = 1},
|
|
wield_image = "exchangeclone_transmutation_table.png",
|
|
inventory_image = "exchangeclone_transmutation_table.png",
|
|
on_secondary_use = function(itemstack, player, pointed_thing)
|
|
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
|
|
if click_test ~= false then
|
|
return click_test
|
|
end
|
|
exchangeclone.show_transmutation_table_formspec(player)
|
|
end,
|
|
on_place = function(itemstack, player, pointed_thing)
|
|
local click_test = exchangeclone.check_on_rightclick(itemstack, player, pointed_thing)
|
|
if click_test ~= false then
|
|
return click_test
|
|
end
|
|
exchangeclone.show_transmutation_table_formspec(player)
|
|
end
|
|
})
|
|
|
|
minetest.register_node("exchangeclone:transmutation_table", {
|
|
description = "Transmutation Table",
|
|
paramtype2 = "wallmounted",
|
|
tiles = {"exchangeclone_transmutation_table.png", "exchangeclone_transmutation_table.png", "exchangeclone_transmutation_table_side.png"},
|
|
groups = {oddly_breakable_by_hand = 3, handy = 1},
|
|
drawtype = "nodebox",
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {-0.5, -0.5, -0.5, 0.5, -0.3, 0.5},
|
|
},
|
|
sounds = exchangeclone.sound_mod.node_sound_stone_defaults(),
|
|
on_rightclick = function(pos, node, player, itemstack, pointed_thing)
|
|
exchangeclone.show_transmutation_table_formspec(player)
|
|
end,
|
|
_mcl_hardness = 0.6,
|
|
_mcl_blast_resistance = 6,
|
|
})
|
|
|
|
minetest.register_tool("exchangeclone:alchemical_tome", {
|
|
description = "Alchemical Tome",
|
|
inventory_image = "exchangeclone_alchemical_tome.png",
|
|
wield_image = "exchangeclone_alchemical_tome.png",
|
|
groups = {disable_repair = 1, fire_immune = 1}
|
|
})
|
|
|
|
local book = "default:book"
|
|
local obsidian = "default:obsidian"
|
|
local stone = "default:stone"
|
|
if exchangeclone.mineclone then
|
|
book = "mcl_books:book"
|
|
obsidian = "mcl_core:obsidian"
|
|
stone = "mcl_core:stone"
|
|
end
|
|
|
|
minetest.register_craft({
|
|
output = "exchangeclone:transmutation_table",
|
|
recipe = {
|
|
{obsidian, stone, obsidian},
|
|
{stone, "exchangeclone:philosophers_stone", stone},
|
|
{obsidian, stone, obsidian}
|
|
},
|
|
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = "exchangeclone:transmutation_tablet",
|
|
recipe = {
|
|
{"exchangeclone:dark_matter_block", stone, "exchangeclone:dark_matter_block"},
|
|
{stone, "exchangeclone:transmutation_table", stone},
|
|
{"exchangeclone:dark_matter_block", stone, "exchangeclone:dark_matter_block"}
|
|
},
|
|
})
|
|
|
|
minetest.register_craft({
|
|
output = "exchangeclone:alchemical_tome",
|
|
recipe = {
|
|
{"", book, ""},
|
|
{"exchangeclone:exchange_orb", "exchangeclone:philosophers_stone", "exchangeclone:exchange_orb"},
|
|
{"", "exchangeclone:red_matter", ""}
|
|
},
|
|
replacements = {{"exchangeclone:philosophers_stone", "exchangeclone:philosophers_stone"}}
|
|
})
|
|
|
|
minetest.register_craft_predict(function(itemstack, player, old_craft_grid, craft_inv)
|
|
if itemstack == ItemStack("exchangeclone:alchemical_tome") then
|
|
if exchangeclone.get_orb_itemstack_energy(old_craft_grid[4]) >= exchangeclone.energy_max
|
|
and exchangeclone.get_orb_itemstack_energy(old_craft_grid[6]) >= exchangeclone.energy_max then
|
|
return
|
|
else
|
|
return ItemStack("")
|
|
end
|
|
end
|
|
end) |