forked from mtcontrib/claycrafter
4a8a178800
Fixed a bug where the Claycrafter would remain in its active state even if the output inv was full. This didn't waste or create any resources (only light and kept the block animated), it was purely cosmetic. Fixes issue #9, I guess.
307 lines
8.8 KiB
Lua
307 lines
8.8 KiB
Lua
--
|
|
-- Formspecs
|
|
--
|
|
|
|
local function active_formspec(fuel_percent, item_percent)
|
|
local formspec =
|
|
"size[8,8.5]"..
|
|
default.gui_bg..
|
|
default.gui_bg_img..
|
|
default.gui_slots..
|
|
"list[current_name;src;2.75,0.5;1,1;]"..
|
|
"list[current_name;fuel;2.75,2.5;1,1;]"..
|
|
"image[2.75,1.5;1,1;claycrafter_claycrafter_water_bg.png^[lowpart:"..
|
|
(100-fuel_percent)..":claycrafter_claycrafter_water_fg.png]"..
|
|
"image[3.75,1.5;1,1;gui_claycrafter_arrow_bg.png^[lowpart:"..
|
|
(item_percent)..":gui_claycrafter_arrow_fg.png^[transformR270]"..
|
|
"list[current_name;dst;4.75,0.96;3,2;]"..
|
|
"list[current_name;vessels;0,1.5;2,2;]"..
|
|
"list[current_player;main;0,4.25;8,1;]"..
|
|
"list[current_player;main;0,5.5;8,3;8]"..
|
|
"listring[current_name;dst]"..
|
|
"listring[current_player;main]"..
|
|
"listring[current_name;src]"..
|
|
"listring[current_player;main]"..
|
|
"listring[current_name;vessels]"..
|
|
"listring[current_player;main]"..
|
|
default.get_hotbar_bg(0, 4.25)
|
|
return formspec
|
|
end
|
|
|
|
local inactive_formspec =
|
|
"size[8,8.5]"..
|
|
default.gui_bg..
|
|
default.gui_bg_img..
|
|
default.gui_slots..
|
|
"list[current_name;src;2.75,0.5;1,1;]"..
|
|
"list[current_name;fuel;2.75,2.5;1,1;]"..
|
|
"image[2.75,1.5;1,1;claycrafter_claycrafter_water_bg.png]"..
|
|
"image[3.75,1.5;1,1;gui_claycrafter_arrow_bg.png^[transformR270]"..
|
|
"list[current_name;dst;4.75,0.96;3,2;]"..
|
|
"list[current_name;vessels;0,1.5;2,2;]"..
|
|
"list[current_player;main;0,4.25;8,1;]"..
|
|
"list[current_player;main;0,5.5;8,3;8]"..
|
|
"listring[current_name;dst]"..
|
|
"listring[current_player;main]"..
|
|
"listring[current_name;src]"..
|
|
"listring[current_player;main]"..
|
|
"listring[current_name;vessels]"..
|
|
"listring[current_player;main]"..
|
|
default.get_hotbar_bg(0, 4.25)
|
|
|
|
--
|
|
-- Node callback functions that are the same for active and inactive claycrafter
|
|
--
|
|
|
|
local function can_dig(pos, player)
|
|
local meta = minetest.get_meta(pos);
|
|
local inv = meta:get_inventory()
|
|
return inv:is_empty("fuel") and inv:is_empty("dst") and inv:is_empty("src") and inv:is_empty("vessels")
|
|
end
|
|
|
|
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
|
if minetest.is_protected(pos, player:get_player_name()) then
|
|
return 0
|
|
end
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
if listname == "fuel" then -- "Water"
|
|
if minetest.get_item_group(stack:get_name(), "h2o") > 0 then
|
|
if inv:is_empty("src") then
|
|
meta:set_string("infotext", "Claycrafter is empty")
|
|
end
|
|
return stack:get_count()
|
|
else
|
|
return 0
|
|
end
|
|
elseif listname == "src" then
|
|
return stack:get_count()
|
|
elseif listname == "dst" then
|
|
return 0
|
|
elseif listname == "vessels" then
|
|
return 0
|
|
end
|
|
end
|
|
|
|
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
|
local meta = minetest.get_meta(pos)
|
|
local inv = meta:get_inventory()
|
|
local stack = inv:get_stack(from_list, from_index)
|
|
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
|
|
end
|
|
|
|
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
|
if minetest.is_protected(pos, player:get_player_name()) then
|
|
return 0
|
|
end
|
|
return stack:get_count()
|
|
end
|
|
|
|
--
|
|
-- Node definitions
|
|
--
|
|
|
|
minetest.register_node("claycrafter:claycrafter", {
|
|
description = "Claycrafter",
|
|
tiles = {
|
|
"claycrafter_claycrafter_top.png", "claycrafter_claycrafter_bottom.png",
|
|
"claycrafter_claycrafter_side.png", "claycrafter_claycrafter_side.png",
|
|
"claycrafter_claycrafter_back.png", "claycrafter_claycrafter_front.png"
|
|
},
|
|
paramtype2 = "facedir",
|
|
groups = {choppy = 1, oddly_breakable_by_hand = 1},
|
|
legacy_facedir_simple = true,
|
|
is_ground_content = false,
|
|
sounds = default.node_sound_stone_defaults(),
|
|
|
|
can_dig = can_dig,
|
|
|
|
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
|
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
|
allow_metadata_inventory_take = allow_metadata_inventory_take
|
|
})
|
|
|
|
minetest.register_node("claycrafter:claycrafter_active", {
|
|
description = "Claycrafter",
|
|
tiles = {
|
|
"claycrafter_claycrafter_top.png", "claycrafter_claycrafter_bottom.png",
|
|
"claycrafter_claycrafter_side.png", "claycrafter_claycrafter_side.png",
|
|
"claycrafter_claycrafter_side.png",
|
|
{
|
|
image = "claycrafter_claycrafter_front_active.png",
|
|
backface_culling = false,
|
|
animation = {
|
|
type = "vertical_frames",
|
|
aspect_w = 16,
|
|
aspect_h = 16,
|
|
length = 1.5
|
|
}
|
|
}
|
|
},
|
|
paramtype2 = "facedir",
|
|
light_source = 8,
|
|
drop = "claycrafter:claycrafter",
|
|
groups = {choppy = 1, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1},
|
|
legacy_facedir_simple = true,
|
|
is_ground_content = false,
|
|
sounds = default.node_sound_stone_defaults(),
|
|
|
|
can_dig = can_dig,
|
|
|
|
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
|
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
|
allow_metadata_inventory_take = allow_metadata_inventory_take
|
|
})
|
|
|
|
--
|
|
-- ABM
|
|
--
|
|
|
|
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
|
|
|
|
minetest.register_abm({
|
|
nodenames = {"claycrafter:claycrafter", "claycrafter:claycrafter_active"},
|
|
interval = 1.0,
|
|
chance = 1,
|
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
|
--
|
|
-- Inizialize metadata
|
|
--
|
|
local meta = minetest.get_meta(pos)
|
|
local fuel_time = meta:get_float("fuel_time") or 0
|
|
local src_time = meta:get_float("src_time") or 0
|
|
local fuel_totaltime = meta:get_float("fuel_totaltime") or 0
|
|
|
|
--
|
|
-- Inizialize inventory
|
|
--
|
|
local inv = meta:get_inventory()
|
|
for listname, size in pairs({
|
|
src = 1,
|
|
fuel = 1,
|
|
dst = 6,
|
|
vessels = 4
|
|
}) do
|
|
if inv:get_size(listname) ~= size then
|
|
inv:set_size(listname, size)
|
|
end
|
|
end
|
|
local srclist = inv:get_list("src")
|
|
local fuellist = inv:get_list("fuel")
|
|
local dstlist = inv:get_list("dst")
|
|
|
|
--
|
|
-- Cooking
|
|
--
|
|
|
|
local cooktime = minetest.get_item_group(inv:get_stack("fuel", 1):get_name(), "h2o")
|
|
local cookable = true
|
|
if inv:get_stack("src", 1):get_name() ~= "claycrafter:compressed_dirt" then
|
|
cookable = false
|
|
end
|
|
|
|
-- Check if we have enough fuel to burn
|
|
if fuel_time < fuel_totaltime then
|
|
-- The claycrafter is currently active and has enough fuel
|
|
fuel_time = fuel_time + 1
|
|
|
|
-- If there is a cookable item then check if it is ready yet
|
|
if cookable then
|
|
src_time = src_time + 1
|
|
if src_time >= cooktime then
|
|
-- Place result in dst list if possible
|
|
if inv:room_for_item("dst", ItemStack({name = "default:clay", count = 4}))
|
|
and inv:room_for_item("vessels", ItemStack({name = "vessels:drinking_glass"}))
|
|
then
|
|
inv:add_item("dst", {name = "default:clay", count = 4})
|
|
inv:remove_item("src", inv:get_stack("src", 1):get_name())
|
|
src_time = 0
|
|
else
|
|
swap_node(pos, "claycrafter:claycrafter")
|
|
end
|
|
end
|
|
end
|
|
else
|
|
-- Furnace ran out of fuel
|
|
if cookable and inv:room_for_item("dst", ItemStack({name = "default:clay", count = 4})) then
|
|
-- We need to get new fuel
|
|
local fueltime = minetest.get_item_group(inv:get_stack("fuel", 1):get_name(), "h2o")
|
|
|
|
if fueltime == 0 then
|
|
-- No valid fuel in fuel list
|
|
fuel_totaltime = 0
|
|
fuel_time = 0
|
|
src_time = 0
|
|
else
|
|
-- Take fuel from fuel list
|
|
if inv:room_for_item("vessels", ItemStack({name = "vessels:drinking_glass"}))
|
|
then
|
|
inv:remove_item("fuel", inv:get_stack("fuel", 1):get_name())
|
|
inv:add_item("vessels", {name = "vessels:drinking_glass"})
|
|
else
|
|
swap_node(pos, "claycrafter:claycrafter_active")
|
|
end
|
|
fuel_totaltime = fueltime
|
|
fuel_time = 0
|
|
|
|
end
|
|
else
|
|
-- We don't need to get new fuel since there is no cookable item
|
|
fuel_totaltime = 0
|
|
fuel_time = 0
|
|
src_time = 0
|
|
end
|
|
end
|
|
|
|
--
|
|
-- Update formspec, infotext and node
|
|
--
|
|
local formspec = inactive_formspec
|
|
local item_state = ""
|
|
local item_percent = 0
|
|
if cookable then
|
|
item_percent = math.floor(src_time / cooktime * 100)
|
|
item_state = "Yes"
|
|
else
|
|
if srclist[1]:is_empty() then
|
|
item_state = "Empty"
|
|
else
|
|
item_state = "No water"
|
|
end
|
|
end
|
|
|
|
local fuel_state = "Empty"
|
|
local active = "inactive "
|
|
if fuel_time <= fuel_totaltime and fuel_totaltime ~= 0 then
|
|
active = "active "
|
|
local fuel_percent = math.floor(fuel_time / fuel_totaltime * 100)
|
|
fuel_state = "In use"
|
|
formspec = active_formspec(fuel_percent, item_percent)
|
|
swap_node(pos, "claycrafter:claycrafter_active")
|
|
else
|
|
if not fuellist[1]:is_empty() then
|
|
fuel_state = "Yes"
|
|
end
|
|
swap_node(pos, "claycrafter:claycrafter")
|
|
end
|
|
|
|
local infotext = "Claycrafter " .. active .. "(Dirt: " .. item_state .. "; Water: " .. fuel_state .. ")"
|
|
|
|
--
|
|
-- 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_string("formspec", formspec)
|
|
meta:set_string("infotext", infotext)
|
|
end
|
|
})
|