Skip to content
Snippets Groups Projects
init.lua 18.8 KiB
Newer Older
tenplus1's avatar
tenplus1 committed
--[[
TenPlus1's avatar
TenPlus1 committed
	Farming Redo Mod 1.25 (6th May 2017)
tenplus1's avatar
tenplus1 committed
	by TenPlus1
tenplus1's avatar
tenplus1 committed
	NEW growing routine by prestidigitator
	auto-refill by crabman77
tenplus1's avatar
tenplus1 committed
]]

farming = {}
farming.mod = "redo"
tenplus1's avatar
tenplus1 committed
farming.path = minetest.get_modpath("farming")
tenplus1's avatar
tenplus1 committed
farming.hoe_on_use = default.hoe_on_use
TenPlus1's avatar
TenPlus1 committed
farming.select = {
	type = "fixed",
	fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5}
}
tenplus1's avatar
tenplus1 committed

tenplus1's avatar
tenplus1 committed

local statistics = dofile(farming.path.."/statistics.lua")
-- Intllib
TenPlus1's avatar
TenPlus1 committed

local S
if minetest.get_modpath("intllib") then
	S = intllib.Getter()
else
	S = function(s) return s end
end
farming.intllib = S
tenplus1's avatar
tenplus1 committed

tenplus1's avatar
tenplus1 committed
-- Utility Functions

local time_speed = tonumber(minetest.setting_get("time_speed")) or 72
local SECS_PER_CYCLE = (time_speed > 0 and 24 * 60 * 60 / time_speed) or 0
tenplus1's avatar
tenplus1 committed

local function clamp(x, min, max)
	return (x < min and min) or (x > max and max) or x
end

local function in_range(x, min, max)
	return min <= x and x <= max
end

--- Tests the amount of day or night time between two times.
 --
 -- @param t_game
 --    The current time, as reported by mintest.get_gametime().
 -- @param t_day
 --    The current time, as reported by mintest.get_timeofday().
 -- @param dt
 --    The amount of elapsed time.
 -- @param count_day
 --    If true, count elapsed day time.  Otherwise, count elapsed night time.
 -- @return
 --    The amount of day or night time that has elapsed.
tenplus1's avatar
tenplus1 committed
local function day_or_night_time(t_game, t_day, dt, count_day)

	local t1_day = t_day - dt / SECS_PER_CYCLE
tenplus1's avatar
tenplus1 committed
	local t1_c, t2_c  -- t1_c < t2_c and t2_c always in [0, 1)
tenplus1's avatar
tenplus1 committed
	if count_day then
tenplus1's avatar
tenplus1 committed
		if t_day < 0.25 then
			t1_c = t1_day + 0.75  -- Relative to sunup, yesterday
			t2_c = t_day  + 0.75
		else
			t1_c = t1_day - 0.25  -- Relative to sunup, today
			t2_c = t_day  - 0.25
		end
	else
		if t_day < 0.75 then
			t1_c = t1_day + 0.25  -- Relative to sundown, yesterday
			t2_c = t_day  + 0.25
		else
			t1_c = t1_day - 0.75  -- Relative to sundown, today
			t2_c = t_day  - 0.75
		end
	end

	local dt_c = clamp(t2_c, 0, 0.5) - clamp(t1_c, 0, 0.5)  -- this cycle
tenplus1's avatar
tenplus1 committed
	if t1_c < -0.5 then
		local nc = math.floor(-t1_c)
		t1_c = t1_c + nc
		dt_c = dt_c + 0.5 * nc + clamp(-t1_c - 0.5, 0, 0.5)
	end

	return dt_c * SECS_PER_CYCLE
end

--- Tests the amount of elapsed day time.
 --
 -- @param dt
 --    The amount of elapsed time.
 -- @return
 --    The amount of day time that has elapsed.
 --
local function day_time(dt)
	return day_or_night_time(minetest.get_gametime(), minetest.get_timeofday(), dt, true)
end

