From 7fb2ceea9d596e1e9e8b5f5d6c36f52b1de5e751 Mon Sep 17 00:00:00 2001 From: elite Date: Sat, 22 Jul 2017 21:14:16 -0400 Subject: [PATCH] add bonemeal mod --- worldmods/bonemeal/README.md | 26 + worldmods/bonemeal/api.txt | 76 +++ worldmods/bonemeal/depends.txt | 6 + worldmods/bonemeal/description.txt | 1 + worldmods/bonemeal/init.lua | 482 ++++++++++++++++++ worldmods/bonemeal/intllib.lua | 45 ++ worldmods/bonemeal/license.txt | 21 + worldmods/bonemeal/locale/fr.txt | 7 + worldmods/bonemeal/locale/template.txt | 7 + worldmods/bonemeal/mod.conf | 1 + worldmods/bonemeal/mods.lua | 116 +++++ worldmods/bonemeal/screenshot.png | Bin 0 -> 15254 bytes worldmods/bonemeal/textures/bonemeal_bone.png | Bin 0 -> 148 bytes .../bonemeal/textures/bonemeal_fertiliser.png | Bin 0 -> 186 bytes worldmods/bonemeal/textures/bonemeal_item.png | Bin 0 -> 186 bytes .../bonemeal/textures/bonemeal_mulch.png | Bin 0 -> 186 bytes .../bonemeal/textures/bonemeal_particle.png | Bin 0 -> 116 bytes 17 files changed, 788 insertions(+) create mode 100644 worldmods/bonemeal/README.md create mode 100644 worldmods/bonemeal/api.txt create mode 100644 worldmods/bonemeal/depends.txt create mode 100644 worldmods/bonemeal/description.txt create mode 100644 worldmods/bonemeal/init.lua create mode 100644 worldmods/bonemeal/intllib.lua create mode 100644 worldmods/bonemeal/license.txt create mode 100644 worldmods/bonemeal/locale/fr.txt create mode 100644 worldmods/bonemeal/locale/template.txt create mode 100644 worldmods/bonemeal/mod.conf create mode 100644 worldmods/bonemeal/mods.lua create mode 100644 worldmods/bonemeal/screenshot.png create mode 100644 worldmods/bonemeal/textures/bonemeal_bone.png create mode 100644 worldmods/bonemeal/textures/bonemeal_fertiliser.png create mode 100644 worldmods/bonemeal/textures/bonemeal_item.png create mode 100644 worldmods/bonemeal/textures/bonemeal_mulch.png create mode 100644 worldmods/bonemeal/textures/bonemeal_particle.png diff --git a/worldmods/bonemeal/README.md b/worldmods/bonemeal/README.md new file mode 100644 index 0000000..ed9e0e9 --- /dev/null +++ b/worldmods/bonemeal/README.md @@ -0,0 +1,26 @@ +Bonemeal mod [bonemeal] + +This mod adds four new items into the game, bones which can be dug from normal +dirt which can be made into bonemeal, mulch which is is crafted using a tree and +8x leaves, and fertiliser which is a mixture of them both. + +Each item can be used on saplings and crops for a chance to grow them quicker as +well as dirt which will generate random grass, flowers or whichever decoration +is registered. + +Mulch has a strength of 1, Bonemeal 2 and Fertiliser 3 which means the stronger +the item, the more chance of growing saplings in low light, making crops sprout +quicker or simply decorate a larger area with grass and flowers. + +The api.txt document shows how to add your own saplings, crops and grasses to +the list by using one of the 3 commands included and the mod.lua file gives you +many examples by using some of the popular mods available. + +https://forum.minetest.net/viewtopic.php?f=9&t=16446 + +Changelog: + +- 0.1 - Initial release +- 0.2 - Added global on_use function for bonemeal growth +- 0.3 - Added strength to on_use global for new items (mulch and fertiliser). +- 0.4 - Added Intllib support and fr.txt file diff --git a/worldmods/bonemeal/api.txt b/worldmods/bonemeal/api.txt new file mode 100644 index 0000000..3140ac5 --- /dev/null +++ b/worldmods/bonemeal/api.txt @@ -0,0 +1,76 @@ + +Bonemeal API +============ + +This guide will show you how to add saplings, crops and dirt types for the +bonemeal mod to use from withhin your own mods. Please make sure that bonemeal +appears in the depends.txt file of your mod so everything work properly. + + +Function Usage +============== + + +Adding Crops +------------ + +bonemeal:add_crop({ nodename_start, growing_steps, seed_name }) + +This command is used to add new crops for bonemeal to work on. + +e.g. + +bonemeal:add_crop({ + {"farming:cotton_", 8, "farming:seed_cotton"}, + {"farming:wheat_", 8, "farming:seed_wheat"}, +}) + + +Adding Saplings +--------------- + +bonemeal:add_sapling({ sapling_node, function, soil_type[sand, dirt, nodename] }) + +This command will add new saplings for bonemeal to grow on sand, soil or a +specified node type. + +bonemeal:add_sapling({ + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "soil"}, + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "sand"}, +}) + + +Adding Dirt Decoration +---------------------- + +bonemeal:add_deco({ dirt_node, {grass_node_list}, {decor_node_list} }) + +This command will add grass and decoration to specific dirt types, use "" to +add an empty node. + +e.g. + +bonemeal:add_deco({"default:dirt_with_dry_grass", {"default:dry_grass_1", ""}, + {"flowers:rose", "flowers:viola"} }) + + +Global ON_USE Function +---------------------- + +bonemeal:on_use(pos, strength) + +This function can be called from other mods to grow plants using alternative +bonemeal items and have the same effect. + + {pos} is the location to apply growing + {strength} is how strong to grow [low of 1 to high of 4] + +Note: Higher strength items require lower light levels, and a strength of 4 +needs no light at all. + + +Final Words +=========== + +I hope this guide helps you add your own plants so you can grow them quickly +with the items included. Please check the mods.lua for more examples. diff --git a/worldmods/bonemeal/depends.txt b/worldmods/bonemeal/depends.txt new file mode 100644 index 0000000..4d286ca --- /dev/null +++ b/worldmods/bonemeal/depends.txt @@ -0,0 +1,6 @@ +default +intllib? +farming? +ethereal? +moretrees? +technic_worldgen? diff --git a/worldmods/bonemeal/description.txt b/worldmods/bonemeal/description.txt new file mode 100644 index 0000000..f85f0a2 --- /dev/null +++ b/worldmods/bonemeal/description.txt @@ -0,0 +1 @@ +Adds bone and bonemeal giving the ability to quickly grow plants and saplings. \ No newline at end of file diff --git a/worldmods/bonemeal/init.lua b/worldmods/bonemeal/init.lua new file mode 100644 index 0000000..92c2f03 --- /dev/null +++ b/worldmods/bonemeal/init.lua @@ -0,0 +1,482 @@ + +bonemeal = {} + +-- Load support for intllib. +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP .. "/intllib.lua") + + +-- default crops +local crops = { + {"farming:cotton_", 8, "farming:seed_cotton"}, + {"farming:wheat_", 8, "farming:seed_wheat"}, +} + + +-- special pine check for nearby snow +local function pine_grow(pos) + + if minetest.find_node_near(pos, 1, + {"default:snow", "default:snowblock", "default:dirt_with_snow"}) then + + default.grow_new_snowy_pine_tree(pos) + else + default.grow_new_pine_tree(pos) + end +end + + +-- default saplings +local saplings = { + {"default:sapling", default.grow_new_apple_tree, "soil"}, + {"default:junglesapling", default.grow_new_jungle_tree, "soil"}, + {"default:acacia_sapling", default.grow_new_acacia_tree, "soil"}, + {"default:aspen_sapling", default.grow_new_aspen_tree, "soil"}, + {"default:pine_sapling", pine_grow, "soil"}, +} + +-- helper tables ( "" denotes a blank item ) +local green_grass = { + "default:grass_2", "default:grass_3", "default:grass_4", + "default:grass_5", "", "" +} + +local dry_grass = { + "default:dry_grass_2", "default:dry_grass_3", "default:dry_grass_4", + "default:dry_grass_5", "", "" +} + +local flowers = { + "flowers:dandelion_white", "flowers:dandelion_yellow", "flowers:geranium", + "flowers:rose", "flowers:tulip", "flowers:viola", "" +} + +-- add additional bakedclay flowers if enabled +if minetest.get_modpath("bakedclay") then + flowers[7] = "bakedclay:delphinium" + flowers[8] = "bakedclay:thistle" + flowers[9] = "bakedclay:lazarus" + flowers[10] = "bakedclay:mannagrass" + flowers[11] = "" +end + +-- default biomes deco +local deco = { + {"default:dirt_with_dry_grass", dry_grass, flowers}, + {"default:sand", {}, {"default:dry_shrub", "", "", ""} }, + {"default:desert_sand", {}, {"default:dry_shrub", "", "", ""} }, + {"default:silver_sand", {}, {"default:dry_shrub", "", "", ""} }, +} + + +----- local functions + + +-- particles +local function particle_effect(pos) + + minetest.add_particlespawner({ + amount = 4, + time = 0.15, + minpos = pos, + maxpos = pos, + minvel = {x = -1, y = 2, z = -1}, + maxvel = {x = 1, y = 4, z = 1}, + minacc = {x = -1, y = -1, z = -1}, + maxacc = {x = 1, y = 1, z = 1}, + minexptime = 1, + maxexptime = 1, + minsize = 1, + maxsize = 3, + texture = "bonemeal_particle.png", + }) +end + + +-- tree type check +local function grow_tree(pos, object) + + if type(object) == "table" and object.axiom then + -- grow L-system tree + minetest.remove_node(pos) + minetest.spawn_tree(pos, object) + + elseif type(object) == "string" and minetest.registered_nodes[object] then + -- place node + minetest.set_node(pos, {name = object}) + + elseif type(object) == "function" then + -- function + object(pos) + end +end + + +-- sapling check +local function check_sapling(pos, nodename) + + -- what is sapling placed on? + local under = minetest.get_node({ + x = pos.x, + y = pos.y - 1, + z = pos.z + }) + + local can_grow, grow_on + + -- check list for sapling and function + for n = 1, #saplings do + + if saplings[n][1] == nodename then + + grow_on = saplings[n][3] + + -- sapling grows on top of specific node + if grow_on + and grow_on ~= "soil" + and grow_on ~= "sand" + and grow_on == under.name then + can_grow = true + end + + -- sapling grows on top of soil (default) + if can_grow == nil + and (grow_on == nil or grow_on == "soil") + and minetest.get_item_group(under.name, "soil") > 0 then + can_grow = true + end + + -- sapling grows on top of sand + if can_grow == nil + and grow_on == "sand" + and minetest.get_item_group(under.name, "sand") > 0 then + can_grow = true + end + + -- check if we can grow sapling + if can_grow then + particle_effect(pos) + grow_tree(pos, saplings[n][2]) + return + end + end + end +end + + +-- crops check +local function check_crops(pos, nodename, strength) + + local stage = "" + + -- grow registered crops + for n = 1, #crops do + + if string.find(nodename, crops[n][1]) + or nodename == crops[n][3] then + + -- get stage number or set to 0 for seed + stage = tonumber( nodename:split("_")[2] ) or 0 + stage = math.min(stage + strength, crops[n][2]) + + minetest.set_node(pos, {name = crops[n][1] .. stage}) + + particle_effect(pos) + + return + + end + + end + +end + + +-- check soil for specific decoration placement +local function check_soil(pos, nodename, strength) + + -- set radius according to strength + local side = strength - 1 + local tall = math.max(strength - 2, 0) + + -- get area of land with free space above + local dirt = minetest.find_nodes_in_area_under_air( + {x = pos.x - side, y = pos.y - tall, z = pos.z - side}, + {x = pos.x + side, y = pos.y + tall, z = pos.z + side}, + {"group:soil", "group:sand"}) + + -- set default grass and decoration + local grass = green_grass + local decor = flowers + + -- choose grass and decoration to use on dirt patch + for n = 1, #deco do + + -- do we have a grass match? + if nodename == deco[n][1] then + grass = deco[n][2] or {} + decor = deco[n][3] or {} + end + end + + local pos2, nod + + -- loop through soil + for _,n in pairs(dirt) do + + pos2 = n + + pos2.y = pos2.y + 1 + + -- place random decoration (rare) + if math.random(1, 5) == 5 then + nod = decor[math.random(1, #decor)] or "" + if nod ~= "" then + minetest.set_node(pos2, {name = nod}) + end + else + -- place random grass (common) + nod = grass[math.random(1, #grass)] or "" + if nod ~= "" then + minetest.set_node(pos2, {name = nod}) + end + end + + particle_effect(pos2) + end +end + + +-- global functions + + +-- add to sapling list +-- {sapling node, schematic or function name, "soil"|"sand"|specific_node} +--e.g. {"default:sapling", default.grow_new_apple_tree, "soil"} + +function bonemeal:add_sapling(list) + + for n = 1, #list do + table.insert(saplings, list[n]) + end +end + + +-- add to crop list to force grow +-- {crop name start_, growth steps, seed node (if required)} +-- e.g. {"farming:wheat_", 8, "farming:seed_wheat"} +function bonemeal:add_crop(list) + + for n = 1, #list do + table.insert(crops, list[n]) + end +end + + +-- add grass and flower/plant decoration for specific dirt types +-- {dirt_node, {grass_nodes}, {flower_nodes} +-- e.g. {"default:dirt_with_dry_grass", dry_grass, flowers} +function bonemeal:add_deco(list) + + for n = 1, #list do + table.insert(deco, list[n]) + end +end + + +-- global on_use function for bonemeal +function bonemeal:on_use(pos, strength) + + -- get node pointed at + local node = minetest.get_node(pos) + + -- return if nothing there + if node.name == "ignore" then + return + end + + -- make sure strength is between 1 and 4 + strength = strength or 2 + strength = math.max(strength, 1) + strength = math.min(strength, 4) + + -- grow grass and flowers + if minetest.get_item_group(node.name, "soil") > 0 + or minetest.get_item_group(node.name, "sand") > 0 then + check_soil(pos, node.name, strength) + return + end + + -- light check depending on strength (strength of 4 = no light needed) + if (minetest.get_node_light(pos) or 0) < (12 - (strength * 3)) then + return + end + + -- check for tree growth if pointing at sapling + if minetest.get_item_group(node.name, "sapling") > 0 + and math.random(1, (5 - strength)) == 1 then + check_sapling(pos, node.name) + return + end + + -- check for crop growth + check_crops(pos, node.name, strength) +end + + +----- items + + +-- mulch (strength 1) +minetest.register_craftitem("bonemeal:mulch", { + description = S("Mulch"), + inventory_image = "bonemeal_mulch.png", + + on_use = function(itemstack, user, pointed_thing) + + -- did we point at a node? + if pointed_thing.type ~= "node" then + return + end + + -- is area protected? + if minetest.is_protected(pointed_thing.under, user:get_player_name()) then + return + end + + -- take item if not in creative + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + + -- call global on_use function with strength of 1 + bonemeal:on_use(pointed_thing.under, 1) + + return itemstack + end, +}) + +-- bonemeal (strength 2) +minetest.register_craftitem("bonemeal:bonemeal", { + description = S("Bone Meal"), + inventory_image = "bonemeal_item.png", + + on_use = function(itemstack, user, pointed_thing) + + -- did we point at a node? + if pointed_thing.type ~= "node" then + return + end + + -- is area protected? + if minetest.is_protected(pointed_thing.under, user:get_player_name()) then + return + end + + -- take item if not in creative + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + + -- call global on_use function with strength of 2 + bonemeal:on_use(pointed_thing.under, 2) + + return itemstack + end, +}) + + +-- fertiliser (strength 3) +minetest.register_craftitem("bonemeal:fertiliser", { + description = S("Fertiliser"), + inventory_image = "bonemeal_fertiliser.png", + + on_use = function(itemstack, user, pointed_thing) + + -- did we point at a node? + if pointed_thing.type ~= "node" then + return + end + + -- is area protected? + if minetest.is_protected(pointed_thing.under, user:get_player_name()) then + return + end + + -- take item if not in creative + if not minetest.setting_getbool("creative_mode") then + itemstack:take_item() + end + + -- call global on_use function with strength of 3 + bonemeal:on_use(pointed_thing.under, 3) + + return itemstack + end, +}) + + +-- bone +minetest.register_craftitem("bonemeal:bone", { + description = S("Bone"), + inventory_image = "bonemeal_bone.png", +}) + + +--- crafting recipes + + +-- bonemeal (from bone) +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:bonemeal 2", + recipe = {"bonemeal:bone"}, +}) + +-- bonemeal (from player bones) +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:bonemeal 4", + recipe = {"bones:bones"}, +}) + +-- mulch +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:mulch 4", + recipe = { + "group:tree", "group:leaves", "group:leaves", + "group:leaves", "group:leaves", "group:leaves", + "group:leaves", "group:leaves", "group:leaves" + }, +}) + +-- fertiliser +minetest.register_craft({ + type = "shapeless", + output = "bonemeal:fertiliser 2", + recipe = {"bonemeal:bonemeal", "bonemeal:mulch"}, +}) + + +-- add bones to dirt +minetest.override_item("default:dirt", { + drop = { + max_items = 1, + items = { + { + items = {"bonemeal:bone", "default:dirt"}, + rarity = 30, + }, + { + items = {"default:dirt"}, + } + } + }, +}) + + +-- add support for other mods +dofile(minetest.get_modpath("bonemeal") .. "/mods.lua") + +print (S("[bonemeal] loaded")) diff --git a/worldmods/bonemeal/intllib.lua b/worldmods/bonemeal/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/worldmods/bonemeal/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/worldmods/bonemeal/license.txt b/worldmods/bonemeal/license.txt new file mode 100644 index 0000000..fec6f6a --- /dev/null +++ b/worldmods/bonemeal/license.txt @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 TenPlus1 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/worldmods/bonemeal/locale/fr.txt b/worldmods/bonemeal/locale/fr.txt new file mode 100644 index 0000000..874b106 --- /dev/null +++ b/worldmods/bonemeal/locale/fr.txt @@ -0,0 +1,7 @@ +# init.lua + +Mulch = Paillis +Bone Meal = Poudre d'os +Fertiliser = Engrais +Bone = Os +[bonemeal] loaded = [bonemeal] chargé diff --git a/worldmods/bonemeal/locale/template.txt b/worldmods/bonemeal/locale/template.txt new file mode 100644 index 0000000..f4023ac --- /dev/null +++ b/worldmods/bonemeal/locale/template.txt @@ -0,0 +1,7 @@ +# init.lua + +Mulch = +Bone Meal = +Fertiliser = +Bone = +[bonemeal] loaded = diff --git a/worldmods/bonemeal/mod.conf b/worldmods/bonemeal/mod.conf new file mode 100644 index 0000000..fec08dc --- /dev/null +++ b/worldmods/bonemeal/mod.conf @@ -0,0 +1 @@ +name = bonemeal \ No newline at end of file diff --git a/worldmods/bonemeal/mods.lua b/worldmods/bonemeal/mods.lua new file mode 100644 index 0000000..4accbe6 --- /dev/null +++ b/worldmods/bonemeal/mods.lua @@ -0,0 +1,116 @@ + + +-- craft bones from animalmaterials into bonemeal +if minetest.get_modpath("animalmaterials") then + + minetest.register_craft({ + type = "shapeless", + output = "bonemeal:bonemeal 2", + recipe = {"animalmaterials:bone"}, + }) +end + + +if farming and farming.mod and farming.mod == "redo" then + + bonemeal:add_crop({ + {"farming:tomato_", 8}, + {"farming:corn_", 8}, + {"farming:melon_", 8}, + {"farming:pumpkin_", 8}, + {"farming:beanpole_", 5}, + {"farming:blueberry_", 4}, + {"farming:raspberry_", 4}, + {"farming:carrot_", 8}, + {"farming:cocoa_", 3}, + {"farming:coffee_", 5}, + {"farming:cucumber_", 4}, + {"farming:potato_", 4}, + {"farming:grapes_", 8}, + {"farming:rhubarb_", 3}, + {"farming:barley_", 7}, + {"farming:hemp_", 8}, + }) +end + + +if minetest.get_modpath("ethereal") then + + bonemeal:add_crop({ + {"ethereal:strawberry_", 8}, + {"ethereal:onion_", 5}, + }) + + bonemeal:add_sapling({ + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "soil"}, + {"ethereal:palm_sapling", ethereal.grow_palm_tree, "sand"}, + {"ethereal:yellow_tree_sapling", ethereal.grow_yellow_tree, "soil"}, + {"ethereal:big_tree_sapling", ethereal.grow_big_tree, "soil"}, + {"ethereal:banana_tree_sapling", ethereal.grow_banana_tree, "soil"}, + {"ethereal:frost_tree_sapling", ethereal.grow_frost_tree, "soil"}, + {"ethereal:mushroom_sapling", ethereal.grow_mushroom_tree, "soil"}, + {"ethereal:willow_sapling", ethereal.grow_willow_tree, "soil"}, + {"ethereal:redwood_sapling", ethereal.grow_redwood_tree, "soil"}, + {"ethereal:orange_tree_sapling", ethereal.grow_orange_tree, "soil"}, + {"ethereal:bamboo_sprout", ethereal.grow_bamboo_tree, "soil"}, + {"ethereal:birch_sapling", ethereal.grow_birch_tree, "soil"}, + }) + + local grass = {"default:grass_3", "default:grass_4", "default:grass_5", ""} + + bonemeal:add_deco({ + {"ethereal:crystal_dirt", {"ethereal:crystalgrass", "", "", "", ""}, {}}, + {"ethereal:fiery_dirt", {"ethereal:dry_shrub", "", "", "", ""}, {}}, + {"ethereal:prairie_dirt", grass, {"flowers:dandelion_white", + "flowers:dandelion_yellow", "flowers:geranium", "flowers:rose", + "flowers:tulip", "flowers:viola", "ethereal:strawberry_7"}}, + {"ethereal:gray_dirt", {}, {"ethereal:snowygrass", "", ""}}, + {"ethereal:cold_dirt", {}, {"ethereal:snowygrass", "", ""}}, + {"ethereal:mushroom_dirt", {}, {"flowers:mushroom_red", "flowers:mushroom_brown", "", "", ""}}, + {"ethereal:jungle_dirt", grass, {"default:junglegrass", "", "", ""}}, + {"ethereal:grove_dirt", grass, {"ethereal:fern", "", "", ""}}, + {"ethereal:bamboo_dirt", grass, {}}, + }) +end + + +if minetest.get_modpath("moretrees") then + + -- special fir check for snow + local function fir_grow(pos) + + if minetest.find_node_near(pos, 1, + {"default:snow", "default:snowblock", "default:dirt_with_snow"}) then + + moretrees.grow_fir_snow(pos) + else + moretrees.grow_fir(pos) + end + end + + bonemeal:add_sapling({ + {"moretrees:beech_sapling", moretrees.spawn_beech_object, "soil"}, + {"moretrees:apple_tree_sapling", moretrees.spawn_apple_tree_object, "soil"}, + {"moretrees:oak_sapling", moretrees.spawn_oak_object, "soil"}, + {"moretrees:sequoia_sapling", moretrees.spawn_sequoia_object, "soil"}, + --{"moretrees:birch_sapling", moretrees.spawn_birch_object, "soil"}, + {"moretrees:birch_sapling", moretrees.grow_birch, "soil"}, + {"moretrees:palm_sapling", moretrees.spawn_palm_object, "soil"}, + {"moretrees:palm_sapling", moretrees.spawn_palm_object, "sand"}, + {"moretrees:date_palm_sapling", moretrees.spawn_date_palm_object, "soil"}, + {"moretrees:date_palm_sapling", moretrees.spawn_date_palm_object, "sand"}, + --{"moretrees:spruce_sapling", moretrees.spawn_spruce_object, "soil"}, + {"moretrees:spruce_sapling", moretrees.grow_spruce, "soil"}, + {"moretrees:cedar_sapling", moretrees.spawn_cedar_object, "soil"}, + {"moretrees:poplar_sapling", moretrees.spawn_poplar_object, "soil"}, + {"moretrees:willow_sapling", moretrees.spawn_willow_object, "soil"}, + {"moretrees:rubber_tree_sapling", moretrees.spawn_rubber_tree_object, "soil"}, + {"moretrees:fir_sapling", fir_grow, "soil"}, + }) + +elseif minetest.get_modpath("technic_worldgen") then + + bonemeal:add_sapling({ + {"moretrees:rubber_tree_sapling", technic.rubber_tree_model, "soil"}, + }) +end diff --git a/worldmods/bonemeal/screenshot.png b/worldmods/bonemeal/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..c4b9fa718333f8a3d2d64c35b96daf21553cc365 GIT binary patch literal 15254 zcmWk#cTkg06HbNDLy=xyLa0&%=~7-HXh4vTB1MFN6hVogA}yf?X#o+DrXs!fqEe*< z>0OF|7?7f(2nd4wKEIi}xtW{UKW_J)-P?Wk;w&y-WMdX&hCm=}#(10+1Olc0n~Es- zzn!Nq>yQ2|9TuiGMnbGeEFXugAghufN*N=dEqTgNUI<~xpsysOq$Z)FW?-ShZl}Y? zYQt)KUImZ0^u53tXu_uMD5T<|V&<&K@ql0Zj-s2Z_rsg#B79hbyd07rFdHQpCO-6u z4<_b5ycivRD>dZ4M@&g%R08@O!O;_Lq4Hg&5R6AiVIAS4a-f`$xpcTBsnBM zAMPS)>ti}wvQj$#>l*2r94=h= z8TZ#gXCbLul4zSRPQzbpIb&aCqkkwa{pZj+?WC<; z>kc<=)cxZt>!MhDqIX54zcZZSZBIGdwZ`U8cc*_gzYGc|??qRd_YRvkv$JZ~uZ_%Y zlm0e0zh*w!9t0Ww;{rs*eB0Ek}+Oh)laO6MITQt=}bOwP(pZJhiPk2E+ zM3FM)HamXdV^s54=@o|l{>s_$4Jq`EqHx zer8*6Zf>@`DHA;T<+sjXau_5eJo4tL_dp8^?WVHFr322fN9zKg3nZ3rjghxRYM+vdhHN#LuAG^pNeD zmIr+k_CJr8p!Dyyl7tPxSeEyn8mM*Pul` zvD!An+*bd+0w`+Iei76Q*Hfmt`v5|G)Y!uF8S|iG#8y0%pX;q*79W!MdlUSwJF*0) z%`xF-uJYN+a5-KvgKT6uy*|fAjr~kg<@$-Ny~TvfJrN*X&7u6Zo&R<(7)H;l#dtoY zZwEnV-}(b)Tq^B%A+xH`*@L+NuZtCz2Y+Yd?-&`;(?C(d-7gM|wT>&yc>i*$PCZ&_&QT*gzH7ipoD6R4?*%AP2U*E=IPCB{JClmQef{=|`0e|jRg&SB{< z&r-J+r3f$JFNauY{l|;Jp*Uv|N~Tx-t+nO*pEjntqnB|CaVbha!nbdTQ9?36T=jbi zgGK2VYBOOX5q~YsH`-lsTxSerKl`2O5>2`BZGQQ;IOypB2ZTIRk{N5EAQu}Y4IR^s zATs``-`{%t;3*vS-)|JKS+oEy`yT{yuz~4;pj=D)wBTD8*+)^XYxHzI!QC25rAH~Bb2PQ69NPp#a`C(E?}EsDPFf@z;g|K)V%fgP&H>ZgPocVK zuQtlNH?K@1L?j;bx7KPK1*?jA`Rc?tFZXI@Uj@~_Fc6ENhYKjeItwmt@&1{G_S+EZ zk~sC0w}JfG3;r2gD{z9A%3P=jb?j;!MVfjz03++9HoPl-L#A_>f$GIfHKebS98jDI z>WTYoNv}4Dsq=FfrIi;{{%U>N#YrP|@(8U`UWB11wZ zmX5?OZ7Tr5!nD?}JclbaOt`y+>+oMc-r19N-twbA_3M=r&n#%1o}%3ES#)WCx4QdC zku@zO?c5E+d!ZBc=YjqQI-;SriL-&@GW`1ok8ka+FNfVtelQ?(v6!_A`KtBEqTzZt z?ZWfAeIWV2ow8fIv^T-@t>sl&^5pA%V*c$D3p1fVKG7>0Qy*S3_8rELYNqJiOBTi# zyfe8g%6*UG{1-yG^>=#`dX_v2f6u1Ji}KP}1!AgosxP*CgX=6lM_YP^hf&e3GReVO zi%pOE5-YP8z_4&n&F~bB!~Jg@m9>8fT>$=yF^u7`&m_fBkIdE9T?denpfJ|g~c;K_uzGBr{$!ojPI|)Y;@7xz4A4`-ti4$1J6e1kX-60!}N1ub3U@-+i#$U zC<(!fOdC^Edri07ot%(6EfAHCV1|m<7@{2T(+3uJorTu(L{U5toG!ho3jgH|dh$jk z=^}PmhMtbzlc%;s_We$_eRVRa;EP6y>^|>LS-PY2HP~jr7*JhIa@u(!B! zDd^1?cmy+}uUJ~uCDBj_sJEa27tkc3Fyjvwj>+l@yPk~LMsoF>vl!sUN3DX;c5lP6 zKM^~em*n!mJBbYuZJhu8b!Rn0!RUhKx#iDd)k+yvpw1Z?McUHT``^eRdJ5FvPGl@Q zbc{?He@u2R>sb4)OEUEbUJcE|RDL6B!^DA^FA$ZWU~rvN+j?i2v3r%E1xE{00#S-i zwb_eVLc+AYy#|EJ&C?~{-JzH)mh9J*QTgq(K?}1QIe!~e--{T$4cjx zgt+#~qPdlT`y!-}JFvqar68^(lBz$j(MCZ(Ic2M~n0<=20NMG$Kx&2sUTt*V-m?Pq zPm4COf#u9CWfn~M?FeW~+oLX%>&T~5Vs0bJ1=p@va1f%Phox|1aPmJpG6H$BX2J0H%!5;18RCq?7A}(x8%2OV zK&j^5%kI|u5j|_0lmLppS4=)Ht(t)%c(0<9^_6y>o?)G1dozhOgzWjMGSgjtQhZ3v zBf0&RdXCYirF%~grqM-JbWAT%acV7G1+Mg_3DG-`$TPEf242vl4tbG|iA3Nxg!aDt zTM3ltw$nkrMOefghp4!Ox`fk~TtfQK6+i`auHLm#1h~V2ILAmjBsH6ZCWwd$UFh%f zU|u@9ghK4pY1gad8T3a&;*jxr$W+H9Eox0G+ki1SVG)gXnRqNgI$mSgap0!5HLTvm zkh*#BD_?;hg@iX>VL1M#Re$gW+aU=Wbf1;_#D4xW1MxG%PTl)1hd<+Uk!mF*QyFTQ z&Rgt=57{M5NhC!3J2P80;17Lv1n->KUYmR(2OD22GX;Lxfh4mg(x|{`hA4F&N~2;Y zgUaYv1fvSSbE=(g+ho!oxFzlk;Koh+vkQi4G0-~rP@B88FN&V8}$mZjZ(6-F;Pp!r1RsGcqKOa z%sv=q3r=tSIqZsM05tr7V$y=#qb9#Z_wn`LY`_!oXQm8XG*V9IYc_NfCui990PN5R zK7NKgko?Yj=+A74gA(8!N8>tahGN&eQeCj*ZY+kgZF_FvyIZUHJG~R{BrUjsUS;k| z%i}RsV|AgH{1efSgEwfu)8J=q1_Su}oV$QBU&Xe@F4&%%}d=BN2Yz`|jUk zth2t-b=UR%MK$#kX4>uLgNpZ!0BCyFIWhSG{^R0lMa+}OcY*@%26`#_T623|ii5_V zr$(bBUOn=2`|7_8i|}(|NH;p4%*S)}tVAViTuW;t3rfeKu){Mj`PKtmvB;Gk``7J0 z3YRs)kLJaeK19ynUgBDD9~0;v*xF)79forWfYTQt&oH3qpnI~hud){#^?E4z*cEcP zz)UL?MJ>O)GT;S$Ip=9eH&YENJ_$S8PtLGa-*NLwq^RP?L68j=TwNe54Cib$1BN|SXu+)8-iN{T(6;)e%ngGQ=?cBdZnsZxdK(q z>O$%9l?;tBna+Y+*954oM(OWUZD4n-|K1G@wT;6-iNRT{8Eh>rf)gf7Wm%UjEiyZt z-q!D-!a%(ZWg1t-;6nu<@*1!*cUU4o8@UYV0FL_0N$$tH-8~DfNvnBq9@y zB*ejk9zIl`=SJ=vm*kx%g*+71g#u}`g#fqnbn%jekDx0LtyYv4$tgF{X_U=$4z(ARg;yCRc&;d!lPy8n#y^y`+i zlZj>pYLx;h#E+5w&WqG7BnIfafi}aN3~=J#P`GmzEYaPyy}p+}Ufmp*Ce{lf2*x?yw=ae8AjXQyyVd|E`|y@--R z%5eofe4kq+Oi{&XqbDfY%(Rd&4}jyh2$tZ+OI6pj=chVYyLCFstvDL%u;TZR-wL_A zK?yGQfz=%4UT;4|i2T}fBUy~Z3U1wRS5pB@uEmNz7F^NY z9Z>71oM?3Y*eUm`AoiIEsLCW@nWN^BbbGH`W}t;pNGWxra34HihZ#K5CF7M#D)&a7 z>t{r~=*AVypSP^)eAmzbTuYO5d&jn*Ct#m{H{R^BEO4n>p?tnCuSK4nt|jynPZ%_O zhZy{;FE0Z2vI7j9Ay8fImXB<-bJFOy;}1!f?Hs`GRlcIzopS0tv^oFUpVn+>adEot z6Y(1vw+R~HsVXoV_Y1LE6`hQ3T)l&0#R zVH)#GAer*6F%}s~gSqRso>;4Lklko;1vIMggG#tSp4RQub84yaNewI z=Bo~TCguf5|2VWhdFn3uyz*P&U~Q4tb`Cw6!5kfL`)9O8M>^B~o+g{h0mQ(pH&s$p zS$5pw<32WQ*m>YV!QMxwA=}?Ciq<;qGQ2lz6iqNuZgx#ji&nEDkP<~0?95DfHmp*o zvrbf6wC15b7{2&%K?A&U@4;$~G?kH+24^JBu+wUJDSC|1d(M-`B@O;ZB|Zz`oKo}> zXM+nmvLm{S0~35O8_8pDg_-{%K6&mQf z7{vHrhb)=ul&x3h&3GugPd@jfgaH_mmQ}2tV&Ns=aWOD-5%ok@+qE_VOu z@2?wuq^}pQ7k&QA0|^>E7auUyJZ~BPS+j*3_VTDqR{y@!QQS2k@?1jf`Y+wLcSTY2 z_S*Q6wKqT0p3Bm*um^9`a=*FXMuW8WCvQnnRYJ5#B!P}3Bqkrm9YK9hYeMXh3VD-Z#Jy!5 zGe+t`$L%6F=11?CcU=Cvs!q2~H(S-6!3!JwCkPInONbY_s|{23lVvCUaJwWg>ecL} zsv86A+YHVYYuZlGngi#A zDa$n)x8kU2x=O^+#Eb5ueG?nIUSC)Up$5QTK8Q*&oEWYGNO2sArt))i8N*dve_=+r zwVfoTrW4th?r-@yT^Z9_xB}m~;{n9#TG+o{$>Wfvj>(i|;%jxx3bm;P)87xRct4t) z^LtR1rEQb3#6YD_f~KM`3>3B2FY_|Ei#cMT5^&c+fuT3**z0{4I^d|^>3Tw+|FlR@ zC7E&ZJ~(oDG6O6uAgtJzhawRbUYS72<$V6U?3pC+>sJ#w=%&cf3vP+HVv>}IO94#*ju{rIqV?S2+IVz-s^pw-tVyRWRYTe&{xZL#dxRz2{1M zCz#(00)IHCiE|%52N7@G&BYzZkg`qOo~eHnNJRn3>eP!l(A%fyb_xsI&EC$RsQhgE z?kjrVSBV3w5!-;nk?LQ_&%^Bxp+7@@#VvPSFAXviN{_r<+ zoXPR~N3-KgXm>xkgJaH?!7Y+%!{+ID%^N$1MuVxavZI-BGl_iaJm zXJ3*ftO}lA&K=*cf>}))<1Yg4mw@k|S!tVraRKmJZ6@m5+*l22y^bVxMFFaHlK)oK zZU{94?Y9JiUSAa}t34S5H`|)oDT&e$`7?2trPneit)R(uph4$BKj zK^o>SvU+!5J2cWAPJ4M_uG&=vL!+pl4}?HLWCt4|dKJIfR;~V+q8bhe@TCM;E`!Yf zw5Jb^~aGXwlYCHG6l`S3w1K=K)`8{nh8%W$hauzHtp z>T6y4xe3e(y*1>Fz-Nw$Tc7Ql^_RECo-LUm*L8Psj1LeOTa$;r8M}l95e7k_DS}{!wE3+ zNm3Q~EH(re*;;c8N@$f-93QUdjG^%O^f67s?f*U|(La)C8Vnw;GrC^**t7@j?7%aM zb@ub{$Kd$HaSCqJdSsikLfbdrwo)_R4G8$9aN zZ~J{&5MuVsR&M@;NY4yItphE+gdQhwXbaX}fe}Oh9&PG?f{{Oa<8UXJ76k`n(tbf} zN4eT!C}?0Obadgl5PoV=m3mJGf-bjEbSjR&?q1hi)cxmIWVd9Duok(xqejM@IUk;? z2=4qFeZQbD-OP076SN%4_0I{itudg7q*a{Pzz?x?c7D_I2&?H4yXR1v1f;g&xFm4( z<2WS;DJJ_YHFcRNOoPE{-d=y_whOarNCJuaz^VhnN)C|sNmZ0no|OZTopnxG=~7jU zR=_8`1MrTp2&GsiEUh1lI^?%p)6Iq9z2L^yDc2YL1gNI>D6rW^hyi!PMR;7Er>1^f zlqz(?hS&1mkIJ_mtZ|61_f$T;c?CC)v0=2*x~2$pl-5a0!?=uog)^f+-`^q;W{1lI zs374>KjLC;l^IYfp!8Jx{~(jiBGJDfTu;h{P$G>U0E_Q3A9B4NfmxI%-{PG4>HE(P z48#P|GWf{ARNWqI3`#G&7B&V+%>yaiFQE3>JQRWQE0uS`tN^9Tn)e;zLcG+Ae(9&> zWvI;7l9p&x=pG$hsqiomd?5Ct**Z^4^25nsbP@M)kngr@i=&`q;!f0 z8s8buXTNb&LW(+^CI352MAfDjTRs(hlm@r2z@op4?!&lp`0*!J z{|8V&&JzJp1scV4(S%H}?Q6>1wy}v^WX<=)drV21X;S0kYjvp?d={a2v*_$15{I(^#oZZ!KCkk0FyHn|XV7{126jRx zIo|`iKTEP1f)JIr*%9Y0|EOu8M~pOrtT%BIsh2SChf?jAneirEovf&!mV?gpif3SR zNA;?;S1`aA$BoZ}ieuizN_eqhFXCQ_P%|4wzc<4pd>HZ|wYw|#Dxfa|Xaba(M@DfF zSu9m^*C(%hBltdGcdBE4dXu8O5jrlAnP#TtE8V3R9&#|GR^U5D?FcPNDJiZir z^5?!^=Ur4(XeM0t%eeILx%u5Xc)vLV;SCKybFuTfdZbLUPQh>d!ibP4rmhO;n0L%p znKQw;Hg39qpt7xB3@s!uBvje30g)SJ=3~465n=@a>KDqmsasNjaey$@4of{K$m!jI zbWO?TUdPUl+PIlL#iBnN2H$`fH=*&bC0V=W9GRnD`9QHd@Kl?y?H+&db@Lm_Pk+96 zb+e{dps4NoP$Y_trY`v^JC&ll3gUl=bG5Kity9#2kHl3)n z{Oc>`6H;0t(ts7OC;6MiJNWi+AI*`xPTun5kr=zxM=Ao zPD1MWXGo*rwd|ncFoZCL#Q!z5i=RBjjBO|Qrt-X<{f^yOI+~AHB@GO<;`sV$(0%Ph#3CHJ1 z7~UK5OpBCeX7t0oi#+_3+A~yS87S%%4 ze)Ednl%JllSvqqP3V{el|GyW&U#>Q_X!e=rGD!UX`#US(B@Ga|Pff}QY`wL5i+W0lZqeK9wOh7ehR(et@LY&S>~y$xM)n7tqi%k zdrFAGsu5aS%rkxEr&nv*5Mn0-j(KwWC=xoW98_#EYP`S=9h-?6dt}K>(8RtHNln8r zS_Qd$(r3ZD>lHH7czq-pqIjTVmLHYbjP%}ExOd7>jij0SOFnm#S!0iF8KN}1#Vzc^ zY-eZ>OL%n_z_(HiTcklbpf-wS^?YUcrJJ09mpJ*BfGLtNaBk=em}F^RzG4Cs@CGvi zrOh`?X>WDW&sSCosgn1N4Sk@WK*h1w&Wp4U{oi?38obxr?VjrI!k(%{pY@)7NJAS*`UR*7t2?-QJ7f# zy#JPjxD$yKXtl~K838fYLa$uh0PzYrH3CxM8Vb{Es{s{cn)}9NLNjSSKH%{MZr{Hl zhD^7ueQ!rH`G>_FVyXTyS0BW~EGOiyb!kW*!B27F<)R{oEbKv(RHiLf`fs0A?@!=b zOLMbC!1<9H(4=p;aZOS#I6ez}>7fw!m7?Sl7z=ZptLudP~q@>7!E>m>asuxw$^chUIm z3Kmm}U!?9F?({%Xy}@StpNs#=@p%QFN+{nEe#Ds5Cz$$-(cOk?CeR{VvwdXGRbmMg`_ZlwdHUrv*`g`FD)KH=c9%OKcOx3x zRfk#qC$7*8$@_4JQ%enfllbT7x(8JDO0+&T!PGv*)0|++T)DwptIh)XR6wkBh^+9Y z6u*7RKoIrj4JqCzKGY&N8)Wa`1uMv+-e0X1 zq~cT2PsW)~QEj=jSKhsJ$0dET{DZ;=sd7N0?80i7WG#X6+DBTw5PbTC7tv#Cqy0K7 z&>|}?2VH_u+PdppIb&WTYTp|Q3uKsh@L6|OnjK8G zx&7^_b0g0{4<}NwT2oNh1B%UdHXr0A_(A#&{O65Pi^Wj^d|_#e2`i(b_$f{pLCtMH zq?1fJkaUwK%A-R$0}P&=LaGqJ9a~L}k8&b3qf5YH99dKM=8UOvbwl9vaN$e1SqOzWHA+)f%uaCDrYBOJM{SuZ+W5Y_H@24iyb-dtMeNp^h4C29uxi<+T zv9$5AP;RR9y>da6(|@Dkg)H0@%0lcr%}O}elZWD@ql!iJ+S#9$9v84rSpg|*QK9nth;jI5^C143i+hT4 zzNzNP`V}Oq$?N<|ErS3h&jzW#V+|=$w|@b8+#)eI-Z6pw zBMH@QB0U>&5#x`+1G#{;!%VJ-5a?fG%N-G26ES775LG>2sc$zrqfKIZx9BW*Uo9M( zGC2oh@|@^mW}`h-P+sGqvBE4nW1Y%ZG3@pWk0k9UBD?v*7Y@ zwrF)q@rR2Rge$?L32$K2hSrlVorAtwm>ulJu`~Q(^Vg}1imUXCOLg~P*wQ)>hyE_vdRYyF)uV}Ys8RQphuS# z#hIcMU07$ugiQmR%j*$&1(!dNHbH}TYn~hpx7FMA5ZVI}6%xpw5;kdym797Xc3hI7 zgq(Yn)JiAE;R9#uer^0d`pf_jg{0J1pp0F#%6cJJ~jjVZQ(MJ`I*oVZBl>1GZU#{pCj zW)A|bg6ArebL79ZHdEgPDa5v^p>yySEZBPwnfN)!uR&5?`2xx$&uznj)l$n%<&k#` zR%d|B9@#rUi45ual(wDsx*|PBg^#Febl$?IXglKC4BMDJ8!m)|bE0TU(v91;EIeU( zF}kRX&#_knGnEf_+zX+W7YOoX3gXz+PT!IFAGmH(CRarqg^^MCAmKSdtG5wHW0nUn z9Dv^N^kQ&=t1LVBb|49s_$NjK0wpn9mjL30?n%0$CJDs?w6A9Nn6Wn@pFAvQC z_A+8w+g|iE9MHWOWx(KqFTUu@kks#66-}v6NvS@sAX4wal*oi*nSLJN2FykE;`7D9 zj3{|Rdi?izH7SYtErrSQ$!R_J&$m=XnJGh&3tRWfE99oLH=ML_diKo~n#a=ddAp>M2CsX<1q-NeNwN(I?~o#?;bLYW%@4DGGzek@y8qe}xbzaWQQ9MJ$5eiE+5zD8b!^HE*yWQNCnZ>8qopfk)`!qSseB|3L=`!6T_RMp0N* zTQP2)6PBIWLR5Re_`H*N$KaMM#Q8yr!F@~3O z%fwlum;MDh8^KSViJH%y#a6(JghXEFJp!eGC^X$P6Y!k1-E4OyQMaQ1 zo8Z*V%yJsf?g9f>1}>xZnrJ3PxLkrCeR!d`>K5?lbO5=+#J=EG(kNU0ZOFzs@(YRb zArCz8P%{FitcW;kE%A+~c{&m*Iqt)g0xfJXQSj1W7lQZKgRJf zP)$7aHVipkK!SEm$N3BW&?sj*(Ztb9_E(cByhrWnWh?^x<3g~V7RZ{OJYgpYaX)jt zuJJpKb7EkeVv~HTaaH=`rv~zRmBnhq3wk|1AG6!v12dp{iQmaMroxX-_pXNuBG-+sn;wz=Gp(aN*xM~giIe{KDjrWq3(x~o4* zai6_a{!wem?SzLCRP>DfU*$8S56s=nG5wvo94j>Ul=!TJD|xOqC`+`b^%s^23V(VV zb&4fEEzRYp@SQzswZCV|1SI8D;c!4pp-q=_vE-6H9v*iUqY@a4cD}xT6 zg$i8cqjoW2r^usR&QE*28MqE10@|bp`2z~}uXxKa$Z~wnxPd}86d}2io&tW*bR>(Nhtn$R{kYd>344yEuE4K1v&IIeVX#Hl*Mw_7OK2^sBJn@q*W2`U@NH z>JaU#|$yb9Tc#93)*DDjA` ze*Q9u_P^Y`{4dwECe2-($o}SlW@1L)=QFzC%;5mDZ0YOKeAH`ja|$;0O7)%YYT?{& zCQgRYHr+9OUVvhp&yM=md6lu&;ZTMiS%oYibqv}RQ1*|ka8|MgxbV}A7&bPA8?5jA zUvmD0aJhmQRQJ`R8;}~x?px9e43}CQzT1d?`neKQR$P=QPSXVv#a>NK-Yn<4ERolq zCJ6HKprpr{@gs12F`UT~L$7AT9i=}65=|~e$%LRrnU!Q0)h=`0G$HNBOg^9b z6=Jkr3WXhaXs-Q^ zA0t+UgezVP;O=K=&5gaL_kgpLG|1ph^{$iNyr;84Kogr1p!W692#zRQ%V2*WjiE*{ zXnq9+=Q54`A#U}sA5Tj7jY*^fX00T7gE3#hGVa?h;^e^vJKbKA=GK@}+pO7RPG#k< zNW_eNO%)|dD#dFZ+MPWS$XP?G{`swc^#OjLkOITNr*5vujJR5r%Dlg{wII)puR2G? zLvMIp7ebwJ@Gq|dx{VNw;}baCdkRO&oiFFHXZo^|f8bh3kFQB|l~xq1e`$Bpy5Y4D z&s*-7#KrX26fZ$t=Y?XH^d^PPZ45eQvf9}Qr}*q}I7A9gT%Di)+=@uDjQ}+Qi2hJYac1n?yF%I zRt9RGePIv2@mApx2zll&u`=EJe&bZ^=XCJljnjax@OcF)jUi7f*yH7;*2pD%Hx!!& zKUJ)`n0a+6=^YAZm=7^zH25zjMGXB}mh!}hbVriN4ir+l*?R~)uP5gRs>`p#OW|X2 zgY*sr%ae5&xDGP%QeVKhcHE<+(AgIy(1&n-v|49nC_9o%d+>EK1yx|ng8c#El4dI- z`U7>()Xx}^VFG>10vdib!3 zg@@n4DEPF3tb{KKFK%(R&)OHRB_;M4ov%7nD%Ysb#%M4pG?GYG<`(Q4h{`^1APmx! zE-L82pbk*Sd(hS=_0?j8$T!vwkl!zbbjz zvvc~>J$Rm?oMjtcC7$5&-+_#v(3ko7<*Pue2d8}y_l;!6=`TZ&vGY-$ebTWM$5N}O zB_}Z!Q%#!k6i96b6X38}NqS_|A;AFR)M6jlV{84)0Nco?FcF15o=Vvdci@?VoN-^} zGPF52I!6rO*}vY;W4fmX9=H_y3Q46j4l0&gUgbgAD|M}zocVkPN0#|AEQWGYgQ+BI zh@F2!Ce<%p_!lo(J;$xQqN#X@RXgJq;o5;aISrI4;-!WuW0#rHN2e^5Esj_kb;w-e zu<;i)!r&igP_F7bKLGbVUt+;}2mErJ;LFKm$tj?U_Wu^g_4OV*AkmVRFm*6|0k}C~ zf#x4v-$B@Yc@ZLiSNFBMf$K780?agk52d01`l=W(Pmi87$bXN2d&+`Md6KNd4+pWF zFAuXpX2z7ZukJ`Xi(?iYfnf}*eQ|2`U+>B}HnLVFay%A%sDz5Lvob$l=X>+Rw%hw_ z2~=Pw@TNS2tzI{jvG%#vaXIJj+Yv6u?hC(GUq1V8Y%&wi4@Qs?t`Nvxb(iIOERoQY z|Lu8RKgRM_#~bK|S1Z)$$3*$e)2$-%o@yUvxPv}*na2?HO@z&61t)ley%)s9snstd zp6TSq-J0&^qH3zJnO7w@fk}Yaho%3x*i7DYg7Taj5*U@nkIzKqFn4xL8leD}o8RqK z)m#4hKDPomH}^fDC8FUqB-|P?p$SHS;1KrGDmmUz{;LVd3vQbjE>J-0gP)RRbdpPJ z?2jMy>mk{Fn5FotQ{lFNZnI)HzkRUpe1P`4gSbDO6GdQ-qw{j2unl$6y}eDXc3?!> z?Zz8k@*AB<+BBOIynFZKQRocw2K&9xWlZX``Fb`6I}-ls+2K2!&!!&OdHdK%XmWYm zjVKTEP$Ays2Nkd}JAB!V9E=3ne2G=iJ!)o+E!_;PH%^Z0kqGF<>3-2P*F;xaHhg#? z4!NAJB}I_1QtK}NtN8GQFZ`1xU`hJ+uq!xL(mgX9AuTmrA+g^4^=XNa&=^J?P2z*n{Mw7aJ(p#0@6jchtd zuH8I;=1T&+Zu8XN5z{cM96k+9v5yN>IlEpP&}cdn>Y1K#aw6^79w}&J{Pj_NGMNRx zV211B7X(D3u@e^2t|7{AE=2JM)>ysID6SA`lM;<__e5fMk;JWZ;klDzmU{gyNhy>g z=$I4^PjT_)_J5$>`UHw~LB9Ai*wVsyVEK>Eyd;DwXD1!DG(qykJ{wyTbnam6imMzw zWF+Q>P9GHQv6bB9z8hLTkjLl@vkHpx13KrSd4t;JA2%8jdk!G>{)09{FGqk(6RNW27LehuCxG^GmIxsIXxwToxpV=xB^U#CnG5#? zpw$~*ztQKP=QR0r{kVd(D@gkA`W!VF{cJH$65}SFLf{}(kEfd7_>dWEerdwL!XB4X z{*-|WXNDQS8>GSR#{w!ya z77~}{G(ylD+{^iSo`v-^`bi^m-dQF*+O)9^tT$=oOGk&Fj*zQhV2qXh@$-YgpWjy{ zOF zwg!rB>Y;WkJq4(=y_!Lq{8{aNWa#rZzeO)!jjDg0m!>5mvJj#jBrFL8f`59Ys(0$z zxLg}2AX+9jMUdEPyPfl*e$b5;@@_U*KJ~Z;jz4H5)sNX1iF17d^O`yF>%7!zOK=76 z(Xzxv{V^55o0bAW;RCo>R^Zr&?m%SCFn{Hyk*! zb10uk44W6es}A#p#=8Y<~H)Yn)G^hzj;I9`re>cdf-Il#E%#%0f8kV?nI1 zcs7SZ{p;yxN7&^wD@x6O+`R*y`XIjYp;7rOdHCIH-ajevv5S0LnNP28e{#!Vrd;A0 zL{5s1`({n3Gw{x=uUYldJg^#6RT6Ia?_)IJZH*2Za`0BH4W7Br-oZBBVf(k}qn}8H z8a4OtqqDJNW8LZ{yOgC%)2aX)%=JqXfqkO!T;PzNjl3ZfKrSlL4Lsu4$p3+0XdPLE{-7_*L~03=4~+GV7+jgSK%#FlK6rh4b%RnPnz^Y zp=QnjRmLA(n;Rd+^axF^UHEe)e_Qqfuke*y)UGG$CK&ZzUv+ZdP08z7&hZ5dN4BP` g1#x+a{My?f?N!3zopr009U@dH?_b literal 0 HcmV?d00001 diff --git a/worldmods/bonemeal/textures/bonemeal_item.png b/worldmods/bonemeal/textures/bonemeal_item.png new file mode 100644 index 0000000000000000000000000000000000000000..f141263050deb0b33da6e60aa72dc8be63378ebb GIT binary patch literal 186 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!73?$#)eFPHV5AX?bO)b$43CSocZaRDR=BKY8 z9cn*#0;L#Bg8YIR9G=}s19BogT^vI=uKS+5&D&tW!Fu5~ufkiVB=H418m9eCpET)* zLd~25s*FFnHa9+s=@FV-yYS~q{B-6 literal 0 HcmV?d00001 diff --git a/worldmods/bonemeal/textures/bonemeal_particle.png b/worldmods/bonemeal/textures/bonemeal_particle.png new file mode 100644 index 0000000000000000000000000000000000000000..71ef90f8155d14b78236a1bb3ad25e4cdd145f8d GIT binary patch literal 116 zcmeAS@N?(olHy`uVBq!ia0vp^tU%1p#0(_&p3JWWQak}ZA+D*q>9!@d=~vU={e4$t zq)-PGXDkWw3ubV5b|VeQ5%Y9$4B@z*{2(ELLCKV@Z6~jS&>2<+feOa1E{1(xKotz0 Lu6{1-oD!M