-- -- Formspecs -- function forestry_bees.get_apiary_active_formspec(queen_percent) return "size[8,8.5]".. "list[context;monarch;2.75,0.5;1,1;]".. "list[context;drone;2.75,2.5;1,1;]".. "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:".. (queen_percent)..":gui_furnace_arrow_fg.png^[transformR270]".. "list[context;dst;4.75,0.96;3,3;]".. "list[current_player;main;0,4.25;8,1;]".. "list[current_player;main;0,5.5;8,3;8]".. "listring[context;dst]".. "listring[current_player;main]".. "listring[context;src]".. "listring[current_player;main]".. "listring[context;fuel]".. "listring[current_player;main]".. default.get_hotbar_bg(0, 4.25) end function forestry_bees.get_apiary_inactive_formspec() return "size[8,8.5]".. "list[context;monarch;2.75,0.5;1,1;]".. "list[context;drone;2.75,2.5;1,1;]".. "image[3.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]".. "list[context;dst;4.75,0.96;3,3;]".. "list[current_player;main;0,4.25;8,1;]".. "list[current_player;main;0,5.5;8,3;8]".. "listring[context;dst]".. "listring[current_player;main]".. "listring[context;src]".. "listring[current_player;main]".. "listring[context;fuel]".. "listring[current_player;main]".. default.get_hotbar_bg(0, 4.25) end -- -- Node callback functions that are the same for active and inactive furnace -- local function can_dig(pos, player) local meta = minetest.get_meta(pos); local inv = meta:get_inventory() return inv:is_empty("monarch") and inv:is_empty("drone") and inv:is_empty("dst") 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 == "drone" then if minetest.get_item_group(stack:get_name(),"bee_drone") == 1 then return stack:get_count() else return 0 end elseif listname == "monarch" then if minetest.get_item_group(stack:get_name(),"bee_monarch") == 1 then return stack:get_count() else return 0 end elseif listname == "dst" 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 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 apiary_node_timer(pos,elapsed) local meta = minetest.get_meta(pos) local src_time = meta:get_float("src_time") or 0 --how much time has passed since src started actioning local inv = meta:get_inventory() local monarchlist, dronelist local timer_elapsed = meta:get_int("timer_elapsed") or 0 meta:set_int("timer_elapsed", timer_elapsed + 1) local update = true local is_queen, is_princess, is_drone local can_breed, can_live local actionable local changed_queen = false local breedtime = 1 local needed_time = 1 --just so that the formspecs doesnt make an error local queentime = 0 while elapsed > 0 and update do update = false monarchlist = inv:get_list("monarch") dronelist = inv:get_list("drone") is_queen = minetest.get_item_group(monarchlist[1]:get_name(),"bee_queen") == 1 is_princess = minetest.get_item_group(monarchlist[1]:get_name(),"bee_princess") == 1 is_drone = minetest.get_item_group(dronelist[1]:get_name(),"bee_drone") == 1 if is_queen then if monarchlist[1]:get_meta():get_string("genes") == "" then --fix for creative queens minetest.chat_send_all("prova") local new_queen = forestry_bees.format_bee(monarchlist[1]) local drone_genes = forestry_bees.return_all_genes_double(string.sub(string.match(string.match(new_queen:get_name(),":.*"),".*_"),2,-2)) new_queen:get_meta():set_string("drone_genes", forestry_bees.serialize(drone_genes)) inv:set_stack("monarch",1,new_queen) monarchlist = inv:get_list("monarch") end queentime = monarchlist[1]:get_meta():get_float("queentime") or 0 src_time = queentime end can_breed = is_princess and is_drone can_live = is_queen and forestry_bees.can_queen_work(monarchlist[1], pos) --these two event are disjoint (there are no queen & princess) actionable = can_breed or can_live local el = elapsed --if actionable check if things are ready if actionable then --ternary expression if can_breed it evals to breedtime else lifetime needed_time = (can_breed and {breedtime} or { tonumber(forestry_bees.settings:get("lifespan_multiplier")) * forestry_bees.deserialize(monarchlist[1]:get_meta():get_string("genes"))["lifespan"][1]})[1] el = math.min(el, needed_time - src_time) src_time = src_time + el if can_live then --chance to drop honeycomb local drops = forestry_bees.calculate_drop(monarchlist[1]) if (not (next(drops) == nil)) and inv:get_size("dst") - forestry_bees.stacks_in_inv(inv,"dst") >= #drops then for _,drop in pairs(drops) do inv:add_item("dst",drop) end end end if src_time >= needed_time then --if possible act accordingly to breed or live if can_breed then local queen = forestry_bees.breed_princess_drone(monarchlist[1],dronelist[1]) local drone_count = dronelist[1]:get_count() local final_drone if drone_count == 1 then final_drone = ItemStack() else dronelist[1]:set_count(drone_count - 1) final_drone = dronelist[1] end inv:set_stack("monarch",1,queen) inv:set_stack("drone",1,final_drone) src_time = src_time - needed_time else --if actionable but not can_breed we have can_live local queen = monarchlist[1] local princess, dronelistout = forestry_bees.apiary_result(queen, pos) if inv:get_size("dst")-forestry_bees.stacks_in_inv(inv,"dst") >= 1 + #dronelistout then inv:add_item("dst",princess) for _,drone in pairs(dronelistout) do inv:add_item("dst",drone) end inv:set_stack("monarch",1,ItemStack()) src_time = src_time - needed_time update = true changed_queen = true else dst_full = true end end end end elapsed = elapsed - el end if monarchlist and monarchlist[1]:is_empty() then src_time = 0 end -- -- Update formspec, infotext and node -- local formspec local item_state local percent = 0 --by default timer doesnt restart local result = false if actionable then percent = math.floor(src_time / needed_time * 100) if dst_full then item_state = "100% (output full)" else item_state = tostring(percent).."%" end --make sure timer restarts result = true else if (monarchlist and not monarchlist[1]:is_empty()) or (dronelist and not dronelist[1]:is_empty()) then item_state = "Cannot breed" else item_state = "Empty" end end formspec = forestry_bees.get_apiary_active_formspec(percent) if is_queen and (not changed_queen) then monarchlist[1]:get_meta():set_float("queentime", src_time) inv:set_stack("monarch",1,monarchlist[1]) end meta:set_float("src_time", src_time) meta:set_string("formspec", formspec) minetest.chat_send_all(tostring(math.random())) return result end -- -- Node definitions -- local function apply_logger(def) default.set_inventory_action_loggers(def, "apiary") return def end minetest.register_node("forestry_bees:apiary", apply_logger({ description = "Apiary", tiles = { "forestry_bees_apiary_y.png", "forestry_bees_apiary_y.png", "forestry_bees_apiary_front.png", "forestry_bees_apiary_front.png", "forestry_bees_apiary_side.png", "forestry_bees_apiary_side.png" }, paramtype2 = "facedir", groups = {choppy=2, oddly_breakable_by_hand=2, tubedevice = 1, tubedevice_receiver = 1}, legacy_facedir_simple = true, is_ground_content = false, sounds = default.node_sound_wood_defaults(), can_dig = can_dig, on_timer = apiary_node_timer, on_construct = function(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() inv:set_size('monarch', 1) inv:set_size('drone', 1) inv:set_size('dst', 9) apiary_node_timer(pos, 0) end, on_metadata_inventory_move = function(pos) minetest.get_node_timer(pos):start(1.0) end, on_metadata_inventory_put = function(pos) -- start timer function, it will sort out whether apiary can work or not. minetest.get_node_timer(pos):start(1.0) end, on_metadata_inventory_take = function(pos) -- check whether the apiary is empty or not. minetest.get_node_timer(pos):start(1.0) end, on_blast = function(pos) local drops = {} default.get_inventory_drops(pos, "monarch", drops) default.get_inventory_drops(pos, "drone", drops) default.get_inventory_drops(pos, "dst", drops) drops[#drops+1] = "forestry_bees:apiary" minetest.remove_node(pos) return drops end, tube = { insert_object = function(pos, node, stack, direction) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() minetest.get_node_timer(pos):start(1.0) if minetest.get_item_group(stack:get_name(),"bee_drone") == 1 then return inv:add_item('drone', stack) end if minetest.get_item_group(stack:get_name(),"bee_monarch") == 1 then return inv:add_item('monarch', stack) end end, can_insert = function(pos, node, stack, direction) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() if minetest.get_item_group(stack:get_name(),"bee_drone") == 1 then return inv:room_for_item('drone', stack) end if minetest.get_item_group(stack:get_name(),"bee_monarch") == 1 then return inv:room_for_item('monarch', stack) end end, input_inventory = 'dst', connect_sides = {left = 1, right = 1, front = 1, back = 1, bottom = 1, top = 1} }, 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_craft({ output = "forestry_bees:apiary", recipe = { {"group:choppy,slab", "group:choppy,slab", "group:choppy,slab"}, {"group:wood", "group:comb", "group:wood"}, {"group:wood", "group:wood", "group:wood"}, } }) if forestry_bees.depends.hopper then hopper:add_container({ {"top", "forestry_bees:apiary", "dst"}, {"bottom", "forestry_bees:apiary", "monarch"}, {"side", "forestry_bees:apiary", "drone"}, }) end