--- Tests the amount of elapsed night time.
 --
 -- @param dt
 --    The amount of elapsed time.
 -- @return
 --    The amount of night time that has elapsed.
 --
local function night_time(time_game, time_day, dt, count_day)
	return day_or_night_time(minetest.get_gametime(), minetest.get_timeofday(), dt, false)
end


-- Growth Logic

local STAGE_LENGTH_AVG = 160.0
local STAGE_LENGTH_DEV = STAGE_LENGTH_AVG / 6
local MIN_LIGHT = 13
local MAX_LIGHT = 1000

--- Determines plant name and stage from node.
 --
 -- Separates node name on the last underscore (_).
 --
 -- @param node
 --    Node or position table, or node name.
 -- @return
 --    List (plant_name, stage), or nothing (nil) if node isn't loaded
tenplus1's avatar
tenplus1 committed
local function plant_name_stage(node)
tenplus1's avatar
tenplus1 committed
	local name
	if type(node) == "table" then
tenplus1's avatar
tenplus1 committed
		if node.name then
			name = node.name
tenplus1's avatar
tenplus1 committed
		elseif node.x and node.y and node.z then
			node = minetest.get_node_or_nil(node)
			name = node and node.name
		end
	else
		name = tostring(node)
	end
	if not name or name == "ignore" then
		return nil
	end
tenplus1's avatar
tenplus1 committed

	local sep_pos = name:find("_[^_]+$")
tenplus1's avatar
tenplus1 committed
	if sep_pos and sep_pos > 1 then
tenplus1's avatar
tenplus1 committed
		local stage = tonumber(name:sub(sep_pos + 1))
tenplus1's avatar
tenplus1 committed
		if stage and stage >= 0 then
			return name:sub(1, sep_pos - 1), stage
		end
	end

	return name, 0
end

-- Map from node name to
-- { plant_name = ..., name = ..., stage = n, stages_left = { node_name, ... } }

tenplus1's avatar
tenplus1 committed
local plant_stages = {}
tenplus1's avatar
tenplus1 committed
farming.plant_stages = plant_stages

--- Registers the stages of growth of a (possible plant) node.
 --
 -- @param node
 --    Node or position table, or node name.
 -- @return
 --    The (possibly zero) number of stages of growth the plant will go through
 --    before being fully grown, or nil if not a plant.
tenplus1's avatar
tenplus1 committed
local register_plant_node
tenplus1's avatar
tenplus1 committed
-- Recursive helper
local function reg_plant_stages(plant_name, stage, force_last)
tenplus1's avatar
tenplus1 committed
	local node_name = plant_name and plant_name .. "_" .. stage
	local node_def = node_name and minetest.registered_nodes[node_name]
	if not node_def then
		return nil
	end
tenplus1's avatar
tenplus1 committed

	local stages = plant_stages[node_name]
	if stages then
		return stages
	end
tenplus1's avatar
tenplus1 committed

	if minetest.get_item_group(node_name, "growing") > 0 then

		local ns = reg_plant_stages(plant_name, stage + 1, true)
tenplus1's avatar
tenplus1 committed
		local stages_left = (ns and { ns.name, unpack(ns.stages_left) }) or {}
TenPlus1's avatar
TenPlus1 committed
		stages = {
			plant_name = plant_name,
			name = node_name,
			stage = stage,
			stages_left = stages_left
		}
tenplus1's avatar
tenplus1 committed

		if #stages_left > 0 then
tenplus1's avatar
tenplus1 committed
			local old_constr = node_def.on_construct
			local old_destr  = node_def.on_destruct
tenplus1's avatar
tenplus1 committed
			minetest.override_item(node_name,
				{
					on_construct = function(pos)

						if old_constr then
							old_constr(pos)
						end

tenplus1's avatar
tenplus1 committed
						farming.handle_growth(pos)
					end,

					on_destruct = function(pos)
tenplus1's avatar
tenplus1 committed
						minetest.get_node_timer(pos):stop()

						if old_destr then
							old_destr(pos)
						end
tenplus1's avatar
tenplus1 committed
					end,

					on_timer = function(pos, elapsed)
						return farming.plant_growth_timer(pos, elapsed, node_name)
					end,
				})
		end
