
-- infect a plant at pos and start timer
farming.plant_infect = function(pos)
	local starttime=os.clock()

	local def = minetest.registered_nodes[minetest.get_node(pos).name]
	local infect_name=def.plant_name.."_infected"

	if not minetest.registered_nodes[infect_name] then
		return 
	end

	if not def.groups.infectable then
		return
	end

	if not def.groups.step then
		return
	end

	local meta = minetest.get_meta(pos)
	local toremove=false
	if meta:get_int("farming:healthiness") then
		local healthiness=tonumber(meta:get_int("farming:healthiness"))
		if healthiness ~= nil then
			-- check for nearby plants which can protect against infections
			for i=1,3 do
				local protplant=minetest.find_node_near(pos,i,"group:infection_defense")
				if protplant ~= nil then
					ppdef=minetest.get_node(protplant)
					-- the protection plant has to be within their defined radius
					if ppdef.groups.infection_defense >= i then
						healthiness=healthiness+i*10
					end
				end
			end
		end

		if healthiness>farming.health_threshold then
			meta:set_int("farming:healthiness",healthiness-meta:get_int("farming:weakness"))
		else
			meta:set_int("farming:healthiness",farming.health_threshold)
			meta:set_int("farming:weakness",5)
			toremove=true
		end
	else
		toremove=true
	end

	if toremove then
		local placenode = {name = infect_name}
		if def.place_param2 then
			placenode.param2 = def.place_param2
		end

		minetest.swap_node(pos, placenode)

		local meta = minetest.get_meta(pos)
		meta:set_int("farming:step",def.groups["step"])

		minetest.get_node_timer(pos):start(math.random(farming.wait_min,farming.wait_max))
	end
	--table.insert(farming.time_plantinfect,1000*(os.clock()-starttime))
end

-- cures a plant at pos, restoring at last saved step
farming.plant_cured = function(pos, node, digger)
	local starttime=os.clock()

--	local node = minetest.get_node(pos)
	local name = node.name
	local def = minetest.registered_nodes[name]
	local meta = minetest.get_meta(pos)
	local cured_step=meta:get_int("farming:step")
	if (cured_step == nil) or (cured_step <= 0) then cured_step = 1 end
	local cured_name=def.step_name.."_"..cured_step

	if not minetest.registered_nodes[cured_name] then
		minetest.node_dig(pos,node,digger)
		return 
	end

	local placenode = {name = cured_name}
	if def.place_param2 then
		placenode.param2 = def.place_param2
	end

	minetest.swap_node(pos, placenode)
	--table.insert(farming.time_plantcured,1000*(os.clock()-starttime))
end

-- function for handle punching of a crop
-- if at last step than go back one step and give puncher one fruit
-- then start timer again
farming.punch_step = function(pos, node, puncher, pointed_thing)
	local starttime=os.clock()

	local def = minetest.registered_nodes[node.name]

	if def == nil then return end
	
	if def.groups.punchable == nil then
		return
	end

	-- only give fruit and go back if pre step is defined
	if def.pre_step == nil then
		return
	end

	
	if puncher ~= nil and puncher:get_player_name() ~= "" then
		-- give one item only if no billhook is used
		puncher:get_inventory():add_item('main',def.drop_item)
		local tool_def = puncher:get_wielded_item():get_definition()

		if tool_def.groups.billhook then
			-- when using a billhook give one more item by chance 
			if tool_def.farming_change ~= nil then
				if math.random(1,tool_def.farming_change)==1 then
					puncher:get_inventory():add_item('main',def.drop_item)
				end
			end
		end
	end
	
	
	minetest.swap_node(pos, {name=def.pre_step,
		param2=def.place_param2 or 3})
	
	-- new timer needed?
	local pre_def=minetest.registered_nodes[def.pre_step]
	local meta = minetest.get_meta(pos)
	meta:set_int("farming:step",pre_def.groups.step)

	if pre_def.next_step then
		local waittime=math.random(pre_def.grow_time_min or 100, pre_def.grow_time_max or 200) * farming.factor_regrow
		minetest.get_node_timer(pos):start(math.random(pre_def.grow_time_min or 100, pre_def.grow_time_max or 200))
	end
	return 
end

