-- -- 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 breed_princess_drone(princess,drone) local princess_meta = princess:get_meta() local drone_meta = drone:get_meta() local queen = forestry_bees.Bee("queen", princess_meta:get_string("active_gene"), princess_meta:get_string("inactive_gene")) local queen_meta = queen:get_meta() queen_meta:set_string("drone_active_gene",drone_meta:get_string("active_gene")) queen_meta:set_string("drone_inactive_gene",drone_meta:get_string("inactive_gene")) return queen end local function apiary_result(queen) --given a queen calculates the correct princess + drone output --atm easy just returns the same princess and the same drone local meta = queen:get_meta() --the "meta" of the queen is the princess meta and the drone_"meta" is the drone meta local princess = forestry_bees.Bee("princess",meta:get_string("active_gene"),meta:get_string("inactive_gene")) local drone = forestry_bees.Bee("drone",meta:get_string("drone_active_gene"),meta:get_string("drone_inactive_gene")) drone:set_count(2) return princess, drone 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 breedtime = 5 --hardcoded for now 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 can_breed = is_princess and is_drone can_live = is_queen actionable = can_breed or can_live local el = elapsed if actionable then -- adjust el to action duration el = math.min(el, breedtime - src_time) end --if actionable check if things are ready if actionable then src_time = src_time + el if src_time >= breedtime then --if possible act accordingly to breed or live if can_breed then local queen = breed_princess_drone(monarchlist[1],dronelist[1]) local drone_count = dronelist[1]:get_count() if drone_count >1 then local final_drone = dronelist[1]:set_count(dronelist[1]:get_count()-1) else final_drone = ItemStack() end inv:set_stack("monarch",1,queen) inv:set_stack("drone",1,final_drone) src_time = src_time - breedtime else --if actionable but not can_breed we have can_live local queen = monarchlist[1] local princess, drone = apiary_result(queen) if inv:get_size("dst")-forestry_bees.stacks_in_inv(inv,"dst")>=2 then inv:add_item("dst",princess) inv:add_item("dst",drone) inv:set_stack("monarch",1,ItemStack()) src_time = src_time - breedtime update = true else minetest.chat_send_all("dst_full") 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 queen_percent = 0 if actionable then queen_percent = math.floor(src_time / breedtime * 100) if dst_full then item_state = "100% (output full)" else item_state = tostring(item_percent).."%" end 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 local result = false formspec = forestry_bees.get_apiary_active_formspec(queen_percent) --make sure timer restarts result = true meta:set_float("src_time", src_time) meta:set_string("formspec", formspec) 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}, 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, 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"}, } })