tenplus1's avatar
tenplus1 committed
	elseif force_last then
TenPlus1's avatar
TenPlus1 committed
		stages = {
			plant_name = plant_name,
			name = node_name,
			stage = stage,
			stages_left = {}
		}
tenplus1's avatar
tenplus1 committed
	else
		return nil
	end

	plant_stages[node_name] = stages
tenplus1's avatar
tenplus1 committed
	return stages
end

register_plant_node = function(node)
tenplus1's avatar
tenplus1 committed
	local plant_name, stage = plant_name_stage(node)
tenplus1's avatar
tenplus1 committed
	if plant_name then
tenplus1's avatar
tenplus1 committed
		local stages = reg_plant_stages(plant_name, stage, false)
		return stages and #stages.stages_left
	else
		return nil
	end
end

local function set_growing(pos, stages_left)
	if not stages_left then
		return
	end
tenplus1's avatar
tenplus1 committed

	local timer = minetest.get_node_timer(pos)
tenplus1's avatar
tenplus1 committed
	if stages_left > 0 then
tenplus1's avatar
tenplus1 committed
		if not timer:is_started() then
tenplus1's avatar
tenplus1 committed
			local stage_length = statistics.normal(STAGE_LENGTH_AVG, STAGE_LENGTH_DEV)
tenplus1's avatar
tenplus1 committed
			stage_length = clamp(stage_length, 0.5 * STAGE_LENGTH_AVG, 3.0 * STAGE_LENGTH_AVG)
tenplus1's avatar
tenplus1 committed
			timer:set(stage_length, -0.5 * math.random() * STAGE_LENGTH_AVG)
		end
tenplus1's avatar
tenplus1 committed
	elseif timer:is_started() then
		timer:stop()
	end
end

Milan's avatar
Milan committed
-- https://git.tchncs.de/Illuna-Minetest/farming_plus/blob/master/init.lua#L54

function farming.generate_tree(pos, trunk, leaves, underground, replacements)
	pos.y = pos.y-1
	local nodename = minetest.get_node(pos).name
	local ret = true
	for _,name in ipairs(underground) do
		if nodename == name then
			ret = false
			break
		end
	end
	pos.y = pos.y+1
	if not minetest.get_node_light(pos) then
		return
	end
	if ret or minetest.get_node_light(pos) < 8 then
		return
	end
	
	node = {name = ""}
	for dy=1,4 do
		pos.y = pos.y+dy
		if minetest.get_node(pos).name ~= "air" then
			return
		end
		pos.y = pos.y-dy
	end
	node.name = trunk
	for dy=0,4 do
		pos.y = pos.y+dy
		minetest.set_node(pos, node)
		pos.y = pos.y-dy
	end
	
	if not replacements then
		replacements = {}
	end
	
	node.name = leaves
	pos.y = pos.y+3
	for dx=-2,2 do
		for dz=-2,2 do
			for dy=0,3 do
				pos.x = pos.x+dx
				pos.y = pos.y+dy
				pos.z = pos.z+dz
				
				if dx == 0 and dz == 0 and dy==3 then
					if minetest.get_node(pos).name == "air" and math.random(1, 5) <= 4 then
						minetest.set_node(pos, node)
						for name,rarity in pairs(replacements) do
							if math.random(1, rarity) == 1 then
								minetest.set_node(pos, {name=name})
							end
						end
					end
				elseif dx == 0 and dz == 0 and dy==4 then
					if minetest.get_node(pos).name == "air" and math.random(1, 5) <= 4 then
						minetest.set_node(pos, node)
						for name,rarity in pairs(replacements) do
							if math.random(1, rarity) == 1 then
								minetest.set_node(pos, {name=name})
							end
						end
					end
				elseif math.abs(dx) ~= 2 and math.abs(dz) ~= 2 then
					if minetest.get_node(pos).name == "air" then
						minetest.set_node(pos, node)
						for name,rarity in pairs(replacements) do
							if math.random(1, rarity) == 1 then
								minetest.set_node(pos, {name=name})
							end
						end
					end
				else
					if math.abs(dx) ~= 2 or math.abs(dz) ~= 2 then
						if minetest.get_node(pos).name == "air" and math.random(1, 5) <= 4 then
							minetest.set_node(pos, node)
							for name,rarity in pairs(replacements) do
								if math.random(1, rarity) == 1 then
								minetest.set_node(pos, {name=name})
								end
							end
						end
					end
				end
				
				pos.x = pos.x-dx
				pos.y = pos.y-dy
				pos.z = pos.z-dz
			end
		end
	end
