From 95c1c2d5b7300c4c706689f60e44c993bc959ae1 Mon Sep 17 00:00:00 2001
From: StochasticMouse <alessiorondelli0@gmail.com>
Date: Mon, 7 Oct 2024 14:31:20 +0200
Subject: [PATCH] apiary finally works

---
 forestry_bees/apiary.lua                      | 333 ++++--------------
 forestry_bees/helper.lua                      |  21 ++
 forestry_bees/init.lua                        | 122 +------
 forestry_bees/register.lua                    | 112 ++++++
 .../nodes/forestry_bees_apiary_front.png      | Bin 0 -> 289 bytes
 .../nodes/forestry_bees_apiary_side.png       | Bin 0 -> 277 bytes
 .../textures/nodes/forestry_bees_apiary_y.png | Bin 0 -> 189 bytes
 7 files changed, 210 insertions(+), 378 deletions(-)
 create mode 100644 forestry_bees/helper.lua
 create mode 100644 forestry_bees/register.lua
 create mode 100644 forestry_bees/textures/nodes/forestry_bees_apiary_front.png
 create mode 100644 forestry_bees/textures/nodes/forestry_bees_apiary_side.png
 create mode 100644 forestry_bees/textures/nodes/forestry_bees_apiary_y.png

diff --git a/forestry_bees/apiary.lua b/forestry_bees/apiary.lua
index 9b1d91f..01ec7e8 100644
--- a/forestry_bees/apiary.lua
+++ b/forestry_bees/apiary.lua
@@ -93,9 +93,16 @@ local function swap_node(pos, name)
 	minetest.swap_node(pos, node)
 end
 
-local function bee_change_type(bee_name,final_type)
-	--given a bee_name it gives the same bee_name but with a different type, for example queen -> princess
-	return string.gsub(bee_name,"_.-","_"..final_type)
+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)
@@ -103,8 +110,8 @@ local function apiary_result(queen)
 	--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 = Bee(bee_change_type(queen:get_name(),"princess"),meta:get_string("active_gene"),meta:get_string("inactive_gene"))
-	local drone = Bee(bee_change_type(queen:get_name(),"drone"),meta:get_string("drone_active_gene"),meta:get_string("drone_inactive_gene"))
+	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
@@ -146,229 +153,69 @@ local function apiary_node_timer(pos,elapsed)
 			if src_time >= breedtime then
 				--if possible act accordingly to breed or live
 				if can_breed then
-					local queen = Bee(bee_change_type())
-					inv:set_stack("monarch",1,)
+          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
-		
-    end
-end
-
-local function furnace_node_timer(pos, elapsed)
-	--
-	-- Initialize 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
-
-	local inv = meta:get_inventory()
-	local monarchlist, dronelist
-	local dst_full = false
-
-	local timer_elapsed = meta:get_int("timer_elapsed") or 0
-	meta:set_int("timer_elapsed", timer_elapsed + 1)
-
-	--local cookable, cooked
-  local breedable
-	--local fuel
-
-	local update = true
-	--local items_smelt = 0
-	while elapsed > 0 and update do
-		update = false
-
-		monarchlist = inv:get_list("monarch")
-		dronelist = inv:get_list("drone")
-
-		--
-		-- Cooking
-		--
-
-		-- Check if we have breedable content
-		--local aftercooked
-		--cooked, aftercooked = minetest.get_craft_result({method = "cooking", width = 1, items = srclist})
-		breedable = (minetest.get_item_group(monarchlist[1]:get_name(),"bee_monarch") == 1) and (minetest.get_item_group(dronelist[1]:get_name(),"bee_drone") == 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
-						inv:add_item("dst", cooked.item)
-						inv:set_stack("src", 1, aftercooked.items[1])
-						src_time = src_time - cooked.time
-						update = true
-					else
-						dst_full = true
-					end
-					items_smelt = items_smelt + 1
-				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})
-
-				if fuel.time == 0 then
-					-- No valid fuel in fuel list
-					fuel_totaltime = 0
-					src_time = 0
-				else
-					-- prevent blocking of fuel inventory (for automatization mods)
-					local is_fuel = minetest.get_craft_result({method = "fuel", width = 1, items = {afterfuel.items[1]:to_string()}})
-					if is_fuel.time == 0 then
-						table.insert(fuel.replacements, afterfuel.items[1])
-						inv:set_stack("fuel", 1, "")
-					else
-						-- Take fuel from fuel list
-						inv:set_stack("fuel", 1, afterfuel.items[1])
-					end
-					-- Put replacements in dst list or drop them on the furnace.
-					local replacements = fuel.replacements
-					if replacements[1] then
-						local leftover = inv:add_item("dst", replacements[1])
-						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
+    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
 
