Update 1.0.1

master
Noodlemire 2021-08-31 23:33:02 -05:00
parent f44d862e7e
commit 4c38c142ce
14 changed files with 531 additions and 103 deletions

View File

@ -303,6 +303,7 @@ The arguments for the above "list" Formspec Element would be represented as such
* lua_inv.dynamic_list(inv_location, listname, x, y, w, h, start_index) - Like a list[], except it's a grid of buttons to form a lua_inv-compatible UI.
* lua_inv.stack_mode_selector(x, y) - Meant to be paired with dynamic_list to offer more options for moving around ItemStacks.
* lua_inv.drop_item_button(x, y) - Provides a way for formspecs with dynamic lists to drop items onto the ground.
* lua_inv.active_indicator(x, y, w, y, base_img, cover_img, var)- Like an image[], except var% of cover_img will be drawn over base_img.
@ -400,5 +401,8 @@ lua_inv.get_detached_inventory(name) - Returns a detached inventory indexed by t
[Misc. Functions]
* lua_inv.update_hotbar(player) - Update the player's hotbar visuals in the event of a change. Automatically called for most use cases.
* lua_inv.change_involves_list(change, listname) - If the change table has an involved stack in the given listname, return the stack.
* lua_inv.set_list_take_only(inv, change, listname) - Use in an allow_change callback to prevent players from placing items in the given listname.
* lua_inv.tiles_to_cube_textures({tiles}) - Converts a table of tiles from an object's properties into a table of textures for an entity.
* lua_inv.update_hotbar(player) - Update the player's hotbar visuals in the event of a change. Automatically called for most use cases.

15
changelog.txt Normal file
View File

@ -0,0 +1,15 @@
1.0.1:
-Added the active_indicator[] element, which can draw a percent-based part of an image over another image, using a defined meta field.
-Added support for the /give command
-Added support for default furnaces
-In Dynamic Lists, non-cubic nodes will now display in their proper form using the item_image[] element.
-Fixed the hotbar's functionality on mobile. Tapping each slot now switches the wield index properly.
-Fixed the "Press this or ESC to continue" window on mobile. Pressing the button now properly opens the inventory, rather than closing the form.
-Added a workaround for mobile users being unable to place blocks. The Aux button can now place blocks as well.
-To help with aiming the Aux button, a crosshair is now shown on mobile, as the regular one is permanently disabled by the Android Client.
-Mobile's Aux key and extra crosshair can both be disabled in the settings.
-Test items can now be disabled in the settings.
-The hotbar HUD should now scale properly across different screen resolutions.
-The game will no longer crash when you use an unknown item.
-Right-clicking while holding a worn tool will no longer magically repair it.

View File

@ -56,6 +56,8 @@ function lua_inv.dynamic_formspec(input_elems)
end,
form = function(self, player, formname, fields)
self.meta:set_string("formname", formname)
local formspec = ""
for i = 1, self:size() do
@ -85,8 +87,9 @@ function lua_inv.dynamic_formspec(input_elems)
end
function lua_inv.get_df_meta(player)
if lua_inv.open_formspecs[player:get_player_name()] then
return lua_inv.open_formspecs[player:get_player_name()].meta, lua_inv.open_formspecs[player:get_player_name()].temp_meta
local open = lua_inv.open_formspecs[player:get_player_name()]
if open then
return open.meta, open.temp_meta
end
end

View File