end

-- Detects a plant type node at the given position, starting
-- or stopping the plant growth timer as appopriate

-- @param pos
--    The node's position.
-- @param node
--    The cached node table if available, or nil.
tenplus1's avatar
tenplus1 committed
function farming.handle_growth(pos, node)
	if not pos then
		return
	end
tenplus1's avatar
tenplus1 committed
	local stages_left = register_plant_node(node or pos)
	if stages_left then
		set_growing(pos, stages_left)
	end
minetest.after(0, function()

	for _, node_def in ipairs(minetest.registered_nodes) do
		register_plant_node(node_def)
	end
end)
tenplus1's avatar
tenplus1 committed

local abm_func = farming.handle_growth
tenplus1's avatar
tenplus1 committed
-- Just in case a growing type or added node is missed (also catches existing
-- nodes added to map before timers were incorporated).
minetest.register_abm({
tenplus1's avatar
tenplus1 committed
	nodenames = { "group:growing" },
	interval = 300,
	chance = 1,
	action = abm_func
})
-- Plant timer function.
-- Grows plants under the right conditions.
tenplus1's avatar
tenplus1 committed
function farming.plant_growth_timer(pos, elapsed, node_name)
tenplus1's avatar
tenplus1 committed
	local stages = plant_stages[node_name]
	if not stages then
		return false
	end
tenplus1's avatar
tenplus1 committed

	local max_growth = #stages.stages_left
	if max_growth <= 0 then
		return false
	end
tenplus1's avatar
tenplus1 committed

	if stages.plant_name == "farming:cocoa" then
TenPlus1's avatar
TenPlus1 committed
		if not minetest.find_node_near(pos, 1, {"default:jungletree"}) then
tenplus1's avatar
tenplus1 committed
			return true
		end
	else
		local under = minetest.get_node({ x = pos.x, y = pos.y - 1, z = pos.z })
TenPlus1's avatar
TenPlus1 committed
		if minetest.get_item_group(under.name, "soil") < 3 then
			return true
		end
tenplus1's avatar
tenplus1 committed
	end

	local growth
	local light_pos = {x = pos.x, y = pos.y + 1, z = pos.z}
tenplus1's avatar
tenplus1 committed
	local lambda = elapsed / STAGE_LENGTH_AVG
	if lambda < 0.1 then
		return true
	end
tenplus1's avatar
tenplus1 committed
	if max_growth == 1 or lambda < 2.0 then
		local light = (minetest.get_node_light(light_pos) or 0)
tenplus1's avatar
tenplus1 committed
		--print ("light level:", light)
		if not in_range(light, MIN_LIGHT, MAX_LIGHT) then
			return true
		end
tenplus1's avatar
tenplus1 committed
		growth = 1
	else
		local night_light  = (minetest.get_node_light(light_pos, 0) or 0)
		local day_light    = (minetest.get_node_light(light_pos, 0.5) or 0)
tenplus1's avatar
tenplus1 committed
		local night_growth = in_range(night_light, MIN_LIGHT, MAX_LIGHT)
		local day_growth   = in_range(day_light,   MIN_LIGHT, MAX_LIGHT)

		if not night_growth then

			if not day_growth then
				return true
			end