minetest.register_on_punchnode(farming.punch_step)
-- function for digging crops
-- if dug with scythe by change you harvest more
farming.dig_harvest = function(pos, node, digger)
--	local starttime=os.clock()

	local def = minetest.registered_nodes[node.name]
	if digger == nil then
		return
	end
	local tool_def = digger:get_wielded_item():get_definition()

	if tool_def.groups.scythe and def.drop_item then
		if tool_def.farming_change ~= nil then
			if math.random(1,tool_def.farming_change)==1 then
				digger:get_inventory():add_item('main',def.drop_item)
			end
		end
	end

--	print(dump(def.drop))
--	minetest.node_dig(pos,node,digger)
	--table.insert(farming.time_digharvest,1000*(os.clock()-starttime))
end
minetest.register_on_dignode(farming.dig_harvest)

-- timer function for infected plants
-- the step of plant is reduced till zero then the plant dies
-- nearby crops are infected by change given in configuration
-- normally in monoculture the infection rate is higher
farming.timer_infect = function(pos,elapsed)
--	local starttime=os.clock()
	local node = minetest.get_node(pos)

	local def = minetest.registered_nodes[node.name]
	local meta = minetest.get_meta(pos)
	-- if no step is saved in metadata (should not be, but...) , removing plant

	if meta:get_int("farming:step") == nil then
		minetest.swap_node(pos, {name="air"})
		return
	end

	-- if zero step is reached, plant dies
	if meta:get_int("farming:step") <= 0 then
		minetest.swap_node(pos, {name="default:grass_"..math.random(1,4)})
		return
	end

	local infected = 0
	-- check for monoculture and infect nearby plants
	if def.infect_rate_monoculture ~= nil then
		local monoculture=minetest.find_nodes_in_area(vector.subtract(pos,2),vector.add(pos,2),"group:"..def.plant_name)
		if monoculture ~= nil then
			for i = 1,#monoculture do
				if math.random(1,math.max(2,def.infect_rate_monoculture))==1 then
					farming.plant_infect(monoculture[i])
					infected=infected+1
				end
			end
		end
	end

	-- if no monoculture plant was infected try other crops
	-- check for nearby other plants and infect them
	if infected == 0 then
		if def.infect_rate_base ~= nil then
			local culture=minetest.find_nodes_in_area(vector.subtract(pos,3),vector.add(pos,3),"group:infectable")
			if culture ~= nil then
				for i = 1,#culture do
					if math.random(1,math.max(2,def.infect_rate_base))==1 then
						farming.plant_infect(culture[i])
						infected=infected+1
					end
				end
			end
		end
	end

	meta:set_int("farming:step",meta:get_int("farming:step")-1)
	minetest.get_node_timer(pos):start(math.random(farming.wait_min,farming.wait_max))
	--table.insert(farming.time_infect,1000*(os.clock()-starttime))
end

-- timer function called for a step to grow
-- if enough light then grow to next step
-- if a following step or wilt is defined then calculate new time and set timer
farming.timer_step = function(pos, elapsed)
	local starttime=os.clock()

	local def = minetest.registered_nodes[minetest.get_node(pos).name]

	-- if no next step define: exit
	if not def.next_step then
		return
	end

	if minetest.registered_nodes[def.next_step] == nil then
		return
	end
	local light = minetest.get_node_light(pos)
	local pdef=farming.registered_plants[def.plant_name]

	-- if too less or too much light: Wait more time
	if not light or light < pdef.light_min or light > pdef.light_max then
		minetest.get_node_timer(pos):start(math.random(farming.wait_min, farming.wait_max))
		return
	end

	local next_def=minetest.registered_nodes[def.next_step]
	minetest.swap_node(pos, {name=def.next_step,
		param2=def.place_param2 or 3})
	local meta = minetest.get_meta(pos)

	if next_def.groups.farming_wilt ~= nil then
		if meta:get_int("farming:weakness") == nil then
			farming.set_node_metadata(pos)
		end
		meta:set_int("farming:weakness",math.ceil(meta:get_int("farming:weakness")/2))
	else
		meta:set_int("farming:step",next_def.groups.step)
	end
	
	if next_def.groups.farming_fullgrown ~= nil then
		meta:set_int("farming:seeds",1)
	else
		meta:set_int("farming:seeds",0)
	end

	-- new timer needed?
	local wait_factor = 1
	-- check for config values
	local lightamount=meta:get_int("farming:lightamount")

	if lightamount ~= nil then
		local ls = farming.light_stat[tostring(def.light_min)]
		if ls.amount ~= nil and lightamount > 0 then
			-- time till next step is stretched. Less light means longer growing time
			wait_factor = ls.amount / lightamount
		end
	else
		wait_factor = math.max(0.75,def.light_min/minetest.get_node_light(pos,0.5))
	end

	-- using light at midday to increase or decrease growing time
	local wait_min = math.ceil(def.grow_time_min * wait_factor)
	local wait_max = math.ceil(def.grow_time_max * wait_factor)
	if wait_max <= wait_min then wait_max = 2*wait_min end

	local timespeed=minetest.settings:get("time_speed")
	local time_wait=math.random(wait_min,wait_max)
	local local_rwt=time_wait*timespeed/(86400)
	local daystart=meta:get_float("farming:daystart")
	local acttime=minetest.get_timeofday()

	if math.abs(acttime+local_rwt-0.5)>(0.5-daystart) then
		time_wait=86400*(1+daystart-acttime)/timespeed
	end
	minetest.get_node_timer(pos):start(time_wait)
	--table.insert(farming.time_steptimer,1000*(os.clock()-starttime))
	return