-	if items_smelt > 0 then
-		-- Play cooling sound
-		minetest.sound_play("default_cool_lava",
-			{ pos = pos, max_hear_distance = 16, gain = 0.07 * math.min(items_smelt, 7) }, true)
-	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 formspec
-	local item_state
-	local item_percent = 0
-	if cookable then
-		item_percent = math.floor(src_time / cooked.time * 100)
-		if dst_full then
-			item_state = S("100% (output full)")
-		else
-			item_state = S("@1%", item_percent)
-		end
-	else
-		if srclist and not srclist[1]:is_empty() then
-			item_state = S("Not cookable")
-		else
-			item_state = S("Empty")
-		end
-	end
-
-	local fuel_state = S("Empty")
-	local active = false
-	local result = false
-
-	if fuel_totaltime ~= 0 then
-		active = true
-		local fuel_percent = 100 - math.floor(fuel_time / fuel_totaltime * 100)
-		fuel_state = S("@1%", fuel_percent)
-		formspec = default.get_furnace_active_formspec(fuel_percent, item_percent)
-		swap_node(pos, "default:furnace_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
-			local sound_id = minetest.sound_play("default_furnace_active",
-				{pos = pos, max_hear_distance = 16, gain = 0.25})
-			local hash = minetest.hash_node_position(pos)
-			furnace_fire_sounds[hash] = furnace_fire_sounds[hash] or {}
-			table.insert(furnace_fire_sounds[hash], sound_id)
-			-- Only remember the 3 last sound handles
-			if #furnace_fire_sounds[hash] > 3 then
-				table.remove(furnace_fire_sounds[hash], 1)
-			end
-			-- Remove the sound ID automatically from table after 11 seconds
-			minetest.after(11, function()
-				if not furnace_fire_sounds[hash] then
-					return
-				end
-				for f=#furnace_fire_sounds[hash], 1, -1 do
-					if furnace_fire_sounds[hash][f] == sound_id then
-						table.remove(furnace_fire_sounds[hash], f)
-					end
-				end
-				if #furnace_fire_sounds[hash] == 0 then
-					furnace_fire_sounds[hash] = nil
-				end
-			end)
-		end
-	else
-		if fuellist and not fuellist[1]:is_empty() then
-			fuel_state = S("@1%", 0)
-		end
-		formspec = default.get_furnace_inactive_formspec()
-		swap_node(pos, "default:furnace")
-		-- stop timer on the inactive furnace
-		minetest.get_node_timer(pos):stop()
-		meta:set_int("timer_elapsed", 0)
-
-		stop_furnace_sound(pos)
-	end
-
-
-	local infotext
-	if active then
-		infotext = S("Furnace active")
-	else
-		infotext = S("Furnace inactive")
-	end
-	infotext = infotext .. "\n" .. S("(Item: @1; Fuel: @2)", item_state, 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)
 
 	return result
+
 end
 
 --
@@ -381,10 +228,10 @@ local function apply_logger(def)
 end
 
 minetest.register_node("forestry_bees:apiary", apply_logger({
-	description = S("Apiary"),
+	description = "Apiary",
 	tiles = {
-		"forestry_bees_apiary_top.png", "forestry_bees_apiary_bottom.png",
-		"forestry_bees_apiary_side.png", "forestry_bees_apiary_side.png",
+		"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",
@@ -432,47 +279,11 @@ minetest.register_node("forestry_bees:apiary", apply_logger({
 	allow_metadata_inventory_take = allow_metadata_inventory_take,
 }))
 
---minetest.register_node("default:furnace_active", apply_logger({
-	--description = S("Furnace"),
-	--tiles = {
-		--"default_furnace_top.png", "default_furnace_bottom.png",
-		--"default_furnace_side.png", "default_furnace_side.png",
-		--"default_furnace_side.png",
-		--{
-			--image = "default_furnace_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 = "default:furnace",
-	--groups = {cracky=2, not_in_creative_inventory=1},
-	--legacy_facedir_simple = true,
-	--is_ground_content = false,
-	--sounds = default.node_sound_stone_defaults(),
-	--on_timer = furnace_node_timer,
-	--on_destruct = function(pos)
-		--stop_furnace_sound(pos)
-	--end,
-
-	--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_craft({
 	output = "forestry_bees:apiary",
 	recipe = {
-		{"default:slab_wood", "default:slab_wood", "default:slab_wood"},
-		{"default:wood", "", "default:wood"},
-		{"default:wood", "default:wood", "default:wood"},
+		{"group:choppy,slab", "group:choppy,slab", "group:choppy,slab"},
+		{"group:wood", "group:comb", "group:wood"},
+		{"group:wood", "group:wood", "group:wood"},
 	}
 })
diff --git a/forestry_bees/helper.lua b/forestry_bees/helper.lua
new file mode 100644
index 0000000..498a4fb
--- /dev/null
+++ b/forestry_bees/helper.lua
@@ -0,0 +1,21 @@
+function forestry_bees.Bee(bee_type,active_gene,inactive_gene)
+    local itemstack = ItemStack({name = forestry_bees.bee_name(bee_type,active_gene)})
+    itemstack:get_meta():set_string("active_gene",active_gene)
+    itemstack:get_meta():set_string("inactive_gene",inactive_gene)
+    return itemstack
+end
+
+function forestry_bees.bee_name(bee_type,active_gene)
+    return "forestry_bees:"..active_gene.."_"..bee_type
+end
+
+function forestry_bees.stacks_in_inv(inv,listname)
+  local stack_list = inv:get_list(listname)
+  local result = 0
+  for i = 1,#stack_list do
+    if not stack_list[i]:is_empty() then
+      result = result + 1
+    end
+  end
+  return result
+end
\ No newline at end of file
diff --git a/forestry_bees/init.lua b/forestry_bees/init.lua
index 29b72ca..e89b7b1 100644
--- a/forestry_bees/init.lua
+++ b/forestry_bees/init.lua
@@ -1,118 +1,6 @@
-local function Bee(beename,active_gene,inactive_gene)
-    local itemstack = ItemStack({name = beename})
-    itemstack:get_meta():set_string("active_gene",active_gene)
-    itemstack:get_meta():set_string("inactive_gene",inactive_gene)
-    return itemstack
-end
+--definitions that can be used around
+forestry_bees = {}
 
-local function makebeetexture(body1,body2,outline,color,ratio)
-    return body1.."^("..body1.."^[makealpha:0,0,0^[colorize:"..color..":"..ratio..")^"..body2.."^("..outline.."^[colorize:"..color..":"..ratio..")"
-end
-
-local function printbeestats(itemstack, user, pointed_thing) 
-    local meta = itemstack:get_meta()
-    local name = itemstack:get_name()
-    minetest.chat_send_player(user:get_player_name(), "Name:"..string.sub(string.match(name, ":.*"),2)..", Active:"..meta:get_string("active_gene")..", Inactive:"..meta:get_string("inactive_gene")) 
-end
-
-local function capitalize(s)
-    return s:sub(1,1):upper()..s:sub(2)
-end
-
-local function register_bee(name, color, color_ratio)
-  minetest.register_craftitem("forestry_bees:"..name.."_princess", {
-    description = capitalize(name).." Princess",
-    inventory_image = makebeetexture("body1.png",
-                                      "princess.body2.png",
-                                      "princess.outline.png",color,color_ratio),
-    on_use = printbeestats,
-    groups = {bee_princess=1, bee_monarch=1},
-  })
-  minetest.register_craftitem("forestry_bees:"..name.."_drone", {
-    description = capitalize(name).." Drone",
-    inventory_image = makebeetexture("body1.png",
-                                      "drone.body2.png",
-                                      "drone.outline.png",color,color_ratio),
-    on_use = printbeestats,
-    groups = {bee_drone=1},
-  })
-  minetest.register_craftitem("forestry_bees:"..name.."_queen", {
-    description = capitalize(name).." Queen",
-    inventory_image = makebeetexture("body1.png",
-                                      "queen.body2.png",
-                                      "queen.outline.png",color,color_ratio),
-    on_use = printbeestats,
-    groups = {bee_queen=1, bee_monarch=1},
-  })
-end
-
---Here we register nodes
-minetest.register_node("forestry_bees:forest_beehive", {
-  description = "Forest Beehive",
-  tiles = {
-          "forestry_bees_forest_beehive_top.png",
-          "forestry_bees_forest_beehive_top.png",
-          "forestry_bees_forest_beehive_side.png",
-          "forestry_bees_forest_beehive_side.png",
-          "forestry_bees_forest_beehive_side.png",
-          "forestry_bees_forest_beehive_side.png",
-  },
-  groups = {scoopy = 1},
-  diggable = true,
-  drop = {
-      max_items = 3,
-      items = {
-          {tool_groups = {"scoop_tool"}, rarity = 2, items = {Bee("forestry_bees:forest_princess","forest","forest")}},
-          {tool_groups = {"scoop_tool"}, rarity = 2, items = {Bee("forestry_bees:forest_drone","forest","forest")}},
-          {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}}
-      }
-  }
-})
-
-minetest.register_node("forestry_bees:meadow_beehive", {
-  description = "Meadow Beehive",
-  tiles = {
-          "forestry_bees_meadow_beehive_top.png",
-          "forestry_bees_meadow_beehive_top.png",
-          "forestry_bees_meadow_beehive_side.png",
-          "forestry_bees_meadow_beehive_side.png",
-          "forestry_bees_meadow_beehive_side.png",
-          "forestry_bees_meadow_beehive_side.png",
-  },
-  groups = {scoopy = 1},
-  diggable = true,
-  drop = {
-      max_items = 3,
-      items = {
-          {tool_groups = {"scoop_tool"}, rarity = 2, items = {Bee("forestry_bees:meadow_princess","meadow","meadow")}},
-          {tool_groups = {"scoop_tool"}, rarity = 2, items = {Bee("forestry_bees:meadow_drone","meadow","meadow")}},
-          {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}}
-      }
-  }
-})
-
-minetest.register_tool("forestry_bees:scoop", {
-    description = "Scoop",
-    inventory_image = "forestry_bees_scoop.png",
-    groups = {scoop_tool = 1},
-    tool_capabilities = {
-        full_punch_interval = 1.5,
-        max_drop_level = 1,
-        groupcaps = {
-            scoopy = {
-                maxlevel = 1,
-                uses = 10,
-                times = { [1]=1, [2]=1, [3]=1 }
-            },
-        },
-    },
-})
-
-register_bee("forest","#19d0ec","255")
-register_bee("meadow","#ef131e","255")
-register_bee("common","#b2b2b2","255")
-
-minetest.register_craftitem("forestry_bees:honey_comb", {
-    description = "Honey Comb",
-    inventory_image = "(bee_combs.0.png^[colorize:Yellow:100)^(bee_combs.1.png^[colorize:Yellow:120)"
-})
\ No newline at end of file
+dofile(minetest.get_modpath("forestry_bees") .. "/helper.lua")
+dofile(minetest.get_modpath("forestry_bees") .. "/register.lua")
+dofile(minetest.get_modpath("forestry_bees") .. "/apiary.lua")
\ No newline at end of file
diff --git a/forestry_bees/register.lua b/forestry_bees/register.lua
new file mode 100644
index 0000000..02d40d5
--- /dev/null
+++ b/forestry_bees/register.lua
@@ -0,0 +1,112 @@
+local function capitalize(s)
+    return s:sub(1,1):upper()..s:sub(2)
+end
+
+local function makebeetexture(body1,body2,outline,color,ratio)
+    return body1.."^("..body1.."^[makealpha:0,0,0^[colorize:"..color..":"..ratio..")^"..body2.."^("..outline.."^[colorize:"..color..":"..ratio..")"
+end
+
+local function printbeestats(itemstack, user, pointed_thing) 
+    local meta = itemstack:get_meta()
+    local name = itemstack:get_name()
+    minetest.chat_send_player(user:get_player_name(), "Name:"..string.sub(string.match(name, ":.*"),2)..", Active:"..meta:get_string("active_gene")..", Inactive:"..meta:get_string("inactive_gene")) 
+end
+
+local function register_bee(name, color, color_ratio)
+  minetest.register_craftitem("forestry_bees:"..name.."_princess", {
+    description = capitalize(name).." Princess",
+    inventory_image = makebeetexture("body1.png",
+                                      "princess.body2.png",
+                                      "princess.outline.png",color,color_ratio),
+    on_use = printbeestats,
+    groups = {bee_princess=1, bee_monarch=1},
+  })
+  minetest.register_craftitem("forestry_bees:"..name.."_drone", {
+    description = capitalize(name).." Drone",
+    inventory_image = makebeetexture("body1.png",
+                                      "drone.body2.png",
+                                      "drone.outline.png",color,color_ratio),
+    on_use = printbeestats,
+    groups = {bee_drone=1},
+  })
+  minetest.register_craftitem("forestry_bees:"..name.."_queen", {
+    description = capitalize(name).." Queen",
+    inventory_image = makebeetexture("body1.png",
+                                      "queen.body2.png",
+                                      "queen.outline.png",color,color_ratio),
+    on_use = printbeestats,
+    groups = {bee_queen=1, bee_monarch=1},
+  })
+end
+
+--Here we register nodes
+minetest.register_node("forestry_bees:forest_beehive", {
+  description = "Forest Beehive",
+  tiles = {
+          "forestry_bees_forest_beehive_top.png",
+          "forestry_bees_forest_beehive_top.png",
+          "forestry_bees_forest_beehive_side.png",
+          "forestry_bees_forest_beehive_side.png",
+          "forestry_bees_forest_beehive_side.png",
+          "forestry_bees_forest_beehive_side.png",
+  },
+  groups = {scoopy = 1},
+  diggable = true,
+  drop = {
+      max_items = 3,
+      items = {
+          {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess","forest","forest")}},
+          {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone","forest","forest")}},
+          {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}}
+      }
+  }
+})
+
+minetest.register_node("forestry_bees:meadow_beehive", {
+  description = "Meadow Beehive",
+  tiles = {
+          "forestry_bees_meadow_beehive_top.png",
+          "forestry_bees_meadow_beehive_top.png",
+          "forestry_bees_meadow_beehive_side.png",
+          "forestry_bees_meadow_beehive_side.png",
+          "forestry_bees_meadow_beehive_side.png",
+          "forestry_bees_meadow_beehive_side.png",
+  },
+  groups = {scoopy = 1},
+  diggable = true,
+  drop = {
+      max_items = 3,
+      items = {
+          {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("princess","meadow","meadow")}},
+          {tool_groups = {"scoop_tool"}, rarity = 2, items = {forestry_bees.Bee("drone","meadow","meadow")}},
+          {tool_groups = {"scoop_tool"}, rarity = 2, items = {"forestry_bees:honey_comb"}}
+      }
+  }
+})
+
+minetest.register_tool("forestry_bees:scoop", {
+    description = "Scoop",
+    inventory_image = "forestry_bees_scoop.png",
+    groups = {scoop_tool = 1},
+    tool_capabilities = {
+        full_punch_interval = 1.5,
+        max_drop_level = 1,
+        groupcaps = {
+            scoopy = {
+                maxlevel = 1,
+                uses = 10,
+                times = { [1]=1, [2]=1, [3]=1 }
+            },
+        },
+    },
+})
+
+register_bee("forest","#19d0ec","255")
+register_bee("meadow","#ef131e","255")
+register_bee("common","#b2b2b2","255")
+
+minetest.register_craftitem("forestry_bees:honey_comb", {
+    description = "Honey Comb",
+    groups = {comb = 1},
+    inventory_image = "(bee_combs.0.png^[colorize:Yellow:100)^(bee_combs.1.png^[colorize:Yellow:120)"
+})
\ No newline at end of file
diff --git a/forestry_bees/textures/nodes/forestry_bees_apiary_front.png b/forestry_bees/textures/nodes/forestry_bees_apiary_front.png
new file mode 100644
index 0000000000000000000000000000000000000000..74ce35debd6731b9be04caea2942aa9990b9b5da
GIT binary patch
literal 289
zcmV++0p9+JP)<h;3K|Lk000e1NJLTq000mG000mO0{{R3C@l|D0000^P)t-syqIFO
zf;6psGJRSkqI555R5O-qD|22sg<mEn8w;O=O;S4;JS!1=Vm|De8LM<Ch+!v8JtmxO
zDYTGUcTpUoZYHdCDS%obvwA3UQXy)y^`ig)0FFsSK~#8NEsh5c#V`m%ZOH8YbKL);
z-!!!%Jp{xCz%)%jyaz(H)-~rfi}{vw1(_tXLK?{ecW*;}me9gHYjV<z5SL|UF$<;y
zax|_1(OMMV2E(KG@76oTP{CcH8_k3;F4)cNx+PTbRQ9-K5Id!$6y+F6y!2Hn!zLNt
n6r#a%f%vp`xF2ESKY9EC7aj%2w0VJ400000NkvXXu0mjf_A73N

literal 0
HcmV?d00001

diff --git a/forestry_bees/textures/nodes/forestry_bees_apiary_side.png b/forestry_bees/textures/nodes/forestry_bees_apiary_side.png
new file mode 100644
index 0000000000000000000000000000000000000000..9465209fdaa300cdac0c1f458133fe1b272f1d5a
GIT binary patch
literal 277
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!M}SX=>z)}&TboSQ))>`BsZ7h(
zUR0vr8n0FyXPFsdT$5xszr{DmTEa$KaCM1BN20o#H20ib%`Fq6$^&H<<*BVH)oh4T
z^s!Yd3R0AFXO{t*+2QHp7*Y|Z+sDaw*nxvNmwEQto4f!1_vgOZGl8vf1H%R#?trfj
zhQ62Y{JwMf@9p0#MnWe&Czi~Jl)iDZN$|DTugp%5{M%mBPYEg<e-I_GHZ(bRhf$vT
zo;N$(oisxa_QhWM>iw|d+0P%T64sL!w7Ykx#69$>InweWZ511j;lbrw55HL<@H_RG
Zyc`4TuB@Fp^*}c<c)I$ztaD0e0svE5X?6er

literal 0
HcmV?d00001

diff --git a/forestry_bees/textures/nodes/forestry_bees_apiary_y.png b/forestry_bees/textures/nodes/forestry_bees_apiary_y.png
new file mode 100644
index 0000000000000000000000000000000000000000..cd9bf2e36471bda79a590699ac9f41f9ae3b26a5
GIT binary patch
literal 189
zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPE^4e$wZ-7_O;ev9vx2~ovymYE^O
zHA!|pwrcYO0>ps|l097<LpWqv8yE!-Iq<N2Z)&`A-9ehCghS(phXd0;Q-c$doK5LB
zvpL`FVm92pJ6+0h>0-Y>TA?=uPMBXX2J$OXL=K(%q$u1PTl(?c&AXc!Uw+`c-uvhi
j)A9(1`e(P_-~Y$#U(55+>ZxT5&^iWBS3j3^P6<r_!mmZe

literal 0
HcmV?d00001