@ -55,20 +55,7 @@ function lua_inv.survival_inventory.ref(player)
return lua_inv.inventory(player:get_player_name(),
--Allow Change
function(inv, change)
if change.type == "swap" and ((change.stack1.parent.list == "craftpreview" and change.stack2:is_empty()) or
(change.stack2.parent.list == "craftpreview" and change.stack1:is_empty())) then
return true
end
if change.type == "swap" and (change.stack1.parent.list == "craftpreview" or change.stack2.parent.list == "craftpreview") then
return false
end
if change.type == "set" and change.stack.parent.list == "craftpreview" and (change.key ~= "count" or change.val ~= 0) then
return false
end
return true
return lua_inv.set_list_take_only(inv, change, "craftpreview")
end,
nil,

View File

@ -0,0 +1,32 @@
function lua_inv.active_indicator(in_x, in_y, in_w, in_h, in_base_img, in_cover_img, in_var)
return lua_inv.formspec_element(
"fuel_indicator",
{
{in_x, in_y},
{in_w, in_h},
in_base_img,
in_cover_img,
in_var,
},
function(self, player, formname, fields)
local meta, temp_meta = lua_inv.get_df_meta(player)
if not meta then
minetest.log("warning", "Warning: Attempt to form a closed formspec.")
return ""
end
local pos = self.args[1]
local size = self.args[2]
local base_img = self.args[3]
local cover_img = self.args[4]
local var = self.args[5]
local variable = meta:get_float(var)
return "image["..pos[1]..","..pos[2]..";"..size[1]..","..size[2]..";"..base_img.."^[lowpart:"..(variable)..":"..cover_img.."]"
end
)
end

View File

@ -187,13 +187,15 @@ function lua_inv.dynamic_list(in_inv_location, in_listname, in_x, in_y, in_w, in
str = str.."image_button["..(pos[1] + x - 1)..','..(pos[2] + y - 1)..";1,1;;"..slotname..";]"
if not stack:is_empty() then
if stack and not stack:is_empty() then
str = str.."tooltip["..slotname..';'..stack:get_description()..']'
local anim = stack:get_animation()
if anim then
str = str.."animated_image["..(pos[1] + x - 1)..','..(pos[2] + y - 1)..";1,1;"..stack:get_name()..";"
..stack:get_inventory_image()..";"..anim.frames..";"..anim.speed..";]"
elseif not stack:get_inventory_image(true) then
str = str.."item_image["..(pos[1] + x - 1)..','..(pos[2] + y - 1)..";1,1;"..stack:get_name().."]"
else
str = str.."image["..(pos[1] + x - 1)..','..(pos[2] + y - 1)..";1,1;"..stack:get_inventory_image()..']'
end

View File

@ -21,6 +21,11 @@ local hotbar_data = {}
local default_ratio = minetest.settings:get("screen_w") / minetest.settings:get("screen_h")
local function default_pos(i)
--0.348 + .0435 * (i - 1), 0.9625
return 0.30555 + .05555 * (i - 1), -32
end
function lua_inv.update_hotbar(player)
local pname = player:get_player_name()
@ -68,15 +73,17 @@ function lua_inv.update_hotbar(player)
end
if not hotbar_data[pname]["hotbar_slot_"..i] then
local x, y = default_pos(i)
hotbar_data[pname]["hotbar_slot_"..i] = player:hud_add({
hud_elem_type = "image",
text = img,
scale = {x = -4, y = -4 * hotbar_data[pname].aspect_ratio},
position = {x = 0.348 + .0435 * (i - 1), y = 0.9625},
position = {x = 0.5, y = 1},
direction = 1,
alignment = {x = 0, y = 0},
offset = {x = 0, y = 0},
offset = {x = x * 1000 - 500, y = y},
z_index = 1
})
@ -86,10 +93,10 @@ function lua_inv.update_hotbar(player)
number = "0xFFFFFF",
scale = {x = -4, y = -4 * hotbar_data[pname].aspect_ratio},
position = {x = 0.363 + .0435 * (i - 1), y = 0.9825},
position = {x = 0.5, y = 1},
direction = 1,
alignment = {x = 0, y = 0},
offset = {x = 0, y = 0},
offset = {x = (x + 0.015) * 1000 - 500, y = y + 16},
z_index = 1
})
@ -98,10 +105,10 @@ function lua_inv.update_hotbar(player)
text = wear_img,
scale = {x = -4, y = -4 * hotbar_data[pname].aspect_ratio},
position = {x = 0.348 + .0435 * (i - 1), y = 0.9625},
position = {x = 0.5, y = 1},
direction = 1,
alignment = {x = 0, y = 0},
offset = {x = 0, y = 0},
offset = {x = x * 1000 - 500, y = y},
z_index = 1
})
else
@ -114,6 +121,7 @@ end
minetest.register_on_joinplayer(function(player, last_login)
local pname = player:get_player_name()
local x, y = default_pos(1)
hotbar_data[pname] = {
wield_index = player:get_wield_index(),
@ -121,17 +129,17 @@ minetest.register_on_joinplayer(function(player, last_login)
animation = {}
}
player:hud_set_flags({hotbar = false})
minetest.after(0.25, player.hud_set_flags, player, {hotbar = false})
player:hud_add({
hud_elem_type = "image",
text = "lua_inv_hotbar.png",
scale = {x = 0.75, y = 0.75},
position = {x = 0.5, y = 0.9625},
position = {x = 0.5, y = 1},
direction = 1,
alignment = {x = 0, y = 0},
offset = {x = 0, y = 0},
offset = {x = 0, y = y},
z_index = 0
})
@ -140,10 +148,10 @@ minetest.register_on_joinplayer(function(player, last_login)
text = "lua_inv_selected.png",
scale = {x = 3.25, y = 3.25},
position = {x = 0.348, y = 0.9625},
position = {x = 0.5, y = 1},
direction = 1,
alignment = {x = 0, y = 0},
offset = {x = 0, y = 0},
offset = {x = x * 1000 - 500, y = y},
z_index = 2
})
@ -183,11 +191,9 @@ minetest.register_globalstep(function(dtime)
if hotbar_data[pname].wield_index ~= player:get_wield_index() then
hotbar_data[pname].wield_index = player:get_wield_index()
local x, y = default_pos(hotbar_data[pname].wield_index)
player:hud_change(hotbar_data[pname].hotbar_wield_index, "position", {
x = 0.348 + .0435 * (player:get_wield_index() - 1),
y = 0.9625
})
player:hud_change(hotbar_data[pname].hotbar_wield_index, "offset", {x = x * 1000 - 500, y = y})
lua_inv.update_held_item_data(player)
end

View File

@ -36,6 +36,7 @@ dofile(mp.."formspec_elements/formspec_element.lua")
dofile(mp.."formspec_elements/dynamic_list.lua")
dofile(mp.."formspec_elements/stack_mode_selector.lua")
dofile(mp.."formspec_elements/drop_item_button.lua")
dofile(mp.."formspec_elements/active_indicator.lua")
dofile(mp.."dynamic_formspecs/manager.lua")
dofile(mp.."dynamic_formspecs/dynamic_formspec.lua")

View File

@ -84,9 +84,23 @@ minetest.register_on_joinplayer(function(player)
player_inventory.form = lua_inv.survival_inventory.form(player)
lua_inv.player_inventory[player:get_player_name()] = player_inventory
player:set_inventory_formspec("size[8,8]button_exit[1,1;6,6;continue;Please hit ESC to continue.]")
player:set_inventory_formspec("size[8,8]button[1,1;6,6;continue;Please this or hit ESC to continue.]")
lua_inv.update_held_item_data(player)
if minetest.settings:get_bool("lua_inv_mobile_support", true) then
player:hud_add({
hud_elem_type = "image",
text = "lua_inv_crosshair.png",
scale = {x = 1, y = 1},
position = {x = 0.5, y = 0.5},
direction = 1,
alignment = {x = 0, y = 0},
offset = {x = 0, y = 0},
z_index = 1
})
end
end)
function lua_inv.get_player_wielded_item(player)
@ -140,7 +154,7 @@ local function get_pointed_thing(player, tool)
--Get the tool's definition, to check its digparams and range
local def = tool:get_definition()
--Create a ray between the player's eyes and where they're looking, limited by their tool's range
local ray = Raycast(pos, vector.add(pos, vector.multiply(player:get_look_dir(), def.range or minetest.registered_items[""].range or 4)))
local ray = Raycast(pos, vector.add(pos, vector.multiply(player:get_look_dir(), (def and def.range) or minetest.registered_items[""].range or 4)))
--Return the first pointable thing found that isn't the player calling this
for pt in ray do
@ -182,7 +196,7 @@ controls.register_on_press(function(player, control)
lua_inv.set_player_wielded_item(player, itemstack)
end
if control == "place" then
if control == "place" or (minetest.settings:get_bool("lua_inv_mobile_support", true) and control == "aux1") then
local itemstack = lua_inv.get_player_wielded_item(player)
if itemstack:is_empty() then return end
@ -201,7 +215,7 @@ controls.register_on_press(function(player, control)
if pointed_thing.type == "node" then
itemstack = lua_inv.itemstack_to_userdata(itemstack)
local output = (def.on_place or minetest.item_place_node)(itemstack, player, pointed_thing)
local output = (def.on_place or minetest.item_place)(itemstack, player, pointed_thing)
if output then
itemstack = output
@ -220,7 +234,7 @@ controls.register_on_press(function(player, control)
end
if itemstack then
lua_inv.set_player_wielded_item(player, lua_inv.itemstack_from_userdata(itemstack))
lua_inv.set_player_wielded_item(player, itemstack)
end
end
end)

View File

@ -215,16 +215,19 @@ local static = {
minetest.registered_items["unknown"].description
end,
get_inventory_image = function(self)
get_inventory_image = function(self, nil_if_tiles)
if not self:is_known() then
return "unknown_item.png"
end
local image = self:get_meta():get("inventory_image") or self:get_definition().inventory_image
local tiles = self:get_definition().tiles
local def = self:get_definition()
local image = self:get_meta():get("inventory_image") or def.inventory_image
local tiles = def.tiles
if (not image or image == "") then
if tiles then
if nil_if_tiles then return end
local t2 = tileToString(tiles[3]) or tileToString(tiles[2]) or tileToString(tiles[1])
local t3 = tileToString(tiles[6]) or t2
image = minetest.inventorycube(tileToString(tiles[1]), t3, t2)
@ -431,6 +434,9 @@ local static = {
}
function lua_inv.itemstack(input_name, input_count, input_wear, input_meta, input_parent)
input_name = (not input_count or input_count > 0) and input_name
input_count = input_name and input_name ~= "" and input_count
local itemstack = {
name = input_name or "",
count = input_count or (input_name and 1) or 0,
@ -508,6 +514,8 @@ end
function lua_inv.itemstack_from_string(str)
local splits = str:split("return", false, 1)
if not splits[1] then return lua_inv.itemstack() end
local stats = splits[1]:split(' ')
local meta = nil
@ -520,10 +528,14 @@ function lua_inv.itemstack_from_string(str)
end
function lua_inv.itemstack_from_userdata(itemstack)
if type(itemstack) ~= "userdata" then return itemstack end
return lua_inv.itemstack(itemstack:get_name(), itemstack:get_count(), itemstack:get_wear() / 655.35, itemstack:get_meta():to_table().fields)
end
function lua_inv.itemstack_to_userdata(itemstack)
if type(itemstack) ~= "table" then return itemstack end
local stack = ItemStack({
name = itemstack:get_name(),
count = itemstack:get_count(),

157
misc.lua
View File

@ -17,6 +17,31 @@ License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--]]
function lua_inv.change_involves_list(change, listname)
if change.stack and change.stack.parent.list == listname then return change.stack end
if change.stack1 and change.stack1.parent.list == listname then return change.stack2 end
if change.stack2 and change.stack2.parent.list == listname then return change.stack1 end
end
function lua_inv.set_list_take_only(inv, change, listname)
if change.type == "swap" and ((change.stack1.parent.list == listname and change.stack2:is_empty()) or
(change.stack2.parent.list == listname and change.stack1:is_empty())) then
return true
end
if change.type == "swap" and (change.stack1.parent.list == listname or change.stack2.parent.list == listname) then
return false
end
if change.type == "set" and change.stack.parent.list == listname and (change.key ~= "count" or change.val ~= 0) then
return false
end
return true
end
minetest.register_chatcommand("is", {
description = "Get the item string of the item that you are holding.",
@ -28,67 +53,99 @@ minetest.register_chatcommand("is", {
end
})
minetest.register_craftitem("lua_inv:die", {
description = "Roll the die!",
inventory_image = "lua_inv_die_1.png",
local function give_item(name, param)
if not minetest.get_player_by_name(name):get_pos() then return end
_lua_inv_on_use = function(itemstack, user, pointed_thing)
local meta = itemstack:get_meta()
local side = math.random(6)
local playername, itemname = param:match("^([^ ]+) +(.+)$")
minetest.chat_send_player(user:get_player_name(), "You got a "..side.."!")
meta:set_string("inventory_image", "lua_inv_die_"..side..".png")
local player = minetest.get_player_by_name(playername or "")
local itemstack = lua_inv.itemstack_from_string(itemname or "")
if not player or not player:get_pos() or itemstack:is_empty() or not itemstack:is_known() or itemstack:get_name() == "ignore" then
return false, "The provided player or itemstack is invalid."
end
})
local torch_def = {
description = "Animated Torch",
inventory_image = "lua_inv_torch_animated.png",
itemstack = lua_inv.player_inventory[name].inv:add_item("main", itemstack)
_lua_inv_animation = function(self, frame)
return {frames = 16, speed = 250, frame_template = "lua_inv_torch_%d.png"}
if not itemstack:is_empty() then
return false, "That player's inventory was too full. Could not give all of the requested stack."
end
}
if minetest.get_modpath("default") then
minetest.override_item("default:torch", torch_def)
minetest.register_alias("lua_inv:torch", "default:torch")
else
minetest.register_craftitem("lua_inv:torch", torch_def)
return true, "Successfully given."
end
minetest.register_craftitem("lua_inv:pick", {
description = "Stackable Pickaxe",
inventory_image = "lua_inv_stackwear_pick.png",
tool_capabilities = {
full_punch_interval = 1.2,
max_drop_level=0,
groupcaps={
cracky = {times={[3]=0.60}, uses=2, maxlevel=1},
},
damage_groups = {fleshy=2},
},
sound = {breaks = "default_tool_breaks"},
groups = {pickaxe = 1}
minetest.override_chatcommand("give", {
func = give_item
})
minetest.register_chatcommand("testitems", {
description = "Gain a set of test lua_inv test items.",
privs = {debug = true},
minetest.override_chatcommand("giveme", {
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player:get_pos() then return end
local inv = lua_inv.player_inventory[name].inv
inv:add_item("main", lua_inv.itemstack("lua_inv:die"))
inv:add_item("main", lua_inv.itemstack("lua_inv:torch"))
inv:add_item("main", lua_inv.itemstack("lua_inv:pick", 66, 75))
inv:add_item("main", lua_inv.itemstack("lua_inv:pick", 75, 33))
return give_item(name, name.." "..(param or ""))
end
})
if minetest.settings:get_bool("lua_inv_test_items") then
minetest.register_craftitem("lua_inv:die", {
description = "Roll the die!",
inventory_image = "lua_inv_die_1.png",
_lua_inv_on_use = function(itemstack, user, pointed_thing)
local meta = itemstack:get_meta()
local side = math.random(6)
minetest.chat_send_player(user:get_player_name(), "You got a "..side.."!")
meta:set_string("inventory_image", "lua_inv_die_"..side..".png")
end
})
local torch_def = {
description = "Animated Torch",
inventory_image = "lua_inv_torch_animated.png",
_lua_inv_animation = function(self, frame)
return {frames = 16, speed = 250, frame_template = "lua_inv_torch_%d.png"}
end
}
if minetest.get_modpath("default") then
minetest.override_item("default:torch", torch_def)
minetest.register_alias("lua_inv:torch", "default:torch")
else
minetest.register_craftitem("lua_inv:torch", torch_def)
end
minetest.register_craftitem("lua_inv:pick", {
description = "Stackable Pickaxe",
inventory_image = "lua_inv_stackwear_pick.png",
tool_capabilities = {
full_punch_interval = 1.2,
max_drop_level=0,
groupcaps={
cracky = {times={[3]=0.60}, uses=2, maxlevel=1},
},
damage_groups = {fleshy=2},
},
sound = {breaks = "default_tool_breaks"},
groups = {pickaxe = 1}
})
minetest.register_chatcommand("testitems", {
description = "Gain a set of test lua_inv test items.",
privs = {debug = true},
func = function(name, param)
local player = minetest.get_player_by_name(name)
if not player:get_pos() then return end
local inv = lua_inv.player_inventory[name].inv
inv:add_item("main", lua_inv.itemstack("lua_inv:die"))
inv:add_item("main", lua_inv.itemstack("lua_inv:torch"))
inv:add_item("main", lua_inv.itemstack("lua_inv:pick", 66, 75))
inv:add_item("main", lua_inv.itemstack("lua_inv:pick", 75, 33))
end
})
end

View File

@ -17,6 +17,12 @@ License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
--]]
local function can_dig_container(pos, player)
local inv = lua_inv.fetch_node_inventory(pos, true)
return inv and inv:is_empty() and default.can_interact_with_node(player, pos)
end
-----------------------------------------------------
-- Chests --
-----------------------------------------------------
@ -36,6 +42,13 @@ local function chest_override(name)
local override_def = {}
override_def._lua_inv_inventory = function(pos)
local inv = lua_inv.inventory(pos)
inv:set_size("main", 32)
return inv
end
override_def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
minetest.sound_play(def.sound_open, {gain = 0.3, pos = pos,
max_hear_distance = 10}, true)
@ -50,18 +63,7 @@ local function chest_override(name)
sound = def.sound_close, swap = name }
end
override_def.can_dig = function(pos, player)
local inv = lua_inv.fetch_node_inventory(pos, true)
return inv and inv:is_empty("main") and default.can_interact_with_node(player, pos)
end
override_def._lua_inv_inventory = function(pos)
local inv = lua_inv.inventory(pos)
inv:set_size("main", 32)
return inv
end
override_def.can_dig = can_dig_container
minetest.override_item(name, override_def)
minetest.override_item(name.."_open", override_def)
@ -69,3 +71,291 @@ end
chest_override("default:chest")
chest_override("default:chest_locked")
-----------------------------------------------------
-- Furnaces --
-----------------------------------------------------
local function furnace_formspec(pos)
return lua_inv.dynamic_formspec({
lua_inv.formspec_element("size", {{8, 10}}),
lua_inv.dynamic_list({k = "nodemeta", v = {pos.x, pos.y, pos.z}}, "src", 2.75, 0.5, 1, 1),
lua_inv.dynamic_list({k = "nodemeta", v = {pos.x, pos.y, pos.z}}, "fuel", 2.75, 2.5, 1, 1),
lua_inv.dynamic_list({k = "nodemeta", v = {pos.x, pos.y, pos.z}}, "dst", 4.75, 0.96, 2, 2),
lua_inv.active_indicator(2.75, 1.5, 1, 1, "default_furnace_fire_bg.png", "default_furnace_fire_fg.png", "fuel_percent"),
lua_inv.active_indicator(3.75, 1.5, 1, 1, "gui_furnace_arrow_bg.png", "gui_furnace_arrow_fg.png^[transformR270", "item_percent"),
lua_inv.dynamic_list("current_player", "main", 0, 4.85, 8, 1),
lua_inv.dynamic_list("current_player", "main", 0, 6.08, 8, 3, 8),
lua_inv.stack_mode_selector(0, 9.1)
})
end
local function swap_node(pos, name)
local node = minetest.get_node(pos)
if node.name == name then
return
end
node.name = name
minetest.swap_node(pos, node)
end
local function override_furnace(name)
local def = minetest.registered_items[name]
local override_def = {}
override_def._lua_inv_inventory = function(pos)
local inv = lua_inv.inventory(pos,
--Allow Change
function(inv, change)
if not lua_inv.set_list_take_only(inv, change, "dst") then
return false
end
local fuel = lua_inv.change_involves_list(change, "fuel")
if fuel then
if change.key == "name" then
fuel = ItemStack(change.val)
elseif fuel:get_name() ~= "" then
fuel = ItemStack(fuel:get_name())
end
if minetest.get_craft_result({method = "fuel", width = 1, items = {lua_inv.itemstack_to_userdata(fuel)}}).time ~= 0 then
return true
end
if not lua_inv.set_list_take_only(inv, change, "fuel") then
return false
end
end
return true
end,
nil,
--After Change
function(inv, change)
minetest.get_node_timer(inv.parent):start(1)
end
)
inv:set_size("src", 1)
inv:set_size("fuel", 1)
inv:set_size("dst", 4)
return inv
end
---[[
override_def.on_timer = function(pos, elapsed)
local meta = minetest.get_meta(pos)
local fuel_time = meta:get_float("fuel_time")
local src_time = meta:get_float("src_time")
local fuel_totaltime = meta:get_float("fuel_totaltime")
local inv = lua_inv.fetch_node_inventory(pos)
local srclist, fuellist
local dst_full = false
local timer_elapsed = meta:get_int("timer_elapsed")
meta:set_int("timer_elapsed", timer_elapsed + 1)
local cookable, cooked
local fuel
local update = true
while elapsed > 0 and update do
update = false
srclist = {lua_inv.itemstack_to_userdata(inv:get_stack("src", 1))}
fuellist = {lua_inv.itemstack_to_userdata(inv:get_stack("fuel", 1))}
--
-- Cooking
--
-- Check if we have cookable content
local aftercooked
cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
cookable = cooked.time ~= 0
cooked.item = lua_inv.itemstack_from_userdata(cooked.item)
aftercooked.items[1] = lua_inv.itemstack_from_userdata(aftercooked.items[1])
local el = math.min(elapsed, fuel_totaltime - fuel_time)
if cookable then -- fuel lasts long enough, adjust el to cooking duration
el = math.min(el, cooked.time - src_time)
end
-- Check if we have enough fuel to burn
if fuel_time < fuel_totaltime then
-- The furnace is currently active and has enough fuel
fuel_time = fuel_time + el
-- If there is a cookable item then check if it is ready yet
if cookable then
src_time = src_time + el
if src_time >= cooked.time then
-- Place result in dst list if possible
if inv:room_for_item("dst", cooked.item) then
for i = 1, inv:get_size("dst") do
local stack = inv:get_stack("dst", i)
if cooked.item:item_fits(stack) then
rawset(stack, "name", cooked.item:get_name())
rawset(stack, "count", stack:get_count() + cooked.item:get_count())
rawset(stack, "wear", stack:get_wear() + cooked.item:get_wear())
break
end
end
inv:set_stack("src", 1, aftercooked.items[1])
src_time = src_time - cooked.time
update = true
else
dst_full = true
end
-- Play cooling sound
minetest.sound_play("default_cool_lava",
{pos = pos, max_hear_distance = 16, gain = 0.1}, true)
else
-- Item could not be cooked: probably missing fuel
update = true
end
end
else
-- Furnace ran out of fuel
if cookable then
-- We need to get new fuel
local afterfuel
fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
fuel.item = lua_inv.itemstack_from_userdata(fuel.item)
afterfuel.items[1] = lua_inv.itemstack_from_userdata(afterfuel.items[1])
if fuel.time == 0 then
-- No valid fuel in fuel list
fuel_totaltime = 0
src_time = 0
else
-- Take fuel from fuel list
inv:set_stack("fuel", 1, afterfuel.items[1])
-- Put replacements in dst list or drop them on the furnace.
local replacements = fuel.replacements
if replacements[1] then
local leftover = replacements[1]
for i = 1, inv:get_size("dst") do
local stack = inv:get_stack("dst", i)
if replacements[1]:item_fits(stack) then
rawset(stack, "name", cooked.item:get_name())
rawset(stack, "count", stack:get_count() + cooked.item:get_count())
rawset(stack, "count", stack:get_wear() + cooked.item:get_wear())
replacements[1]:set_count(0)
break
end
end
if not leftover:is_empty() then
local above = vector.new(pos.x, pos.y + 1, pos.z)
local drop_pos = minetest.find_node_near(above, 1, {"air"}) or above
minetest.item_drop(replacements[1], nil, drop_pos)
end
end
update = true
fuel_totaltime = fuel.time + (fuel_totaltime - fuel_time)
end
else
-- We don't need to get new fuel since there is no cookable item
fuel_totaltime = 0
src_time = 0
end
fuel_time = 0
end
elapsed = elapsed - el
end
if fuel and fuel_totaltime > fuel.time then
fuel_totaltime = fuel.time
end
if srclist and srclist[1]:is_empty() then
src_time = 0
end
--
-- Update formspec, infotext and node
--
local item_state
local fuel_percent = 0
local item_percent = 0
if cookable then
item_percent = math.floor(src_time / cooked.time * 100)
end
local active = false
local result = false
if fuel_totaltime ~= 0 then
active = true
fuel_percent = 100 - math.floor(fuel_time / fuel_totaltime * 100)
swap_node(pos, name.."_active")
-- make sure timer restarts automatically
result = true
-- Play sound every 5 seconds while the furnace is active
if timer_elapsed == 0 or (timer_elapsed+1) % 5 == 0 then
minetest.sound_play("default_furnace_active",
{pos = pos, max_hear_distance = 16, gain = 0.5}, true)
end
else
item_percent = 0
formspec = default.get_furnace_inactive_formspec()
swap_node(pos, name)
-- stop timer on the inactive furnace
minetest.get_node_timer(pos):stop()
meta:set_int("timer_elapsed", 0)
end
--
-- Set meta values
--
meta:set_float("fuel_totaltime", fuel_totaltime)
meta:set_float("fuel_time", fuel_time)
meta:set_float("src_time", src_time)
meta:set_float("fuel_percent", fuel_percent)
meta:set_float("item_percent", item_percent)
for playername, formspec in pairs(lua_inv.open_formspecs) do
if formspec.meta:get_string("formname") == name then
formspec.meta:set_float("fuel_percent", fuel_percent)
formspec.meta:set_float("item_percent", item_percent)
lua_inv.show_formspec(minetest.get_player_by_name(playername), name, formspec)
end
end
return result
end--]]
override_def.on_construct = function() end
override_def.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local meta = minetest.get_meta(pos)
local formspec = furnace_formspec(pos)
formspec.meta:set_float("fuel_percent", meta:get_float("fuel_percent"))
formspec.meta:set_float("item_percent", meta:get_float("item_percent"))
lua_inv.show_formspec(clicker, name, formspec)
end
override_def.can_dig = can_dig_container
minetest.override_item(name, override_def)
minetest.override_item(name.."_active", override_def)
end
override_furnace("default:furnace")

5
settingtypes.txt Normal file
View File

@ -0,0 +1,5 @@
#Adds an animated torch, a D6 that changes it sprite according to what you roll, and a stackable pickaxe.
lua_inv_test_items (Register various items to test lua_inv features) bool false
#Adds an extra crosshair that won't be invisible to mobile players, and makes the aux1 (E) key act like a right-click, as the "place" control doesn't work
lua_inv_mobile_support (Enable features required for Mobile users) bool true

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B