end

-- Seed placement
-- adopted from minetest-game
farming.place_seed = function(itemstack, placer, pointed_thing, plantname)
	local starttime=os.clock()

	-- check if pointing at a node
	if not pointed_thing then
		return itemstack
	end

	if pointed_thing.type ~= "node" then
		return itemstack
	end

	-- check if pointing at the top of the node
	if pointed_thing.above.y ~= pointed_thing.under.y+1 then
		return itemstack
	end
	
	local player_name = placer and placer:get_player_name() or ""

	if minetest.is_protected(pointed_thing.under, player_name) then
		minetest.record_protection_violation(pointed_thing.under, player_name)
		return
	end
	if minetest.is_protected(pointed_thing.above, player_name) then
		minetest.record_protection_violation(pointed_thing.above, player_name)
		return
	end

	local under = minetest.get_node(pointed_thing.under)
	-- return if any of the nodes is not registered
	if not minetest.registered_nodes[under.name] then
		return itemstack
	end

	local above = minetest.get_node(pointed_thing.above)
	if not minetest.registered_nodes[above.name] then
		return itemstack
	end

	-- check if you can replace the node above the pointed node
	if not minetest.registered_nodes[above.name].buildable_to then
		return itemstack
	end

	local udef = minetest.registered_nodes[under.name]
	local pdef = minetest.registered_nodes[plantname]
	
	-- check if pointing at soil and seed needs soil
	if minetest.get_item_group(under.name,"soil") < 2 then
		if minetest.get_item_group(plantname,"on_soil") >= 1 then
			return
		else

			-- check if node is correct one
			local plant_def=farming.registered_plants[pdef.plant_name]
			-- check for correct temperature
			if pointed_thing.under.y < plant_def.elevation_min or pointed_thing.under.y > plant_def.elevation_max then
				minetest.chat_send_player(player_name,"Elevation must be between "..plant_def.elevation_min.." and "..plant_def.elevation_max)
				return
			end

			if minetest.get_heat(pointed_thing.under) < plant_def.temperature_min or minetest.get_heat(pointed_thing.under) > plant_def.temperature_max then
				minetest.chat_send_player(player_name,"Temperature "..minetest.get_heat(pt.under).." is out of range for planting.")
				return
			end

			if minetest.get_humidity(pointed_thing.under) < plant_def.humidity_min or minetest.get_humidity(pointed_thing.under) > plant_def.humidity_max then
				minetest.chat_send_player(player_name,"Humidity "..minetest.get_humidity(pt.under).." is out of range for planting.")
				return
			end
		end
	end

	-- add the node and remove 1 item from the itemstack
	minetest.add_node(pointed_thing.above, {name = plantname, param2 = 1})
	local wait_min=farming.wait_min or 120
	local wait_max=farming.wait_max or 240

	if pdef.grow_time_min then
		wait_min=pdef.grow_time_min
	end
	if pdef.grow_time_max then
		wait_max=pdef.grow_time_max
	end

	minetest.get_node_timer(pointed_thing.above):start(math.random(wait_min, wait_max))

	local meta = minetest.get_meta(pointed_thing.above)
	meta:set_int("farming:step",0)

	farming.set_node_metadata(pointed_thing.above,placer)

	if not (creative and creative.is_enabled_for
			and creative.is_enabled_for(player_name)) then
		itemstack:take_item()
	end
	--table.insert(farming.time_placeseed,1000*(os.clock()-starttime))
	return itemstack