tenplus1's avatar
tenplus1 committed
			lambda = day_time(elapsed) / STAGE_LENGTH_AVG
tenplus1's avatar
tenplus1 committed
		elseif not day_growth then
tenplus1's avatar
tenplus1 committed
			lambda = night_time(elapsed) / STAGE_LENGTH_AVG
		end

		growth = statistics.poisson(lambda, max_growth)
		if growth < 1 then
			return true
		end
	if minetest.registered_nodes[stages.stages_left[growth]] then
		minetest.swap_node(pos, {name = stages.stages_left[growth]})
tenplus1's avatar
tenplus1 committed

	return growth ~= max_growth
end

-- refill placed plant by crabman (26/08/2015)
local can_refill_plant = {
	["farming:blueberry_1"] = "farming:blueberries",
	["farming:carrot_1"] = "farming:carrot",
	["farming:coffee_1"] = "farming:coffee_beans",
	["farming:corn_1"] =  "farming:corn",
	["farming:cotton_1"] = "farming:seed_cotton",
	["farming:cucumber_1"] = "farming:cucumber",
	["farming:melon_1"] = "farming:melon_slice",
	["farming:potato_1"] = "farming:potato",
	["farming:pumpkin_1"] = "farming:pumpkin_slice",
	["farming:raspberry_1"] = "farming:raspberries",
	["farming:rhubarb_1"] = "farming:rhubarb",
	["farming:tomato_1"] = "farming:tomato",
	["farming:wheat_1"] = "farming:seed_wheat",
	["farming:grapes_1"] = "farming:grapes",
	["farming:beans_1"] = "farming:beans",
	["farming:rhubarb_1"] = "farming:rhubarb",
	["farming:cocoa_1"] = "farming:cocoa_beans",
Milan's avatar
Milan committed
    ["farming:orange_1"] = "farming:orange_item",
	["farming:barley_1"] = "farming:seed_barley",
TenPlus1's avatar
TenPlus1 committed
	["farming:hemp_1"] = "farming:seed_hemp",
}

function farming.refill_plant(player, plantname, index)
	local inv = player:get_inventory()
	local old_stack = inv:get_stack("main", index)
	if old_stack:get_name() ~= "" then
		return
	end
	for i, stack in ipairs(inv:get_list("main")) do
		if stack:get_name() == plantname and i ~= index then
			inv:set_stack("main", index, stack)
			stack:clear()
			inv:set_stack("main", i, stack)
			--minetest.log("action", "farming: refilled stack("..plantname..") of "  .. player:get_player_name()  )
			return
		end
	end
tenplus1's avatar
tenplus1 committed
-- Place Seeds on Soil

function farming.place_seed(itemstack, placer, pointed_thing, plantname)
tenplus1's avatar
tenplus1 committed
	local pt = pointed_thing

	-- check if pointing at a node
TenPlus1's avatar
TenPlus1 committed
	if not pt or pt.type ~= "node" then
tenplus1's avatar
tenplus1 committed
		return
	end

	local under = minetest.get_node(pt.under)

	-- am I right-clicking on something that has a custom on_place set?
	-- thanks to Krock for helping with this issue :)
	local def = minetest.registered_nodes[under.name]
	if def and def.on_rightclick then
		return def.on_rightclick(pt.under, under, placer, itemstack)
	end

tenplus1's avatar
tenplus1 committed
	local above = minetest.get_node(pt.above)


    -- thanks to w_laenger from minetest irc
    -- fixes itemframes compatibility
    if minetest.registered_nodes[under.name].on_rightclick then
        return minetest.registered_nodes[under.name].on_rightclick(pt.under, under, placer, itemstack, pt) 
    end

tenplus1's avatar
tenplus1 committed
	-- check if pointing at the top of the node
TenPlus1's avatar
TenPlus1 committed
	if pt.above.y ~= pt.under.y + 1 then
