minetest-mm/mods/bees/init.lua

1339 lines
30 KiB
Lua
Raw Normal View History

2024-12-19 12:55:40 +01:00
2020-10-26 17:38:53 +01:00
-- Mod: BEES
2024-12-19 12:55:40 +01:00
-- Author: Bas080 (Updated by TenPlus1)
2020-10-26 17:38:53 +01:00
-- License: MIT
2024-12-19 12:55:40 +01:00
-- Translation support
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local S = minetest.get_translator("bees")
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- Functions and Formspecs
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local floor, random = math.floor, math.random
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local function hive_wild(pos, grafting)
2020-10-26 17:38:53 +01:00
local spos = pos.x .. "," .. pos.y .. "," ..pos.z
local formspec = "size[8,9]"
2024-12-19 12:55:40 +01:00
.. "label[0,0;" .. S("Wild Bee Hive") .. "]"
.. "list[nodemeta:" .. spos .. ";combs;1.5,3;5,1;]" -- Honey Comb
.. "list[current_player;main;0,5;8,4;]" -- Player Inventory
2020-10-26 17:38:53 +01:00
if grafting then
2024-12-19 12:55:40 +01:00
formspec = formspec .."list[nodemeta:".. spos .. ";queen;3.5,1;1,1;]" -- Queen
else
formspec = formspec .. "item_image[3.5,1;1,1;bees:queen]"
2020-10-26 17:38:53 +01:00
end
return formspec
end
2024-12-19 12:55:40 +01:00
local function hive_artificial(pos)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local spos = pos.x .. "," .. pos.y .. "," .. pos.z
2020-10-26 17:38:53 +01:00
local formspec = "size[8,9]"
2024-12-19 12:55:40 +01:00
.. "label[0,0;" .. S("Artificial Bee Hive") .. "]"
.. "item_image[2.5,1;1,1;bees:queen]" -- Queen
.. "list[nodemeta:" .. spos .. ";queen;3.5,1;1,1;]"
.. "tooltip[3.5,1;1,1;" .. S("Queen Bee").."]"
.. "list[nodemeta:" .. spos .. ";frames;0,3;8,1;]" -- Frames
.. "tooltip[0,3;8,1;" .. S("Empty Hive Frame") .. "]"
.. "list[current_player;main;0,5;8,4;]" -- Player Inventory
2020-10-26 17:38:53 +01:00
return formspec
end
local polinate_flower = function(pos, flower)
local spawn_pos = {
x = pos.x + random(-3, 3),
y = pos.y + random(-3, 3),
z = pos.z + random(-3, 3)
}
local floor_pos = {x = spawn_pos.x, y = spawn_pos.y - 1, z = spawn_pos.z}
local spawn = minetest.get_node(spawn_pos).name
2020-12-26 22:23:48 +01:00
local floorn = minetest.get_node(floor_pos).name
2020-10-26 17:38:53 +01:00
2020-12-26 22:23:48 +01:00
if floorn == "group:soil" and spawn == "air" then
2020-10-26 17:38:53 +01:00
minetest.set_node(spawn_pos, {name = flower})
end
end
2024-12-19 12:55:40 +01:00
local sting_player = function(player, damage)
minetest.after(0.1, function()
if player and player:get_pos() then
player:set_hp(player:get_hp() - damage)
end
end)
end
-- Nodes
2020-10-26 17:38:53 +01:00
minetest.register_node("bees:extractor", {
description = S("Honey Extractor"),
tiles = {
"bees_extractor.png", "bees_extractor.png", "bees_extractor.png",
"bees_extractor.png", "bees_extractor.png", "bees_extractor_front.png"
},
paramtype2 = "facedir",
groups = {
choppy = 2, oddly_breakable_by_hand = 2, tubedevice = 1,
tubedevice_receiver = 1
},
2024-12-19 12:55:40 +01:00
is_ground_content = false,
2020-10-26 17:38:53 +01:00
2020-12-26 22:23:48 +01:00
on_construct = function(pos)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
2020-12-26 22:23:48 +01:00
pos = pos.x .. "," .. pos.y .. "," .. pos.z
2020-10-26 17:38:53 +01:00
inv:set_size("frames_filled", 1)
inv:set_size("frames_emptied", 1)
inv:set_size("bottles_empty", 1)
inv:set_size("bottles_full", 1)
inv:set_size("wax", 1)
meta:set_string("formspec", "size[8,9]"
2024-12-19 12:55:40 +01:00
.. "label[0,0;" .. S("Honey Extractor") .. "]"
2020-12-26 22:23:48 +01:00
-- input
2024-12-19 12:55:40 +01:00
.. "item_image[1,1;1,1;bees:frame_full]"
.. "list[nodemeta:" .. pos .. ";frames_filled;2,1;1,1;]"
.. "tooltip[2,1;1,1;" .. S("Filled Hive Frame") .. "]"
.. "item_image[1,3;1,1;vessels:glass_bottle]"
.. "list[nodemeta:" .. pos .. ";bottles_empty;2,3;1,1;]"
.. "tooltip[2,3;1,1;Empty Bottles]"
2020-12-26 22:23:48 +01:00
-- output
2024-12-19 12:55:40 +01:00
.. "label[4,2;->]"
.. "list[nodemeta:" .. pos .. ";frames_emptied;5,0.5;1,1;]"
.. "tooltip[5,0.5;1,1;" .. S("Empty Hive Frame") .. "]"
.. "list[nodemeta:" .. pos .. ";wax;5,2;1,1;]"
.. "tooltip[5,2;1,1;" .. S("Bees Wax") .. "]"
.. "list[nodemeta:" .. pos .. ";bottles_full;5,3.5;1,1;]"
.. "tooltip[5,3.5;1,1;" .. S("Honey Bottle") .. "]"
2020-12-26 22:23:48 +01:00
-- player inventory
2020-10-26 17:38:53 +01:00
.. "list[current_player;main;0,5;8,4;]"
)
end,
2024-12-19 12:55:40 +01:00
can_dig = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("frames_filled") and inv:is_empty("frames_emptied")
and inv:is_empty("bottles_empty") and inv:is_empty("bottles_full")
and inv:is_empty("wax") then
return true
else
return false
end
end,
2020-12-26 22:23:48 +01:00
on_timer = function(pos)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
2020-12-26 22:23:48 +01:00
local timer = minetest.get_node_timer(pos)
2020-10-26 17:38:53 +01:00
if not inv:contains_item("frames_filled", "bees:frame_full")
or not inv:contains_item("bottles_empty", "vessels:glass_bottle") then
return
end
if inv:room_for_item("frames_emptied", "bees:frame_empty")
and inv:room_for_item("wax", "bees:wax")
and inv:room_for_item("bottles_full", "bees:bottle_honey") then
2020-12-26 22:23:48 +01:00
-- add to output
2020-10-26 17:38:53 +01:00
inv:add_item("frames_emptied", "bees:frame_empty")
inv:add_item("wax", "bees:wax")
inv:add_item("bottles_full", "bees:bottle_honey")
2020-12-26 22:23:48 +01:00
-- remove from input
2020-10-26 17:38:53 +01:00
inv:remove_item("bottles_empty", "vessels:glass_bottle")
inv:remove_item("frames_filled", "bees:frame_full")
2020-12-26 22:23:48 +01:00
-- wax flying all over the place
2020-10-26 17:38:53 +01:00
minetest.add_particle({
pos = {x = pos.x, y = pos.y, z = pos.z},
2020-12-26 22:23:48 +01:00
velocity = {
2020-10-26 17:38:53 +01:00
x = random(-1, 1),
y = random(4),
z = random(-1, 1)
},
2020-12-26 22:23:48 +01:00
acceleration = {x = 0, y = -6, z = 0},
2020-10-26 17:38:53 +01:00
expirationtime = 2,
size = random(1, 3),
collisiondetection = false,
texture = "bees_wax_particle.png",
})
timer:start(5)
else
2020-12-26 22:23:48 +01:00
timer:start(5) -- try again in 5 seconds (was 1)
2020-10-26 17:38:53 +01:00
end
end,
tube = {
2020-12-26 22:23:48 +01:00
insert_object = function(pos, _, stack)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer = minetest.get_node_timer(pos)
if stack:get_name() == "bees:frame_full" then
if inv:is_empty("frames_filled") then
timer:start(5)
end
return inv:add_item("frames_filled",stack)
elseif stack:get_name() == "vessels:glass_bottle" then
if inv:is_empty("bottles_empty") then
timer:start(5)
end
return inv:add_item("bottles_empty",stack)
end
return stack
end,
2020-12-26 22:23:48 +01:00
can_insert = function(pos, _, stack)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if stack:get_name() == "bees:frame_full" then
2020-12-26 22:23:48 +01:00
return inv:room_for_item("frames_filled", stack)
2020-10-26 17:38:53 +01:00
elseif stack:get_name() == "vessels:glass_bottle" then
2020-12-26 22:23:48 +01:00
return inv:room_for_item("bottles_empty", stack)
2020-10-26 17:38:53 +01:00
end
return false
end,
input_inventory = {"frames_emptied", "bottles_full", "wax"},
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
},
2020-12-26 22:23:48 +01:00
on_metadata_inventory_put = function(pos, listname, _, stack)
2020-10-26 17:38:53 +01:00
local timer = minetest.get_node_timer(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
-- if inventory empty start timer for honey bottle, empty frame and wax
if inv:get_stack(listname, 1):get_count() == stack:get_count() then
timer:start(5)
end
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_put = function(_, listname, _, stack)
2020-10-26 17:38:53 +01:00
if (listname == "bottles_empty" and stack:get_name() == "vessels:glass_bottle")
or (listname == "frames_filled" and stack:get_name() == "bees:frame_full") then
return stack:get_count()
else
return 0
end
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_move = function()
2020-10-26 17:38:53 +01:00
return 0
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_take = function(pos, _, _, stack, player)
2020-10-26 17:38:53 +01:00
if player and minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
2024-12-19 12:55:40 +01:00
end
2020-10-26 17:38:53 +01:00
})
minetest.register_node("bees:bees", {
description = S("Bees"),
drawtype = "plantlike",
paramtype = "light",
groups = {not_in_creative_inventory = 1},
2020-12-26 22:23:48 +01:00
tiles = {{
name = "bees_strip.png",
animation = {
type = "vertical_frames", aspect_w = 16, aspect_h = 16, length = 2.0
2020-10-26 17:38:53 +01:00
}
2020-12-26 22:23:48 +01:00
}},
2020-10-26 17:38:53 +01:00
damage_per_second = 1,
walkable = false,
buildable_to = true,
selection_box = {
type = "fixed",
fixed = {
2024-12-19 12:55:40 +01:00
{-0.3, -0.4, -0.3, 0.3, 0.4, 0.3}
2020-10-26 17:38:53 +01:00
}
},
2024-12-19 12:55:40 +01:00
on_timer = function(pos)
minetest.remove_node(pos)
2020-10-26 17:38:53 +01:00
end,
2024-12-19 12:55:40 +01:00
on_construct = function(pos)
local timer = minetest.get_node_timer(pos)
timer:start(25)
minetest.sound_play("bees",
{pos = pos, gain = 1.0, max_hear_distance = 10}, true)
end,
on_punch = function(_, _, puncher)
sting_player(puncher, 2)
end
2020-10-26 17:38:53 +01:00
})
minetest.register_node("bees:hive_wild", {
description = S("Wild Bee Hive"),
2020-12-26 22:23:48 +01:00
tiles = { -- Neuromancer's base texture
2020-10-26 17:38:53 +01:00
"bees_hive_wild.png", "bees_hive_wild.png", "bees_hive_wild.png",
"bees_hive_wild.png", "bees_hive_wild_bottom.png"
},
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "wallmounted",
drop = {
max_items = 6,
items = {
2020-12-26 22:23:48 +01:00
{items = {"bees:honey_comb"}, rarity = 5}
2020-10-26 17:38:53 +01:00
}
},
2021-09-05 16:06:04 +02:00
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3},
2024-12-19 12:55:40 +01:00
is_ground_content = false,
2020-12-26 22:23:48 +01:00
node_box = { -- VanessaE's wild hive nodebox contribution
2020-10-26 17:38:53 +01:00
type = "fixed",
fixed = {
2020-12-26 22:23:48 +01:00
{-0.25, -0.5, -0.25, 0.25, 0.375, 0.25},
{-0.3125, -0.375, -0.3125, 0.3125, 0.25, 0.3125},
{-0.375, -0.25, -0.375, 0.375, 0.125, 0.375},
2024-12-19 12:55:40 +01:00
{-0.0625, -0.5, -0.0625, 0.0625, 0.5, 0.0625}
2020-10-26 17:38:53 +01:00
}
},
on_timer = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer = minetest.get_node_timer(pos)
local rad = 10
local flowers = minetest.find_nodes_in_area(
{x = pos.x - rad, y = pos.y - rad, z = pos.z - rad},
{x = pos.x + rad, y = pos.y + rad, z = pos.z + rad},
"group:flower")
-- Queen dies if no flowers nearby
if #flowers == 0 then
inv:set_stack("queen", 1, "")
meta:set_string("infotext", S("Colony died, not enough flowers in area!"))
return
end
-- Requires 2 or more flowers to make honey
if #flowers < 3 then return end
local flower = flowers[random(#flowers)]
polinate_flower(flower, minetest.get_node(flower).name)
local stacks = inv:get_list("combs")
2020-12-26 22:23:48 +01:00
for k, _ in pairs(stacks) do
2020-10-26 17:38:53 +01:00
if inv:get_stack("combs", k):is_empty() then
inv:set_stack("combs", k, "bees:honey_comb")
timer:start(1000 / #flowers)
return
end
end
2020-12-26 22:23:48 +01:00
-- what to do if all combs are filled
2020-10-26 17:38:53 +01:00
end,
on_construct = function(pos)
minetest.get_node(pos).param2 = 0
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer = minetest.get_node_timer(pos)
meta:set_int("agressive", 1)
timer:start(100 + random(100))
inv:set_size("queen", 1)
inv:set_size("combs", 5)
inv:set_stack("queen", 1, "bees:queen")
for i = 1, random(3) do
inv:set_stack("combs", i, "bees:honey_comb")
end
end,
2020-12-26 22:23:48 +01:00
on_punch = function(pos, _, puncher)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:contains_item("queen", "bees:queen") then
2024-12-19 12:55:40 +01:00
sting_player(puncher, 4)
2020-10-26 17:38:53 +01:00
end
2024-12-19 12:55:40 +01:00
minetest.sound_play("bees",
{pos = pos, gain = 1.0, max_hear_distance = 10}, true)
2020-10-26 17:38:53 +01:00
end,
2020-12-26 22:23:48 +01:00
on_metadata_inventory_take = function(pos, listname, _, _, taker)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer= minetest.get_node_timer(pos)
if listname == "combs" and inv:contains_item("queen", "bees:queen") then
timer:start(10)
2024-12-19 12:55:40 +01:00
sting_player(taker, 2)
2020-10-26 17:38:53 +01:00
end
end,
2020-12-26 22:23:48 +01:00
on_metadata_inventory_put = function(pos)
2020-10-26 17:38:53 +01:00
local timer = minetest.get_node_timer(pos)
if not timer:is_started() then
timer:start(10)
end
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_put = function(_, listname, _, stack)
2020-10-26 17:38:53 +01:00
2020-12-26 22:23:48 +01:00
-- restart the colony by adding a queen
2020-10-26 17:38:53 +01:00
if listname == "queen" and stack:get_name() == "bees:queen" then
return 1
else
return 0
end
end,
2020-12-26 22:23:48 +01:00
on_rightclick = function(pos, _, clicker, itemstack)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if not itemstack then return end
2020-10-26 17:38:53 +01:00
minetest.show_formspec(clicker:get_player_name(),
"bees:hive_artificial",
hive_wild(pos, (itemstack:get_name() == "bees:grafting_tool"))
)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if meta:get_int("agressive") == 1
and inv:contains_item("queen", "bees:queen") then
2024-12-19 12:55:40 +01:00
minetest.sound_play("bees",
{pos = pos, gain = 1.0, max_hear_distance = 10}, true)
sting_player(clicker, 4)
2020-10-26 17:38:53 +01:00
else
meta:set_int("agressive", 1)
end
end,
2020-12-26 22:23:48 +01:00
can_dig = function(pos)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("queen") and inv:is_empty("combs") then
return true
else
return false
end
end,
2020-12-26 22:23:48 +01:00
after_dig_node = function(_, _, _, user)
2020-10-26 17:38:53 +01:00
local wielded
if user:get_wielded_item() ~= nil then
wielded = user:get_wielded_item()
else
return
end
if "bees:grafting_tool" == wielded:get_name() then
local inv = user:get_inventory()
if inv then
inv:add_item("main", ItemStack("bees:queen"))
end
end
end
})
minetest.register_node("bees:hive_artificial", {
description = S("Artificial Bee Hive"),
tiles = {
"default_wood.png", "default_wood.png", "default_wood.png",
"default_wood.png", "default_wood.png", "bees_hive_artificial.png"
},
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
groups = {
snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,
flammable = 3, wood = 1
},
2024-12-19 12:55:40 +01:00
is_ground_content = false,
2020-10-26 17:38:53 +01:00
sounds = default.node_sound_wood_defaults(),
node_box = {
type = "fixed",
fixed = {
{-4/8, 2/8, -4/8, 4/8, 3/8, 4/8},
{-3/8, -4/8, -2/8, 3/8, 2/8, 3/8},
{-3/8, 0/8, -3/8, 3/8, 2/8, -2/8},
{-3/8, -4/8, -3/8, 3/8, -1/8, -2/8},
{-3/8, -1/8, -3/8, -1/8, 0/8, -2/8},
{1/8, -1/8, -3/8, 3/8, 0/8, -2/8},
}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
meta:set_int("agressive", 1)
inv:set_size("queen", 1)
inv:set_size("frames", 8)
meta:set_string("infotext", S("Requires Queen bee to function"))
end,
2020-12-26 22:23:48 +01:00
on_rightclick = function(pos, _, clicker)
2020-10-26 17:38:53 +01:00
2020-12-26 22:23:48 +01:00
local player_name = clicker:get_player_name()
if minetest.is_protected(pos, player_name) then
2020-10-26 17:38:53 +01:00
return
end
2020-12-26 22:23:48 +01:00
minetest.show_formspec(player_name,
2020-10-26 17:38:53 +01:00
"bees:hive_artificial",
hive_artificial(pos)
)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if meta:get_int("agressive") == 1
and inv:contains_item("queen", "bees:queen") then
2024-12-19 12:55:40 +01:00
sting_player(clicker, 4)
2020-10-26 17:38:53 +01:00
else
meta:set_int("agressive", 1)
end
end,
2020-12-26 22:23:48 +01:00
on_timer = function(pos)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer = minetest.get_node_timer(pos)
if inv:contains_item("queen", "bees:queen") then
if inv:contains_item("frames", "bees:frame_empty") then
timer:start(30)
local rad = 10
local flowers = minetest.find_nodes_in_area(
{x = pos.x - rad, y = pos.y - rad, z = pos.z - rad},
{x = pos.x + rad, y = pos.y + rad, z = pos.z + rad},
"group:flower")
local progress = meta:get_int("progress")
progress = progress + #flowers
meta:set_int("progress", progress)
if progress > 1000 then
local flower = flowers[random(#flowers)]
polinate_flower(flower, minetest.get_node(flower).name)
local stacks = inv:get_list("frames")
2020-12-26 22:23:48 +01:00
for k, _ in pairs(stacks) do
2020-10-26 17:38:53 +01:00
if inv:get_stack("frames", k):get_name() == "bees:frame_empty" then
meta:set_int("progress", 0)
inv:set_stack("frames", k, "bees:frame_full")
return
end
end
else
meta:set_string("infotext", S("progress:")
.. " " .. progress .. " + " .. #flowers .. " / 1000")
end
else
meta:set_string("infotext", S("Does not have empty frame(s)"))
timer:stop()
end
end
end,
2020-12-26 22:23:48 +01:00
on_metadata_inventory_take = function(pos, listname)
2020-10-26 17:38:53 +01:00
if listname == "queen" then
local timer = minetest.get_node_timer(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Requires Queen bee to function"))
timer:stop()
end
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_move = function(pos, from_list, _, to_list, to_index)
2020-10-26 17:38:53 +01:00
local inv = minetest.get_meta(pos):get_inventory()
if from_list == to_list then
if inv:get_stack(to_list, to_index):is_empty() then
return 1
else
return 0
end
else
return 0
end
end,
2020-12-26 22:23:48 +01:00
on_metadata_inventory_put = function(pos, listname, _, stack)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer = minetest.get_node_timer(pos)
if listname == "queen" or listname == "frames" then
meta:set_string("queen", stack:get_name())
meta:set_string("infotext", S("Queen inserted, now for the empty frames"))
if inv:contains_item("frames", "bees:frame_empty") then
timer:start(30)
meta:set_string("infotext", S("Bees are aclimating"))
end
end
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_put = function(pos, listname, index, stack)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if not minetest.get_meta(pos):get_inventory():get_stack(
listname, index):is_empty() then return 0 end
2020-10-26 17:38:53 +01:00
if listname == "queen" then
if stack:get_name():match("bees:queen*") then
return 1
end
elseif listname == "frames" then
if stack:get_name() == ("bees:frame_empty") then
return 1
end
end
return 0
end,
2024-12-19 12:55:40 +01:00
can_dig = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("queen") and inv:is_empty("frames") then
return true
else
return false
end
end
})
2020-12-26 22:23:48 +01:00
-- ABMs
2020-10-26 17:38:53 +01:00
minetest.register_abm({
2024-12-19 12:55:40 +01:00
label = "spawn bee particles",
2020-10-26 17:38:53 +01:00
nodenames = {"bees:hive_artificial", "bees:hive_wild", "bees:hive_industrial"},
interval = 10,
chance = 4,
action = function(pos, node)
-- Bee particle
minetest.add_particle({
pos = {x = pos.x, y = pos.y, z = pos.z},
2020-12-26 22:23:48 +01:00
velocity = {
2020-10-26 17:38:53 +01:00
x = (random() - 0.5) * 5,
y = (random() - 0.5) * 5,
z = (random() - 0.5) * 5
},
2020-12-26 22:23:48 +01:00
acceleration = {
2020-10-26 17:38:53 +01:00
x = random() - 0.5,
y = random() - 0.5,
z = random() - 0.5
},
2024-12-19 12:55:40 +01:00
expirationtime = random(2, 5),
2020-10-26 17:38:53 +01:00
size = random(3),
collisiondetection = true,
texture = "bees_particle_bee.png",
})
2024-12-19 12:55:40 +01:00
minetest.sound_play("bees",
{pos = pos, gain = 0.6, max_hear_distance = 5}, true)
2020-10-26 17:38:53 +01:00
-- floating hive check and removal
if node.name == "bees:hive_wild" then
local num = #minetest.find_nodes_in_area(
{x = pos.x - 1, y = pos.y - 1, z = pos.z - 1},
2024-12-19 12:55:40 +01:00
{x = pos.x + 1, y = pos.y + 1, z = pos.z + 1}, {"air"})
2020-10-26 17:38:53 +01:00
if num and num > 25 then
minetest.remove_node(pos)
end
end
2024-12-19 12:55:40 +01:00
end
2020-10-26 17:38:53 +01:00
})
2024-12-19 12:55:40 +01:00
-- Hive spawn ABM. This should be changed to a more realistic type of spawning
2020-10-26 17:38:53 +01:00
minetest.register_abm({
2024-12-19 12:55:40 +01:00
label = "spawn bee hives",
2020-10-26 17:38:53 +01:00
nodenames = {"group:leaves"},
neighbors = {"air"},
interval = 300,
chance = 4,
2020-10-26 17:38:53 +01:00
2020-12-26 22:23:48 +01:00
action = function(pos)
2020-10-26 17:38:53 +01:00
if floor(pos.x / 20) ~= pos.x / 20
or floor(pos.z / 20) ~= pos.z / 20
or floor(pos.y / 3) ~= pos.y / 3 then return end
2020-10-26 17:38:53 +01:00
local p = {x = pos.x, y = pos.y - 1, z = pos.z}
-- skip if nearby hive found
if minetest.find_node_near(p, 25, {"bees:hive_artificial", "bees:hive_wild",
"bees:hive_industrial"}) then
return
end
2020-10-26 17:38:53 +01:00
local nod = minetest.get_node_or_nil(p)
local def = nod and minetest.registered_nodes[nod.name]
if not def or def.walkable then return end
if minetest.find_node_near(p, 5, "group:flora") then
minetest.add_node(p, {name = "bees:hive_wild"})
end
2024-12-19 12:55:40 +01:00
end
2020-10-26 17:38:53 +01:00
})
2024-12-19 12:55:40 +01:00
-- Spawning bees around bee hive
2020-10-26 17:38:53 +01:00
minetest.register_abm({
2024-12-19 12:55:40 +01:00
label = "spawn bees around bee hives",
2020-10-26 17:38:53 +01:00
nodenames = {"bees:hive_wild", "bees:hive_artificial", "bees:hive_industrial"},
2024-12-19 12:55:40 +01:00
neighbors = {"group:flower", "group:leaves"},
2020-10-26 17:38:53 +01:00
interval = 30,
chance = 4,
2020-12-26 22:23:48 +01:00
action = function(pos)
2020-10-26 17:38:53 +01:00
local p = {
x = pos.x + random(-5, 5),
y = pos.y - random(0, 3),
z = pos.z + random(-5, 5)
}
if minetest.get_node(p).name == "air" then
minetest.add_node(p, {name="bees:bees"})
end
2024-12-19 12:55:40 +01:00
end
2020-10-26 17:38:53 +01:00
})
2024-12-19 12:55:40 +01:00
-- Helper function
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local function add_eatable(item, hp)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local def = minetest.registered_items[item]
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if def then
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
local groups = table.copy(def.groups) or {}
groups.eatable = hp ; groups.flammable = 2
minetest.override_item(item, {groups = groups})
end
end
-- Items
2020-10-26 17:38:53 +01:00
minetest.register_craftitem("bees:frame_empty", {
2024-12-19 12:55:40 +01:00
description = S("Empty Hive Frame"),
2020-10-26 17:38:53 +01:00
inventory_image = "bees_frame_empty.png",
2024-12-19 12:55:40 +01:00
stack_max = 24
2020-10-26 17:38:53 +01:00
})
minetest.register_craftitem("bees:frame_full", {
2024-12-19 12:55:40 +01:00
description = S("Filled Hive Frame"),
2020-10-26 17:38:53 +01:00
inventory_image = "bees_frame_full.png",
2024-12-19 12:55:40 +01:00
stack_max = 12
2020-10-26 17:38:53 +01:00
})
minetest.register_craftitem("bees:bottle_honey", {
2024-12-19 12:55:40 +01:00
description = S("Honey Bottle"),
2020-10-26 17:38:53 +01:00
inventory_image = "bees_bottle_honey.png",
stack_max = 12,
on_use = minetest.item_eat(3, "vessels:glass_bottle"),
2024-12-19 12:55:40 +01:00
groups = {vessel = 1}
2020-10-26 17:38:53 +01:00
})
2024-12-19 12:55:40 +01:00
add_eatable("bees:bottle_honey", 3)
2020-10-26 17:38:53 +01:00
minetest.register_craftitem("bees:wax", {
2024-12-19 12:55:40 +01:00
description = S("Bees Wax"),
2020-10-26 17:38:53 +01:00
inventory_image = "bees_wax.png",
2024-12-19 12:55:40 +01:00
stack_max = 48
2020-10-26 17:38:53 +01:00
})
minetest.register_craftitem("bees:honey_comb", {
2024-12-19 12:55:40 +01:00
description = S("Honey Comb"),
2020-10-26 17:38:53 +01:00
inventory_image = "bees_comb.png",
on_use = minetest.item_eat(2),
2024-12-19 12:55:40 +01:00
stack_max = 8
2020-10-26 17:38:53 +01:00
})
2024-12-19 12:55:40 +01:00
add_eatable("bees:honey_comb", 2)
2020-10-26 17:38:53 +01:00
minetest.register_craftitem("bees:queen", {
description = S("Queen Bee"),
inventory_image = "bees_particle_bee.png",
2024-12-19 12:55:40 +01:00
stack_max = 1
2020-10-26 17:38:53 +01:00
})
2024-12-19 12:55:40 +01:00
-- Crafts
2020-10-26 17:38:53 +01:00
minetest.register_craft({
output = "bees:extractor",
recipe = {
{"", "default:steel_ingot", ""},
{"default:steel_ingot", "default:stick", "default:steel_ingot"},
2024-12-19 12:55:40 +01:00
{"default:mese_crystal", "default:steel_ingot", "default:mese_crystal"}
2020-10-26 17:38:53 +01:00
}
})
minetest.register_craft({
output = "bees:smoker",
recipe = {
{"default:steel_ingot", "wool:red", ""},
{"", "default:torch", ""},
2024-12-19 12:55:40 +01:00
{"", "default:steel_ingot",""}
2020-10-26 17:38:53 +01:00
}
})
minetest.register_craft({
output = "bees:hive_artificial",
recipe = {
{"group:wood", "group:wood", "group:wood"},
{"group:wood", "default:stick", "group:wood"},
2024-12-19 12:55:40 +01:00
{"group:wood", "default:stick", "group:wood"}
2020-10-26 17:38:53 +01:00
}
})
minetest.register_craft({
output = "bees:grafting_tool",
recipe = {
{"", "", "default:steel_ingot"},
{"", "default:stick", ""},
2024-12-19 12:55:40 +01:00
{"", "", ""}
2020-10-26 17:38:53 +01:00
}
})
minetest.register_craft({
output = "bees:frame_empty",
recipe = {
{"group:wood", "group:wood", "group:wood"},
{"default:stick", "default:stick", "default:stick"},
2024-12-19 12:55:40 +01:00
{"default:stick", "default:stick", "default:stick"}
2020-10-26 17:38:53 +01:00
}
})
if minetest.get_modpath("bushes_classic") then
minetest.register_craft({
type = "cooking",
cooktime = 5,
recipe = "bees:bottle_honey",
2024-12-19 12:55:40 +01:00
output = "bushes:sugar"
2020-10-26 17:38:53 +01:00
})
end
2024-12-19 12:55:40 +01:00
-- Tools
2020-10-26 17:38:53 +01:00
minetest.register_tool("bees:smoker", {
2024-12-19 12:55:40 +01:00
description = S("Smoker"),
2020-10-26 17:38:53 +01:00
inventory_image = "bees_smoker.png",
tool_capabilities = {
full_punch_interval = 3.0,
max_drop_level = 0,
2024-12-19 12:55:40 +01:00
damage_groups = {fleshy = 2}
2020-10-26 17:38:53 +01:00
},
2020-12-26 22:23:48 +01:00
on_use = function(itemstack, _, pointed_thing)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
if pointed_thing.type ~= "node" then return end
2020-10-26 17:38:53 +01:00
local pos = pointed_thing.under
for i = 1, 6 do
minetest.add_particle({
pos = {
x = pos.x + random() - 0.5,
y = pos.y,
z = pos.z + random() - 0.5
},
2020-12-26 22:23:48 +01:00
velocity = {x = 0, y = 0.5 + random(), z = 0},
acceleration = {x = 0, y = 0, z = 0},
2020-10-26 17:38:53 +01:00
expirationtime = 2 + random(2.5),
size = random(3),
collisiondetection = false,
2024-12-19 12:55:40 +01:00
texture = "bees_smoke_particle.png"
2020-10-26 17:38:53 +01:00
})
end
itemstack:add_wear(65535 / 200)
2024-12-19 12:55:40 +01:00
local nodename = minetest.get_node(pos).name or ""
if nodename:find("bees:hive_") then
local meta = minetest.get_meta(pos)
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
meta:set_int("agressive", 0)
end
2020-10-26 17:38:53 +01:00
return itemstack
2024-12-19 12:55:40 +01:00
end
2020-10-26 17:38:53 +01:00
})
minetest.register_tool("bees:grafting_tool", {
2024-12-19 12:55:40 +01:00
description = S("Grafting Tool"),
2020-10-26 17:38:53 +01:00
inventory_image = "bees_grafting_tool.png",
tool_capabilities = {
full_punch_interval = 3.0,
2024-12-19 12:55:40 +01:00
max_drop_level = 0,
damage_groups = {fleshy = 2}
}
2020-10-26 17:38:53 +01:00
})
2020-12-26 22:23:48 +01:00
-- COMPATIBILTY
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
-- Aliases
2020-10-26 17:38:53 +01:00
2024-12-19 12:55:40 +01:00
minetest.register_alias("bees:honey_extractor", "bees:extractor")
2020-10-26 17:38:53 +01:00
minetest.register_alias("bees:honey_bottle", "bees:bottle_honey")
2024-12-19 12:55:40 +01:00
-- Start hive timers on map load
2020-10-26 17:38:53 +01:00
minetest.register_lbm({
2024-12-19 12:55:40 +01:00
nodenames = {"bees:hive", "bees:hive_artificial_inhabited", "bees:bees"},
2020-10-26 17:38:53 +01:00
name = "bees:replace_old_hives",
label = "Replace old hives",
run_at_every_load = true,
action = function(pos, node)
2024-12-19 12:55:40 +01:00
if node.name == "bees:bees" then
local timer = minetest.get_node_timer(pos)
timer:start(20)
end
2020-10-26 17:38:53 +01:00
if node.name == "bees:hive" then
minetest.set_node(pos, {name = "bees:hive_wild"})
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_stack("queen", 1, "bees:queen")
end
if node.name == "bees:hive_artificial_inhabited" then
minetest.set_node(pos, {name = "bees:hive_artificial"})
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_stack("queen", 1, "bees:queen")
local timer = minetest.get_node_timer(pos)
timer:start(60)
end
end
})
2024-12-19 12:55:40 +01:00
-- Pipeworks
2020-10-26 17:38:53 +01:00
if minetest.get_modpath("pipeworks") then
minetest.register_node("bees:hive_industrial", {
description = S("Industrial Bee Hive"),
tiles = {"bees_hive_industrial.png"},
paramtype2 = "facedir",
groups = {
snappy = 1, choppy = 2, oddly_breakable_by_hand = 2,
tubedevice = 1, tubedevice_receiver = 1
},
2024-12-19 12:55:40 +01:00
is_ground_content = false,
2020-10-26 17:38:53 +01:00
sounds = default.node_sound_wood_defaults(),
tube = {
2020-12-26 22:23:48 +01:00
insert_object = function(pos, _, stack)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if stack:get_name() ~= "bees:frame_empty"
or stack:get_count() > 1 then
return stack
end
for i = 1, 8 do
if inv:get_stack("frames", i):is_empty() then
inv:set_stack("frames", i, stack)
local timer = minetest.get_node_timer(pos)
timer:start(30)
meta:set_string("infotext", S("Bees are aclimating"))
return ItemStack("")
end
end
return stack
end,
2020-12-26 22:23:48 +01:00
can_insert = function(pos, _, stack)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if stack:get_name() ~= "bees:frame_empty"
or stack:get_count() > 1 then
return false
end
for i = 1, 8 do
if inv:get_stack("frames", i):is_empty() then
return true
end
end
return false
end,
2020-12-26 22:23:48 +01:00
can_remove = function(_, _, stack)
2020-10-26 17:38:53 +01:00
if stack:get_name() == "bees:frame_full" then
return 1
else
return 0
end
end,
input_inventory = "frames",
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
meta:set_int("agressive", 1)
inv:set_size("queen", 1)
inv:set_size("frames", 8)
meta:set_string("infotext", S("Requires Queen bee to function"))
end,
2024-12-19 12:55:40 +01:00
can_dig = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:is_empty("queen") and inv:is_empty("frames") then
return true
else
return false
end
end,
2020-12-26 22:23:48 +01:00
on_rightclick = function(pos, _, clicker)
local player_name = clicker:get_player_name()
2020-10-26 17:38:53 +01:00
2020-12-26 22:23:48 +01:00
if minetest.is_protected(pos, player_name) then
2020-10-26 17:38:53 +01:00
return
end
2020-12-26 22:23:48 +01:00
minetest.show_formspec(player_name,
2020-10-26 17:38:53 +01:00
"bees:hive_artificial",
hive_artificial(pos)
)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if meta:get_int("agressive") == 1
and inv:contains_item("queen", "bees:queen") then
2024-12-19 12:55:40 +01:00
sting_player(clicker, 4)
2020-10-26 17:38:53 +01:00
else
meta:set_int("agressive", 1)
end
end,
2020-12-26 22:23:48 +01:00
on_timer = function(pos)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer = minetest.get_node_timer(pos)
if inv:contains_item("queen", "bees:queen") then
if inv:contains_item("frames", "bees:frame_empty") then
timer:start(30)
local rad = 10
local minp = {x = pos.x - rad, y = pos.y - rad, z = pos.z - rad}
local maxp = {x = pos.x + rad, y = pos.y + rad, z = pos.z + rad}
local flowers = minetest.find_nodes_in_area(minp, maxp, "group:flower")
local progress = meta:get_int("progress")
progress = progress + #flowers
meta:set_int("progress", progress)
if progress > 1000 then
local flower = flowers[random(#flowers)]
polinate_flower(flower, minetest.get_node(flower).name)
local stacks = inv:get_list("frames")
2020-12-26 22:23:48 +01:00
for k, _ in pairs(stacks) do
2020-10-26 17:38:53 +01:00
if inv:get_stack("frames", k):get_name() == "bees:frame_empty" then
meta:set_int("progress", 0)
inv:set_stack("frames", k, "bees:frame_full")
return
end
end
else
meta:set_string("infotext", S("progress:")
.. " " .. progress .. " + " .. #flowers .. " / 1000")
end
else
meta:set_string("infotext", S("Does not have empty frame(s)"))
timer:stop()
end
end
end,
2020-12-26 22:23:48 +01:00
on_metadata_inventory_take = function(pos, listname)
2020-10-26 17:38:53 +01:00
if listname == "queen" then
local timer = minetest.get_node_timer(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", S("Requires Queen bee to function"))
timer:stop()
end
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_move = function(pos, from_list, _, to_list, to_index)
2020-10-26 17:38:53 +01:00
local inv = minetest.get_meta(pos):get_inventory()
if from_list == to_list then
if inv:get_stack(to_list, to_index):is_empty() then
return 1
else
return 0
end
else
return 0
end
end,
2020-12-26 22:23:48 +01:00
on_metadata_inventory_put = function(pos, listname, _, stack)
2020-10-26 17:38:53 +01:00
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local timer = minetest.get_node_timer(pos)
if listname == "queen" or listname == "frames" then
meta:set_string("queen", stack:get_name())
meta:set_string("infotext", S("Queen inserted, now for the empty frames"))
if inv:contains_item("frames", "bees:frame_empty") then
timer:start(30)
meta:set_string("infotext", S("Bees are aclimating"))
end
end
end,
2020-12-26 22:23:48 +01:00
allow_metadata_inventory_put = function(pos, listname, index, stack)
2020-10-26 17:38:53 +01:00
if not minetest.get_meta(pos):get_inventory():get_stack(listname, index):is_empty() then
return 0
end
if listname == "queen" then
if stack:get_name():match("bees:queen*") then
return 1
end
elseif listname == "frames" then
if stack:get_name() == ("bees:frame_empty") then
return 1
end
end
return 0
2024-12-19 12:55:40 +01:00
end
2020-10-26 17:38:53 +01:00
})
minetest.register_craft({
output = "bees:hive_industrial",
recipe = {
2024-12-19 12:55:40 +01:00
{"default:steel_ingot", "homedecor:plastic_sheeting", "default:steel_ingot"},
{"pipeworks:tube_1", "bees:hive_artificial", "pipeworks:tube_1"},
{"default:steel_ingot", "homedecor:plastic_sheeting", "default:steel_ingot"}
2020-10-26 17:38:53 +01:00
}
})
end
2024-12-19 12:55:40 +01:00
-- Lucky Blocks
2020-10-26 17:38:53 +01:00
if minetest.get_modpath("lucky_block") then
local add_bees = function(pos, player)
local objs = minetest.get_objects_inside_radius(pos, 15)
minetest.chat_send_player(player:get_player_name(),
2024-12-19 12:55:40 +01:00
minetest.colorize("violet", S("Bees! Bees for all!")))
2020-10-26 17:38:53 +01:00
for n = 1, #objs do
if objs[n]:is_player() then
local player_pos = objs[n]:get_pos()
player_pos.y = player_pos.y + 1
2024-12-19 12:55:40 +01:00
minetest.set_node(player_pos, {name = "bees:bees"})
2020-10-26 17:38:53 +01:00
end
end
end
lucky_block:add_blocks({
{"cus", add_bees},
{"dro", {"bees:grafting_tool"}, 1},
{"dro", {"bees:frame_empty"}, 2},
{"dro", {"bees:queen"}, 1},
{"nod", "bees:extractor"},
{"dro", {"bees:frame_full"}, 2},
{"dro", {"bees:bottle_honey"}, 3},
{"dro", {"bees:smoker"}, 1},
2024-12-19 12:55:40 +01:00
{"nod", "bees:hive_artificial"}
2020-10-26 17:38:53 +01:00
})
end
2024-12-19 12:55:40 +01:00
print("[MOD] Bees Loaded")