end

-- timer function for growing seed
-- after the time out the first step of plant in placed
farming.timer_seed = function(pos, elapsed)
	local starttime=os.clock()

	local node = minetest.get_node(pos)
	local def = minetest.registered_nodes[node.name]

	local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
	if not soil_node then
		minetest.get_node_timer(pos):start(math.random(farming.wait_min, farming.wait_max))
		return
	end

	-- omitted is a check for light, we assume seeds can germinate in the dark.
	local placenode = {name = def.next_step}
	if def.place_param2 then
		placenode.param2 = def.place_param2 or 3
	end

	minetest.swap_node(pos, placenode)
	local meta = minetest.get_meta(pos)

	if def.next_step then
		meta:set_int("farming:step",minetest.registered_nodes[def.next_step].groups.step)

		-- using light at midday to increase or decrease growing time
		local local_light_max = minetest.get_node_light(pos,0.5)
		local wait_factor = math.max(0.75,def.light_min/local_light_max)
		local wait_min = math.ceil(def.grow_time_min * wait_factor)
		local wait_max = math.ceil(def.grow_time_max * wait_factor)
		if wait_max <= wait_min then wait_max = 2*wait_min end

		local node_timer=math.random(wait_min, wait_max)
		minetest.get_node_timer(pos):start(node_timer)
		return
	end
	--table.insert(farming.time_seedtimer,1000*(os.clock()-starttime))
end