tenplus1's avatar
tenplus1 committed
		return
	end

	-- return if any of the nodes is not registered
	if not minetest.registered_nodes[under.name]
	or not minetest.registered_nodes[above.name] then
		return
	end

	-- can I replace above node, and am I pointing at soil
	if not minetest.registered_nodes[above.name].buildable_to
	or minetest.get_item_group(under.name, "soil") < 2
TenPlus1's avatar
TenPlus1 committed
	-- avoid multiple seed placement bug
	or minetest.get_item_group(above.name, "plant") ~= 0 then
tenplus1's avatar
tenplus1 committed
		return
	end

TenPlus1's avatar
TenPlus1 committed
	-- if not protected then add node and remove 1 item from the itemstack
	if not minetest.is_protected(pt.above, placer:get_player_name()) then
		minetest.set_node(pt.above, {name = plantname, param2 = 1})
		minetest.sound_play("default_place_node", {pos = pt.above, gain = 1.0})
		if not minetest.setting_getbool("creative_mode") then
			itemstack:take_item()
			-- check for refill
			if itemstack:get_count() == 0
			and can_refill_plant[plantname] then
				minetest.after(0.10,
					farming.refill_plant,
					placer,
					can_refill_plant[plantname],
					placer:get_wield_index()
				)
		return itemstack
tenplus1's avatar
tenplus1 committed
	end
end

TenPlus1's avatar
TenPlus1 committed
-- Function to register plants (default farming compatibility)
tenplus1's avatar
tenplus1 committed

farming.register_plant = function(name, def)
tenplus1's avatar
tenplus1 committed
	local mname = name:split(":")[1]
	local pname = name:split(":")[2]

	-- Check def table
	if not def.description then
		def.description = S("Seed")
tenplus1's avatar
tenplus1 committed
	end
tenplus1's avatar
tenplus1 committed
	if not def.inventory_image then
		def.inventory_image = "unknown_item.png"
	end
tenplus1's avatar
tenplus1 committed
	if not def.steps then
		return nil
	end

	-- Register seed
	minetest.register_node(":" .. mname .. ":seed_" .. pname, {
tenplus1's avatar
tenplus1 committed
		description = def.description,
		tiles = {def.inventory_image},
		inventory_image = def.inventory_image,
		wield_image = def.inventory_image,
		drawtype = "signlike",
		groups = {seed = 1, snappy = 3, attached_node = 1},
		paramtype = "light",
		paramtype2 = "wallmounted",
		walkable = false,
		sunlight_propagates = true,
TenPlus1's avatar
TenPlus1 committed
		selection_box = farming.select,
tenplus1's avatar
tenplus1 committed
		on_place = function(itemstack, placer, pointed_thing)
			return farming.place_seed(itemstack, placer,
				pointed_thing, mname .. ":" .. pname .. "_1")
		end,
tenplus1's avatar
tenplus1 committed
	})

	-- Register harvest
	minetest.register_craftitem(":" .. mname .. ":" .. pname, {
		description = pname:gsub("^%l", string.upper),
		inventory_image = mname .. "_" .. pname .. ".png",
	})

	-- Register growing steps
TenPlus1's avatar
TenPlus1 committed
	for i = 1, def.steps do
		local base_rarity = 1
		if def.steps ~= 1 then
			base_rarity =  8 - (i - 1) * 7 / (def.steps - 1)
		end
tenplus1's avatar
tenplus1 committed
		local drop = {
			items = {
				{items = {mname .. ":" .. pname}, rarity = base_rarity},
				{items = {mname .. ":" .. pname}, rarity = base_rarity * 2},
				{items = {mname .. ":seed_" .. pname}, rarity = base_rarity},
				{items = {mname .. ":seed_" .. pname}, rarity = base_rarity * 2},
tenplus1's avatar
tenplus1 committed
			}
		}
tenplus1's avatar
tenplus1 committed
		local g = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1, growing = 1}
