diff options
| -rw-r--r-- | crops_settings.txt | 11 | ||||
| -rw-r--r-- | description.txt | 1 | ||||
| -rw-r--r-- | init.lua | 231 | ||||
| -rw-r--r-- | potato.lua | 35 | ||||
| -rw-r--r-- | screenshot.png | bin | 0 -> 253354 bytes | |||
| -rw-r--r-- | textures/crops_hydrometer.png | bin | 0 -> 223 bytes | |||
| -rw-r--r-- | textures/crops_potato_plant_5.png | bin | 0 -> 424 bytes | |||
| -rw-r--r-- | textures/crops_soak.png | bin | 0 -> 182 bytes | |||
| -rw-r--r-- | textures/crops_watering_can.png | bin | 0 -> 327 bytes | |||
| -rw-r--r-- | textures/crops_wither.png | bin | 0 -> 140 bytes | |||
| -rw-r--r-- | tomato.lua | 45 | 
11 files changed, 311 insertions, 12 deletions
| diff --git a/crops_settings.txt b/crops_settings.txt index 39dd3c0..e784407 100644 --- a/crops_settings.txt +++ b/crops_settings.txt @@ -20,6 +20,17 @@ crops.light = 8  crops.chance = 8  crops.interval = 30  crops.light = 10 +crops.watercan = 25 +crops.watercan_max = 89 +crops.watercanuses = 20 +crops.waterstart = 50 +crops.wateruse = 1 +crops.night = 5 +crops.soak = 80 +crops.soak_damage = 90 +crops.wither = 20 +crops.wither_damage = 10 +crops.max_damage = 50  --[[  -- difficult -- diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..45c16d9 --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +This mod expands the basic set of farming-related crops that minetest_game offers. @@ -11,6 +11,7 @@ of the license, or (at your option) any later version.  --]]  crops = {} +crops.plants = {}  local worldpath = minetest.get_worldpath()  local modpath = minetest.get_modpath(minetest.get_current_modname()) @@ -34,6 +35,176 @@ else  	dofile(worldpath .. "/crops_settings.txt")  end +local find_plant = function(node) +	for i = 1,table.getn(crops.plants) do +		if crops.plants[i].name == node.name then +			return crops.plants[i] +		end +	end +	minetest.log("error", "Unable to find plant \"" .. node.name .. "\" in crops table") +	return nil +end + +crops.plant = function(pos, node) +	minetest.set_node(pos, node) +	local meta = minetest.get_meta(pos) +	meta:set_int("crops_water", crops.waterstart) +	meta:set_int("crops_damage", 0) +end + +crops.can_grow = function(pos) +	if minetest.get_node_light(pos, nil) < crops.light then +		return false +	end +	local meta = minetest.get_meta(pos) +	local water = meta:get_int("crops_water") +	if water < crops.wither or water > crops.soak then +		if math.random(0,1) == 0 then +			return false +		end +	end +	local damage = meta:get_int("crops_damage") +	if not damage == 0 then +		if math.random(math.min(50, damage), 100) > 75 then +			return false +		end +	end +	local node = minetest.get_node(pos) +	local plant = find_plant(node) +	if not plant then +		return false +	end + +	-- allow the plant to grow +	return true +end + +crops.particles = function(pos, flag) +	local p = {} +	if flag == 0 then +		-- wither (0) +		p = { +			amount = 1 * crops.interval, +			time = crops.interval, +			minpos = { x = pos.x - 0.4, y = pos.y - 0.4, z = pos.z - 0.4 }, +			maxpos = { x = pos.x + 0.4, y = pos.y + 0.4, z = pos.z + 0.4 }, +			minvel = { x = 0, y = 0.2, z = 0 }, +			maxvel = { x = 0, y = 0.4, z = 0 }, +			minacc = { x = 0, y = 0, z = 0 }, +			maxacc = { x = 0, y = 0.2, z = 0 }, +			minexptime = 3, +			maxexptime = 5, +			minsize = 1, +			maxsize = 2, +			collisiondetection = false, +			texture = "crops_wither.png", +			vertical = true, +		} +	else +		-- soak (1) +		p = { +			amount = 8 * crops.interval, +			time = crops.interval, +			minpos = { x = pos.x - 0.4, y = pos.y - 0.4, z = pos.z - 0.4 }, +			maxpos = { x = pos.x + 0.4, y = pos.y - 0.4, z = pos.z + 0.4 }, +			minvel = { x = -0.04, y = 0, z = -0.04 }, +			maxvel = { x = 0.04, y = 0, z = 0.04 }, +			minacc = { x = 0, y = 0, z = 0 }, +			maxacc = { x = 0, y = 0, z = 0 }, +			minexptime = 3, +			maxexptime = 5, +			minsize = 1, +			maxsize = 2, +			collisiondetection = false, +			texture = "crops_soak.png", +			vertical = false, +		} +	end +	minetest.add_particlespawner(p) +end + +minetest.register_tool("crops:watering_can", { +	description = "Watering Can", +	inventory_image = "crops_watering_can.png", +	liquids_pointable = true, +	range = 2.5, +	stack_max = 1, +	wear = 65535, +	tool_capabilities = { +	}, +	on_use = function(itemstack, user, pointed_thing) +		local pos = pointed_thing.under +		if pos == nil then +			return itemstack +		end +		-- filling it up? +		local node = minetest.get_node(pos) +		if node.name == "default:water_source" or +		   node.name == "default:water_flowing" then +			itemstack:set_wear(1) +			return itemstack +		end +		-- using it on a plant? +		local meta = minetest.get_meta(pos) +		local water = meta:get_int("crops_water") +		if water == nil then +			return itemstack +		end +		local wear = itemstack:get_wear() +		-- empty? +		if wear == 65534 then +			return itemstack +		end +		water = math.min(water + crops.watercan, crops.watercan_max) +		meta:set_int("crops_water", water) +		itemstack:set_wear(math.min(65534, wear + (65535 / crops.watercanuses))) +		return itemstack +	end, +}) + +minetest.register_tool("crops:hydrometer", { +	description = "Hydrometer", +	inventory_image = "crops_hydrometer.png", +	liquids_pointable = false, +	range = 2.5, +	stack_max = 1, +	tool_capabilities = { +	}, +	on_use = function(itemstack, user, pointed_thing) +		local pos = pointed_thing.under +		if pos == nil then +			return itemstack +		end +		local meta = minetest.get_meta(pos) +		-- using it on a plant? +		local water = meta:get_int("crops_water") +		if water == nil then +			itemstack:set_wear(65534) +			return itemstack +		end +		itemstack:set_wear(65535 - ((65534 / 100) * water)) +		return itemstack +	end, +}) + +minetest.register_craft({ +	output = "crops:watering_can", +	recipe = { +		{ "default:steel_ingot", "", "" }, +		{ "default:steel_ingot", "", "default:steel_ingot" }, +		{ "", "default:steel_ingot", "" }, +	}, +}) + +minetest.register_craft({ +	output = "crops:hydrometer", +	recipe = { +		{ "default:mese_crystal_fragment", "", "" }, +		{ "", "default:steel_ingot", "" }, +		{ "", "", "default:steel_ingot" }, +	}, +}) +  -- crop nodes, crafts, craftitems  dofile(modpath .. "/melon.lua")  dofile(modpath .. "/corn.lua") @@ -41,6 +212,66 @@ dofile(modpath .. "/tomato.lua")  dofile(modpath .. "/potato.lua")  dofile(modpath .. "/polebean.lua") +-- water handling code +minetest.register_abm({ +	nodenames = { +		"crops:tomato_plant_1", "crops:tomato_plant_2", "crops:tomato_plant_3", "crops:tomato_plant_4", "crops:tomato_plant_5", +		"crops:potato_plant_1", "crops:potato_plant_2", "crops:potato_plant_3", "crops:potato_plant_4" +	}, +	interval = crops.interval, +	chance = crops.chance, +	action = function(pos, node, active_object_count, active_object_count_wider) +		local meta = minetest.get_meta(pos) +		local water = meta:get_int("crops_water") +		local damage = meta:get_int("crops_damage") + +		-- get plant specific data +		local plant = find_plant(node) +		if plant == nil then +			return +		end + +		-- increase water for nearby water sources +		local f = minetest.find_node_near(pos, 1, {"default:water_source", "default:water_flowing"}) +		if not f == nil then +			water = math.min(100, water + 2) +		else +			local f = minetest.find_node_near(pos, 2, {"default:water_source", "default:water_flowing"}) +			if not f == nil then +				water = math.min(100, water + 1) +			end +		end + +		-- compensate for light: at night give some water back to the plant +		if minetest.get_node_light(pos, nil) < crops.night then +			water = math.min(100, water + 1) +		end + +		-- dry out the plant +		water = math.max(0, water - ( crops.wateruse * plant.wateruse )) +		meta:set_int("crops_water", water) +		if water < crops.wither_damage then +			crops.particles(pos, 0) +			damage = damage + math.random(0,5) +		elseif water < crops.wither then +			crops.particles(pos, 0) +			return +		elseif water > crops.soak_damage then +			crops.particles(pos, 1) +			damage = damage + math.random(0,5) +		elseif water > crops.soak then +			crops.particles(pos, 1) +			return +		end +		meta:set_int("crops_damage", math.min(crops.max_damage, damage)) + +		-- is it dead? +		if damage >= 100 then +			plant.wither(pos) +		end +	end +}) +  -- cooking recipes that mix craftitems  dofile(modpath .. "/cooking.lua") @@ -28,7 +28,7 @@ minetest.register_node("crops:potato_eyes", {  		if minetest.get_item_group(under.name, "soil") <= 1 then  			return  		end -		minetest.set_node(pointed_thing.above, {name="crops:potato_plant_1"}) +		crops.plant(pointed_thing.above, {name="crops:potato_plant_1"})  		if not minetest.setting_getbool("creative_mode") then  			itemstack:take_item()  		end @@ -36,7 +36,7 @@ minetest.register_node("crops:potato_eyes", {  	end  }) -for stage = 1, 4 do +for stage = 1, 5 do  minetest.register_node("crops:potato_plant_" .. stage , {  	description = "potato plant",  	tiles = { "crops_potato_plant_" .. stage .. ".png" }, @@ -89,6 +89,7 @@ minetest.register_node("crops:soil_with_potatoes", {  	sounds = default.node_sound_dirt_defaults(),  	on_dig = function(pos, node, digger)  		local drops = {} +		-- fixme account for damage  		for i = 1, math.random(3, 5) do  			table.insert(drops, "crops:potato")  		end @@ -110,17 +111,22 @@ minetest.register_abm({  	interval = crops.interval,  	chance = crops.chance,  	action = function(pos, node, active_object_count, active_object_count_wider) -		local below = { x = pos.x, y = pos.y - 1, z = pos.z } -		if not minetest.registered_nodes[minetest.get_node(below).name].groups.soil then +		if not crops.can_grow(pos) then  			return  		end -		if minetest.get_node_light(pos, nil) < crops.light then +		local below = { x = pos.x, y = pos.y - 1, z = pos.z } +		if not minetest.registered_nodes[minetest.get_node(below).name].groups.soil then  			return  		end +		local meta = minetest.get_meta(pos) +		local water = meta:get_int("crops_water") +		local damage = meta:get_int("crops_damage")  		local n = string.gsub(node.name, "3", "4")  		n = string.gsub(n, "2", "3")  		n = string.gsub(n, "1", "2")  		minetest.set_node(pos, { name = n }) +		meta:set_int("crops_water", water) +		meta:set_int("crops_damage", damage)  	end  }) @@ -133,15 +139,32 @@ minetest.register_abm({  	interval = crops.interval,  	chance = crops.chance,  	action = function(pos, node, active_object_count, active_object_count_wider) -		if minetest.get_node_light(pos, nil) < crops.light then +		if not crops.can_grow(pos) then  			return  		end  		local below = { x = pos.x, y = pos.y - 1, z = pos.z }  		if not minetest.registered_nodes[minetest.get_node(below).name].groups.soil then  			return  		end +		local meta = minetest.get_meta(pos) +		local water = meta:get_int("crops_water") +		local damage = meta:get_int("crops_damage")  		local below = { x = pos.x, y = pos.y - 1, z = pos.z}  		minetest.set_node(below, { name = "crops:soil_with_potatoes" })  	end  }) +crops.potato_die = function(pos) +	minetest.set_node(pos, { name = "crops:potato_plant_5" }) +	local below = { x = pos.x, y = pos.y - 1, z = pos.z } +	local node = minetest.get_node(below) +	if node.name == "crops:soil_with_potatoes" then +		local meta = minetest.get_meta(below) +		meta:set_int("crops_damage", 100) +	end +end + +table.insert(crops.plants, { name = "crops:potato_plant_1", wateruse = 1.0, wither = crops.potato_die }) +table.insert(crops.plants, { name = "crops:potato_plant_2", wateruse = 1.0, wither = crops.potato_die }) +table.insert(crops.plants, { name = "crops:potato_plant_3", wateruse = 1.0, wither = crops.potato_die }) +table.insert(crops.plants, { name = "crops:potato_plant_4", wateruse = 1.0, wither = crops.potato_die }) diff --git a/screenshot.png b/screenshot.pngBinary files differ new file mode 100644 index 0000000..16f6348 --- /dev/null +++ b/screenshot.png diff --git a/textures/crops_hydrometer.png b/textures/crops_hydrometer.pngBinary files differ new file mode 100644 index 0000000..1ab9951 --- /dev/null +++ b/textures/crops_hydrometer.png diff --git a/textures/crops_potato_plant_5.png b/textures/crops_potato_plant_5.pngBinary files differ new file mode 100644 index 0000000..596ed1f --- /dev/null +++ b/textures/crops_potato_plant_5.png diff --git a/textures/crops_soak.png b/textures/crops_soak.pngBinary files differ new file mode 100644 index 0000000..e6913bd --- /dev/null +++ b/textures/crops_soak.png diff --git a/textures/crops_watering_can.png b/textures/crops_watering_can.pngBinary files differ new file mode 100644 index 0000000..f3933b8 --- /dev/null +++ b/textures/crops_watering_can.png diff --git a/textures/crops_wither.png b/textures/crops_wither.pngBinary files differ new file mode 100644 index 0000000..d67b605 --- /dev/null +++ b/textures/crops_wither.png @@ -10,6 +10,8 @@ of the license, or (at your option) any later version.  --]] +local wateruse = 1 +  minetest.register_node("crops:tomato_seed", {  	description = "tomato seed",  	inventory_image = "crops_tomato_seed.png", @@ -30,7 +32,7 @@ minetest.register_node("crops:tomato_seed", {  		if minetest.get_item_group(under.name, "soil") <= 1 then  			return  		end -		minetest.set_node(pointed_thing.above, {name="crops:tomato_plant_1"}) +		crops.plant(pointed_thing.above, {name="crops:tomato_plant_1"})  		if not minetest.setting_getbool("creative_mode") then  			itemstack:take_item()  		end @@ -79,6 +81,8 @@ minetest.register_node("crops:tomato_plant_5" , {  		local meta = minetest.get_meta(pos)  		local ttl = meta:get_int("crops_tomato_ttl") +		local water = meta:get_int("crops_water") +		local damage = meta:get_int("crops_damage")  		if ttl > 1 then  			minetest.set_node(pos, { name = "crops:tomato_plant_4"})  			meta:set_int("crops_tomato_ttl", ttl - 1) @@ -86,6 +90,8 @@ minetest.register_node("crops:tomato_plant_5" , {  			minetest.set_node(pos, { name = "crops:tomato_plant_6"})  			meta:set_int("crops_tomato_ttl", 0)  		end +		meta:set_int("crops_water", water) +		meta:set_int("crops_damage", damage)  	end  }) @@ -124,14 +130,19 @@ minetest.register_abm({  	interval = crops.interval,  	chance = crops.chance,  	action = function(pos, node, active_object_count, active_object_count_wider) -		if minetest.get_node_light(pos, nil) < crops.light then +		if not crops.can_grow(pos) then  			return  		end +		local meta = minetest.get_meta(pos) +		local water = meta:get_int("crops_water") +		local damage = meta:get_int("crops_damage")  		local n = string.gsub(node.name, "4", "5")  		n = string.gsub(n, "3", "4")  		n = string.gsub(n, "2", "3")  		n = string.gsub(n, "1", "2")  		minetest.set_node(pos, { name = n }) +		meta:set_int("crops_water", water) +		meta:set_int("crops_damage", damage)  	end  }) @@ -144,16 +155,38 @@ minetest.register_abm({  	interval = crops.interval,  	chance = crops.chance,  	action = function(pos, node, active_object_count, active_object_count_wider) -		if minetest.get_node_light(pos, nil) < crops.light then +		if not crops.can_grow(pos) then  			return  		end  		local meta = minetest.get_meta(pos)  		local ttl = meta:get_int("crops_tomato_ttl") +		local water = meta:get_int("crops_water") +		local damage = meta:get_int("crops_damage")  		if ttl == 0 then -			ttl = math.random(4, 6) +			-- damage 0   - drops 4-6 +			-- damage 50  - drops 2-3 +			-- damage 100 - drops 0-1 +			ttl = math.random(4 - (4 * (damage / 100)), 6 - (5 * (damage / 100))) +		end +		if ttl > 1 then +			minetest.set_node(pos, { name = "crops:tomato_plant_5" }) +			meta:set_int("crops_tomato_ttl", ttl) +			meta:set_int("crops_water", water) +			meta:set_int("crops_damage", damage) +		else +			-- no luck, plant dead! +			minetest.set_node(pos, { name = "crops:tomato_plant_6" })  		end -		minetest.set_node(pos, { name = "crops:tomato_plant_5" }) -		meta:set_int("crops_tomato_ttl", ttl)  	end  }) +crops.tomato_die = function(pos) +	minetest.set_node(pos, { name = "crops:tomato_plant_6" }) +end + +table.insert(crops.plants, { name = "crops:tomato_plant_1", wateruse = 1.0, wither = crops.tomato_die }) +table.insert(crops.plants, { name = "crops:tomato_plant_2", wateruse = 1.0, wither = crops.tomato_die }) +table.insert(crops.plants, { name = "crops:tomato_plant_3", wateruse = 1.0, wither = crops.tomato_die }) +table.insert(crops.plants, { name = "crops:tomato_plant_4", wateruse = 1.0, wither = crops.tomato_die }) +table.insert(crops.plants, { name = "crops:tomato_plant_5", wateruse = 1.0, wither = crops.tomato_die }) + | 