-- timer function for wilt plants
-- normal plants will die after the time
-- weed like nettles can spread to neighbour places
farming.timer_wilt = function(pos, elapsed)
	local starttime=os.clock()

	local node = minetest.get_node(pos)
	local def = minetest.registered_nodes[node.name]

	if def.groups.wiltable == 3 then -- nettle or weed
		-- determine all nearby nodes with soil
		local farming_nearby=minetest.find_nodes_in_area(vector.subtract(pos,2),vector.add(pos,2),"group:farming")
		-- within radius 2 not more than 4 nettles should be for further spreading
		if #farming_nearby <= 4 then
			local neighb=minetest.find_nodes_in_area(vector.subtract(pos,2),vector.add(pos,2),"group:soil")
			if neighb ~= nil then
				local freen={}
				-- get soil nodes with air above
				for j=1,#neighb do
					local jpos=neighb[j]
					if basic_functions.has_value({"air","default:grass_1","default:grass_2","default:grass_3","default:grass_4","default:grass_5"},minetest.get_node({x=jpos.x,y=jpos.y+1,z=jpos.z}).name) then
						table.insert(freen,1,jpos)
					end
				end

				-- randomly pick one and spread
				if #freen >= 1 then
					local npos={x=jpos.x,y=jpos.y+1,z=jpos.z}
					local jpos=freen[math.random(1,#freen)]
					minetest.add_node(npos, {name = def.seed_name, param2 = 1})
					farming.set_node_metadata(npos)
					minetest.get_node_timer(npos):start(def.grow_time_min or 10)
				end
			end
		end

		-- after spreading the source can be removed, go back one step or stay
		-- with higher change to be removed if already several similar plants are nearby
		local wran=math.random(1,math.max(3,#farming_nearby))
		if wran >= 3 then
			minetest.swap_node(pos, {name="air"})
		end
		if wran == 2 then
			if def.pre_step ~= nil then
				minetest.swap_node(pos, {name=def.pre_step, param2=1})
				minetest.get_node_timer(pos):start(math.random(def.grow_time_min or 10,def.grow_time_max or 20))
			end
		end
		if wran == 1 then
			minetest.get_node_timer(pos):start(math.random(def.grow_time_min or 10,def.grow_time_max or 20))
		end
	else --normal crop
		minetest.set_node(pos, {name="air"})
		minetest.add_node(pos, {name="default:grass_"..math.random(1,5),param2=1})
	end
	--table.insert(farming.time_wilttimer,1000*(os.clock()-starttime))
end


farming.seed_on_place = function(itemstack, placer, pointed_thing)
	local node = minetest.get_node(pointed_thing.under)
	local udef = minetest.registered_nodes[node.name]
	local plantname = itemstack:get_name()
	if udef and udef.on_rightclick and
			not (placer and placer:is_player() and
			placer:get_player_control().sneak) then
		return udef.on_rightclick(pointed_thing.under, node, placer, itemstack,
			pointed_thing) or itemstack
	end
	return farming.place_seed(itemstack, placer, pointed_thing, plantname)
end

-- using tools
-- adopted from minetest-games
farming.dig_by_tool = function(itemstack, user, pointed_thing, uses)
	local starttime=os.clock()
	-- check if pointing at a node
	if not pointed_thing then
		return
	end

	local under = minetest.get_node(pointed_thing.under)
	local p = {x=pointed_thing.under.x, y=pointed_thing.under.y+1, z=pointed_thing.under.z}
	local above = minetest.get_node(p)

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

	-- check if the node above the pointed thing is air
	if above.name ~= "air" then
		return
	end

	if minetest.is_protected(pointed_thing.under, user:get_player_name()) then
		minetest.record_protection_violation(pointed_thing.under, user:get_player_name())
		return
	end
	if minetest.is_protected(pointed_thing.above, user:get_player_name()) then
		minetest.record_protection_violation(pointed_thing.above, user:get_player_name())
		return
	end
	if not (creative and creative.is_enabled_for
			and creative.is_enabled_for(user:get_player_name())) then
		-- wear tool
		local wdef = itemstack:get_definition()
		itemstack:add_wear(65535/(wdef.max_uses-1))
		minetest.node_dig(pt.under,under,user)
		-- tool break sound
		if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
			minetest.sound_play(wdef.sound.breaks, {pos = pointed_thing.above, gain = 0.5})
		end
	end
	--table.insert(farming.time_tooldig,1000*(os.clock()-starttime))
	return itemstack
end

farming.use_picker = function(itemstack, user, pointed_thing,uses)
	local starttime=os.clock()
	-- check if pointing at a node
	if not pointed_thing then
		return
	end
	if pointed_thing.type ~= "node" then
		return
	end
	local pos = pointed_thing.under
	local under = minetest.get_node(pos)
	-- return if any of the nodes is not registered
	if not minetest.registered_nodes[under.name] then
		return
	end

	if minetest.is_protected(pos, user:get_player_name()) then
		minetest.record_protection_violation(pos, user:get_player_name())
		return
	end

	local pdef=minetest.registered_nodes[under.name]
	-- check if pointing at punchable crop
	if pdef.groups.punchable == nil then
		return
	end
	-- check if plant is full grown
	if pdef.groups.farming_fullgrown == nil then
		return
	end
	-- check if seeds can be extracted
	if pdef.groups.seed_extractable == nil then
		return
	end
	-- check if seeds are available
	local meta = minetest.get_meta(pos)
	if meta:get_int("farming:seeds") == nil then
		meta:set_int("farming:seeds",0)
		return
	else
		if meta:get_int("farming:seeds")==0 then
			return
		end
	end
	
	local tdef=itemstack:get_definition()
	if not (creative and creative.is_enabled_for
			and creative.is_enabled_for(user:get_player_name())) then
		-- wear tool
		itemstack:add_wear(65535/(uses-1))
		-- tool break sound
		if itemstack:get_count() == 0 and tdef.sound and tdef.sound.breaks then
			minetest.sound_play(tdef.sound.breaks, {pos = pointed_thing.above, gain = 0.5})
		end
	end
	user:get_inventory():add_item('main',pdef.seed_name)
	if math.random(1,3)==1 then
		user:get_inventory():add_item('main',pdef.seed_name)
	end
	-- call punching function of crop: normally go back one step and start timer
	minetest.punch_node(pointed_thing.under)
	local meta = minetest.get_meta(pos)
	meta:set_int("farming:seeds",0)

	--table.insert(farming.time_usehook,1000*(os.clock()-starttime))
	return itemstack
end
-- function for using billhook on punchable fruits
-- add wear to billhook and give player by change one more fruit
farming.use_billhook = function(itemstack, user, pointed_thing, uses)
	local starttime=os.clock()
	-- check if pointing at a node
	if not pointed_thing then
		return
	end
	if pointed_thing.type ~= "node" then
		return
	end
	local under = minetest.get_node(pointed_thing.under)
	-- return if any of the nodes is not registered
	if not minetest.registered_nodes[under.name] then
		return
	end

	local pdef=minetest.registered_nodes[under.name]
	-- check if pointing at punchable crop
	if pdef.groups.punchable == nil then
		return
	end
	-- check if plant is full grown
	if pdef.groups.farming_fullgrown == nil then
		return
	end
	if minetest.is_protected(pointed_thing.under, user:get_player_name()) then
		minetest.record_protection_violation(pointed_thing.under, user:get_player_name())
		return
	end

	local tdef=itemstack:get_definition()
	if not (creative and creative.is_enabled_for
			and creative.is_enabled_for(user:get_player_name())) then
		-- wear tool
		itemstack:add_wear(65535/(uses-1))
		-- tool break sound
		if itemstack:get_count() == 0 and tdef.sound and tdef.sound.breaks then
			minetest.sound_play(tdef.sound.breaks, {pos = pointed_thing.above, gain = 0.5})
		end
	end
	user:get_inventory():add_item('main',pdef.drop_item)
	if tdef.farming_change ~= nil then
		if math.random(1,tdef.farming_change)==1 then
			user:get_inventory():add_item('main',pdef.drop_item)
			farming.ping_punch(user:get_player_name(),pdef.drop_item,1)
		end
	end
	-- call punching function of crop: normally go back one step and start timer
	minetest.punch_node(pointed_thing.under)
	--table.insert(farming.time_usehook,1000*(os.clock()-starttime))
	return itemstack
end

-- calculate light amount on a position for a given light_min
farming.calc_light=function(pos,pdef)
	local starttime=os.clock()
	-- calculating 
	local day_start=99999
	local light_amount=0
	local light_min=pdef.light_min
	
	-- run from 5:00 till 12:00 in 6min steps
	for i=50,120 do
		local reli=i/240
		local nl=minetest.get_node_light(pos,reli)
		if nl>light_min then
			light_amount=light_amount+nl
			if day_start > 1000 then day_start = i end
		end
	end
	
	if day_start > 240 then
		day_start=120
	end
	
	--table.insert(farming.time_calclight,1000*(os.clock()-starttime))
	local outdata={day_start=day_start,
			light_amount=light_amount,
			}
			
	return outdata
end

-- calculate several meta data for a node and save in node storage
farming.set_node_metadata=function(pos,player)
	local starttime=os.clock()
	local base_rate = 5
	local node = minetest.get_node(pos)
	local def = minetest.registered_nodes[node.name]
	local pdef = farming.registered_plants[def.plant_name]
	local ill_rate=base_rate * (pdef.light_max-minetest.get_node_light(pos,0.5))/(pdef.light_max-pdef.light_min)
	local player_meta=99
	if player ~= nil then
		player_meta=player:get_meta()
	end
	-- calc coeff for temperature
	local ill_temp=(base_rate * math.sqrt(math.min(minetest.get_heat(pos)-pdef.temperature_min,pdef.temperature_max-minetest.get_heat(pos))/(pdef.temperature_max-pdef.temperature_min)))
	-- negative coeff means, it is out of range
	if ill_temp < 0 then
		ill_temp = (ill_temp * (-0.75))
	end

	-- calc coeff for humidity
	local ill_hum=(base_rate * math.sqrt(math.min(minetest.get_humidity(pos)-pdef.humidity_min,pdef.humidity_max-minetest.get_humidity(pos))/(pdef.humidity_max-pdef.humidity_min)))
	-- negative coeff means, it is out of range
	if ill_hum < 0 then
		ill_hum = (ill_hum * (-0.75))
	end

	local infect_rate = 1
	if pdef.groups.infectable then
		infect_rate = pdef.groups.infectable
	end

	ill_rate = math.ceil((ill_rate + ill_temp + ill_hum)/infect_rate)
	if player_meta ~= 99 then
		if player_meta:get_int("xp:farming") ~= nil then
			ill_rate = math.ceil(ill_rate * player_meta:get_int("xp:farming"))
		end
	end
	local meta = minetest.get_meta(pos)

	-- weakness as rate, how easily a crop can be infected
	meta:set_int("farming:weakness",ill_rate)
	-- healthiness as mechanism to controll if a crop will be infected
	meta:set_int("farming:healthiness",50+ill_rate)
	
	local lightcalc=farming.calc_light(pos,pdef)
	-- daytime, when light reach light_min
	meta:set_float("farming:daystart",lightcalc.day_start/240)
	-- amount of light the crop gets till midday
	meta:set_int("farming:lightamount",lightcalc.light_amount)
	-- init the amount of seed available at the crop
	meta:set_int("farming:seeds",0)
	--table.insert(farming.time_setmeta,1000*(os.clock()-starttime))
end