tenplus1's avatar
tenplus1 committed
		-- Last step doesn't need growing=1 so Abm never has to check these
		if i == def.steps then
TenPlus1's avatar
TenPlus1 committed
			g.growing = 0
tenplus1's avatar
tenplus1 committed
		end

tenplus1's avatar
tenplus1 committed
		local node_name = mname .. ":" .. pname .. "_" .. i
tenplus1's avatar
tenplus1 committed
		minetest.register_node(node_name, {
tenplus1's avatar
tenplus1 committed
			drawtype = "plantlike",
			waving = 1,
			tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
			paramtype = "light",
			walkable = false,
			buildable_to = true,
			drop = drop,
TenPlus1's avatar
TenPlus1 committed
			selection_box = farming.select,
tenplus1's avatar
tenplus1 committed
			groups = g,
			sounds = default.node_sound_leaves_defaults(),
		})
TenPlus1's avatar
TenPlus1 committed
		register_plant_node(node_name)
tenplus1's avatar
tenplus1 committed
	end

	-- Return info
	local r = {seed = mname .. ":seed_" .. pname, harvest = mname .. ":" .. pname}
	return r
end

TenPlus1's avatar
TenPlus1 committed

-- default settings
farming.carrot = true
farming.potato = true
farming.tomato = true
farming.cucumber = true
farming.corn = true
farming.coffee = true
farming.coffee = true
farming.melon = true
farming.sugar = true
farming.pumpkin = true
farming.cocoa = true
farming.raspberry = true
farming.blueberry = true
farming.rhubarb = true
farming.beans = true
farming.grapes = true
farming.barley = true
farming.hemp = true
farming.donuts = true


-- Load new global settings if found inside mod folder
local input = io.open(farming.path.."/farming.conf", "r")
if input then
	dofile(farming.path .. "/farming.conf")
	input:close()
	input = nil
end

-- load new world-specific settings if found inside world folder
local worldpath = minetest.get_worldpath()
local input = io.open(worldpath.."/farming.conf", "r")
if input then
	dofile(worldpath .. "/farming.conf")
	input:close()
	input = nil
end


-- load crops
TenPlus1's avatar
TenPlus1 committed
dofile(farming.path.."/soil.lua")
if not minetest.get_modpath("ethereal") then
    dofile(farming.path.."/banana.lua")
end
TenPlus1's avatar
TenPlus1 committed
dofile(farming.path.."/hoes.lua")
dofile(farming.path.."/grass.lua")
dofile(farming.path.."/wheat.lua")
dofile(farming.path.."/cotton.lua")
dofile(farming.path.."/carrot.lua")
dofile(farming.path.."/potato.lua")
dofile(farming.path.."/tomato.lua")
dofile(farming.path.."/cucumber.lua")
dofile(farming.path.."/corn.lua")
dofile(farming.path.."/coffee.lua")
dofile(farming.path.."/melon.lua")
dofile(farming.path.."/sugar.lua")
dofile(farming.path.."/pumpkin.lua")
dofile(farming.path.."/cocoa.lua")
dofile(farming.path.."/raspberry.lua")
Milan's avatar
Milan committed
dofile(farming.path.."/strawberry.lua")
TenPlus1's avatar
TenPlus1 committed
dofile(farming.path.."/blueberry.lua")
dofile(farming.path.."/rhubarb.lua")
dofile(farming.path.."/beanpole.lua")
dofile(farming.path.."/grapes.lua")
dofile(farming.path.."/barley.lua")
Milan's avatar
Milan committed
dofile(farming.path.."/oranges.lua")
Milan's avatar
Milan committed
dofile(farming.path.."/hemp.lua")
TenPlus1's avatar
TenPlus1 committed
dofile(farming.path.."/donut.lua")
dofile(farming.path.."/mapgen.lua")
dofile(farming.path.."/compatibility.lua") -- Farming Plus compatibility
TenPlus1's avatar
TenPlus1 committed
dofile(farming.path.."/lucky_block.lua")