From 40f62954138db76e4833c1bf4597067102cf168e Mon Sep 17 00:00:00 2001 From: ThePython <87204246+ThePython10110@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:20:27 -0800 Subject: [PATCH] All buttons besides rename and delete working! --- exchangeclone/alchemical_books.lua | 141 +++++++++++++++++++++++--- exchangeclone/transmutation_table.lua | 2 +- 2 files changed, 128 insertions(+), 15 deletions(-) diff --git a/exchangeclone/alchemical_books.lua b/exchangeclone/alchemical_books.lua index 355722f..2e5ea43 100644 --- a/exchangeclone/alchemical_books.lua +++ b/exchangeclone/alchemical_books.lua @@ -1,3 +1,5 @@ +-- There's a lot of duplicated code in this file, but removing it means adding more duplicated code... so I'm just going to leave it. + local function extract_dimension(pos) if exchangeclone.mtg then if minetest.get_modpath("nether") then @@ -60,7 +62,7 @@ end local base_formspec = { "formspec_version[3]", "size[13,10]", - "textarea[8.5,0.5;3,0.7;name;;Location Name]", + "field[8.5,0.5;3,0.7;name;;]", "button[11.5,0.5;1,0.7;add;Add]", "button[8.5,1.5;4,1;teleport;Teleport]", "button[8.5,2.75;4,1;rename;Rename]", @@ -71,7 +73,7 @@ local base_formspec = { "field_enter_after_edit[name;false]" } -local using_stack_data = {} +local formspec_data = {} -- player: The player to be shown the formspec -- index: The index of the location the player is currently selecting @@ -81,7 +83,8 @@ local function show_formspec(player, index, use_stack_data) if minetest.get_item_group(stack:get_name(), "exchangeclone_alchemical_book") < 1 then return end - using_stack_data[player:get_player_name()] = use_stack_data + formspec_data[player:get_player_name()] = formspec_data[player:get_player_name()] or {} + formspec_data[player:get_player_name()].using_stack_data = use_stack_data local book_data = stack:get_definition().alchemical_book_data local data = minetest.deserialize((use_stack_data and stack or player):get_meta():get_string("exchangeclone_alchemical_book")) local formspec = table.copy(base_formspec) @@ -95,7 +98,10 @@ local function show_formspec(player, index, use_stack_data) if #data.locations > 0 then formspec[#formspec+1] = "textlist[0.5,0.5;7,7;location_list;" for _, location in ipairs(data.locations) do - formspec[#formspec+1] = minetest.formspec_escape(location.name)..";" + formspec[#formspec+1] = minetest.formspec_escape(location.name).."," + end + if index then + formspec[#formspec+1] = ";"..index end formspec[#formspec+1] = "]" end @@ -105,23 +111,39 @@ local function show_formspec(player, index, use_stack_data) local dimension, pos = extract_dimension(selected.pos) local dimension_string = dimension and (" ("..dimension..")") or "" local distance = vector.distance(pos, player_pos) - local cost = book_data.emc_per_node*distance + local cost = math.floor(book_data.emc_per_node*distance*20)/20 local info = minetest.formspec_escape(string.format([[%s -Position: %s, %s, %s%s -Distance: %s -Cost: %s EMC]], selected.name, pos.x, pos.y, pos.z, dimension_string, distance, cost)) +Position: %.1f, %.1f, %.1f%s +Distance: %.1f +Cost: %s EMC]], selected.name, pos.x, pos.y, pos.z, dimension_string, exchangeclone.format_number(distance), exchangeclone.format_number(cost))) formspec[#formspec+1] = "textarea[0.5,8;4,4;;;"..info.."]" end end minetest.show_formspec(player:get_player_name(), "exchangeclone_alchemical_book", table.concat(formspec)) end +minetest.register_on_joinplayer(function(player) + formspec_data[player:get_player_name()] = nil +end) + +minetest.register_on_leaveplayer(function(player) + formspec_data[player:get_player_name()] = nil +end) + minetest.register_on_player_receive_fields(function(player, formname, fields) if formname ~= "exchangeclone_alchemical_book" then return end - if fields.quit == "true" then return end - local use_stack_data = using_stack_data[player:get_player_name()] + if fields.quit then + formspec_data[player:get_player_name()] = nil + return + end + local use_stack_data = formspec_data[player:get_player_name()].using_stack_data local stack = player:get_wielded_item() - local data = minetest.deserialize((use_stack_data and stack or player):get_meta():get_string("exchangeclone_alchemical_book")) + if minetest.get_item_group(stack:get_name(), "exchangeclone_alchemical_book") < 1 then + return + end + local meta = (use_stack_data and stack or player):get_meta() + local data = minetest.deserialize(meta:get_string("exchangeclone_alchemical_book")) + local index = formspec_data[player:get_player_name()].index if type(data) ~= "table" then data = {} end @@ -129,13 +151,104 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) data.locations = {} end minetest.log(dump(fields)) + if fields.key_enter_field == "name" or fields.add then + local name = fields.name + if name == "" then return end + for _, location in pairs(data.locations) do + if location.name == name then + minetest.chat_send_player(player:get_player_name(), "There is already a location called '"..location.name.."'") + return + end + end + data.locations[#data.locations+1] = {name = name, pos = player:get_pos()} + meta:set_string("exchangeclone_alchemical_book", minetest.serialize(data)) + if use_stack_data then player:set_wielded_item(stack) end + show_formspec(player, index, use_stack_data) + elseif fields.teleport then + if not data.locations[index] then return end + local pos = data.locations[index].pos + local _, adjusted_pos = extract_dimension(pos) + local distance = vector.distance(player:get_pos(), adjusted_pos) + local emc_per_node = stack:get_definition().alchemical_book_data.emc_per_node + local cost = distance*emc_per_node + cost = math.floor(cost*20)/20 -- floor to nearest .05, might fail if unless emc_per_node is over half a million + local player_emc = exchangeclone.get_player_emc(player) + if player_emc < cost then + minetest.chat_send_player(player:get_player_name(), "Not enough EMC to teleport.") + else + player:set_pos(pos) + exchangeclone.add_player_emc(player, -cost) + end + show_formspec(player, index, use_stack_data) + elseif fields.location_list then + local exploded = minetest.explode_textlist_event(fields.location_list) + index = math.min(exploded.index, #data.locations) + minetest.log(dump(#data.locations)) + if not formspec_data[player:get_player_name()] then formspec_data[player:get_player_name()] = {} end + formspec_data[player:get_player_name()].index = index + if exploded.type == "DCL" then + local pos = data.locations[index].pos + local _, adjusted_pos = extract_dimension(pos) + local distance = vector.distance(player:get_pos(), adjusted_pos) + local emc_per_node = stack:get_definition().alchemical_book_data.emc_per_node + local cost = distance*emc_per_node + local player_emc = exchangeclone.get_player_emc(player) + if player_emc < cost then + minetest.chat_send_player(player:get_player_name(), "Not enough EMC to teleport.") + else + player:set_pos(pos) + exchangeclone.add_player_emc(-cost) + end + end + show_formspec(player, index, use_stack_data) + elseif fields.up then + if not data.locations[index] then return end + if index > 1 then + data.locations[index], data.locations[index-1] = data.locations[index-1], data.locations[index] + meta:set_string("exchangeclone_alchemical_book", minetest.serialize(data)) + if use_stack_data then player:set_wielded_item(stack) end + index = index - 1 + if not formspec_data[player:get_player_name()] then formspec_data[player:get_player_name()] = {} end + formspec_data[player:get_player_name()].index = index + show_formspec(player, index, use_stack_data) + end + elseif fields.down then + if not data.locations[index] then return end + if index < #data.locations then + data.locations[index], data.locations[index+1] = data.locations[index+1], data.locations[index] + meta:set_string("exchangeclone_alchemical_book", minetest.serialize(data)) + if use_stack_data then player:set_wielded_item(stack) end + index = index + 1 + if not formspec_data[player:get_player_name()] then formspec_data[player:get_player_name()] = {} end + formspec_data[player:get_player_name()].index = index + show_formspec(player, index, use_stack_data) + end + end end) +local function alchemical_book_function(itemstack, player, pointed_thing) + local use_stack_data = itemstack:get_meta():get_int("exchangeclone_use_stack_data") + if use_stack_data == 0 then + use_stack_data = nil + end + if player:get_player_control().sneak then + if use_stack_data then + minetest.chat_send_player(player:get_player_name(), "Using player data") + itemstack:get_meta():set_int("exchangeclone_use_stack_data", 0) + else + minetest.chat_send_player(player:get_player_name(), "Using book data") + itemstack:get_meta():set_int("exchangeclone_use_stack_data", 1) + end + return itemstack + else + show_formspec(player, nil, use_stack_data) + end +end + minetest.register_tool("exchangeclone:basic_alchemical_book", { description = "Basic Alchemical Book", groups = {exchangeclone_alchemical_book = 1}, alchemical_book_data = {emc_per_node = 1000}, - on_secondary_use = function(itemstack, player, pointed_thing) - show_formspec(player) - end + on_secondary_use = alchemical_book_function, + on_place = alchemical_book_function }) \ No newline at end of file diff --git a/exchangeclone/transmutation_table.lua b/exchangeclone/transmutation_table.lua index d5d4c4c..ff0595c 100644 --- a/exchangeclone/transmutation_table.lua +++ b/exchangeclone/transmutation_table.lua @@ -108,7 +108,7 @@ local function add_to_output(player, amount, show) local max_amount = math.min(amount, stack_max, math.floor(player_emc/emc_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_emc(player, math.min(player_emc, player_emc - (emc_value * added_amount))) -- not sure if "math.min()" is necessary + exchangeclone.add_player_emc(player, math.min(player_emc, -(emc_value * added_amount))) -- not sure if "math.min()" is necessary if show then exchangeclone.show_transmutation_table_formspec(player) end end end