274 lines
8.6 KiB
Lua
274 lines
8.6 KiB
Lua
local MODNAME = "waterican"
|
|
|
|
--
|
|
-- Waterican (by gravgun)
|
|
-- v1.2
|
|
-- A mod that add watering cans that make crops grow faster.
|
|
--
|
|
-- LICENSE: GPLv3+
|
|
-- ('cuz every time you use proprietary software, a kitten dies)
|
|
--
|
|
-- Why that name?
|
|
-- Because somehow when I wrote "watering can" fast I actually wrote "waterican".
|
|
--
|
|
|
|
local function rn() return math.random()-.5 end
|
|
local function rr(min, max) return min + math.random() * (max-min) end
|
|
|
|
local function waternode(user, pos)
|
|
local node = minetest.get_node(pos)
|
|
local nodedef = minetest.registered_nodes[node.name]
|
|
if nodedef == nil then
|
|
return -- dafuq?
|
|
end
|
|
|
|
-- General soil wetting
|
|
local soil = nodedef.soil
|
|
if soil and node.name == soil.dry then
|
|
minetest.set_node(pos, {name=soil.wet})
|
|
return
|
|
end
|
|
|
|
-- Farming soil wetting (compatibility with Farming Redo)
|
|
if node.name == "farming:soil" then
|
|
minetest.set_node(pos, {name="farming:soil_wet"})
|
|
return
|
|
end
|
|
|
|
-- Seed growth
|
|
if minetest.get_item_group(node.name, "seed") > 0 and nodedef.fertility then
|
|
local grow = false
|
|
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
|
if node_under == nil then
|
|
return
|
|
end
|
|
-- Can this seed grow on the node that's beneath it?
|
|
for _, v in pairs(nodedef.fertility) do
|
|
if minetest.get_item_group(node_under.name, v) > 0 then
|
|
grow = true
|
|
end
|
|
end
|
|
if grow then
|
|
minetest.set_node(pos, {name=node.name:gsub("seed_", "") .. "_1"})
|
|
end
|
|
return
|
|
end
|
|
|
|
-- Plant growth
|
|
local plant_nbr_s, plant_nbr_e = string.find(node.name, "_[0-9]+$")
|
|
if minetest.get_item_group(node.name, "plant") > 0 and plant_nbr_s then
|
|
local plant_nbr = tonumber(string.sub(node.name, plant_nbr_s+1, plant_nbr_e))
|
|
local orig_name = string.sub(node.name, 0, plant_nbr_s)
|
|
local next = orig_name .. (plant_nbr+1)
|
|
if minetest.registered_nodes[next] then
|
|
minetest.set_node(pos, {name=next})
|
|
end
|
|
return
|
|
end
|
|
|
|
-- Cactus growth
|
|
if node.name == "default:cactus" then
|
|
default.grow_cactus(pos, minetest.get_node(pos))
|
|
return
|
|
end
|
|
|
|
-- Papyrus growth
|
|
if node.name == "default:papyrus" then
|
|
default.grow_papyrus(pos, minetest.get_node(pos))
|
|
return
|
|
end
|
|
|
|
-- Grow grass on dirt
|
|
-- Convery dry grass to grass
|
|
if (node.name == "default:dirt" and minetest.find_node_near(pos, 1, {"default:dirt_with_grass"}))
|
|
or (node.name == "default:dirt_with_dry_grass")
|
|
and math.random() > 0.4 then
|
|
local above = {x = pos.x, y = pos.y + 1, z = pos.z}
|
|
local name = minetest.get_node(above).name
|
|
local above_nodedef = minetest.registered_nodes[name]
|
|
if name ~= "ignore" and above_nodedef and
|
|
((above_nodedef.sunlight_propagates or above_nodedef.paramtype == "light") and above_nodedef.liquidtype == "none") then
|
|
minetest.set_node(pos, {name="default:dirt_with_grass"})
|
|
end
|
|
return
|
|
end
|
|
|
|
-- Put out fire
|
|
if node.name == "fire:basic_flame" then
|
|
minetest.set_node(pos, {name="air"})
|
|
minetest.sound_play("default_cool_lava",
|
|
{pos = pos, max_hear_distance = 16, gain = 0.25})
|
|
return
|
|
end
|
|
|
|
-- Tree growth
|
|
if math.random() > 0.9 then
|
|
-- The code in this `if` statement is copied from the `default` mod, therefore is LGPLv2.1+.
|
|
-- If Minetest coredevs had the lil' idea to plan ahead, they would have **named** ABMs
|
|
-- so we can reuse them OR added a way to force ABMs to trigger on certain nodes.
|
|
-- But no, they seem way too dumb for that simple shit.
|
|
local node_under = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
|
if not node_under then
|
|
return
|
|
end
|
|
local name_under = node_under.name
|
|
local is_soil = minetest.get_item_group(name_under, "soil")
|
|
if is_soil == 0 then
|
|
return
|
|
end
|
|
|
|
local mapgen = minetest.get_mapgen_params().mgname
|
|
if node.name == "default:sapling" then
|
|
minetest.log("action", "A sapling grows into a tree at "..
|
|
minetest.pos_to_string(pos))
|
|
if mapgen == "v6" then
|
|
default.grow_tree(pos, random(1, 4) == 1)
|
|
else
|
|
default.grow_new_apple_tree(pos)
|
|
end
|
|
elseif node.name == "default:junglesapling" then
|
|
minetest.log("action", "A jungle sapling grows into a tree at "..
|
|
minetest.pos_to_string(pos))
|
|
if mapgen == "v6" then
|
|
default.grow_jungle_tree(pos)
|
|
else
|
|
default.grow_new_jungle_tree(pos)
|
|
end
|
|
elseif node.name == "default:pine_sapling" then
|
|
minetest.log("action", "A pine sapling grows into a tree at "..
|
|
minetest.pos_to_string(pos))
|
|
if mapgen == "v6" then
|
|
default.grow_pine_tree(pos)
|
|
else
|
|
default.grow_new_pine_tree(pos)
|
|
end
|
|
elseif node.name == "default:acacia_sapling" then
|
|
minetest.log("action", "An acacia sapling grows into a tree at "..
|
|
minetest.pos_to_string(pos))
|
|
default.grow_new_acacia_tree(pos)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function water(user, minp, maxp, chance)
|
|
for x=minp.x,maxp.x do
|
|
for y=minp.y,maxp.y do
|
|
for z=minp.z,maxp.z do
|
|
if math.random() < chance then
|
|
waternode(user, {x=x, y=y, z=z})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local particle_count = math.random(1, 4) * (maxp.x-minp.x+1) * (maxp.z-minp.z+1)
|
|
for _=0,particle_count do
|
|
minetest.add_particle({
|
|
pos = {x = rr(minp.x, maxp.x), y = maxp.y + 0.7, z = rr(minp.z, maxp.z) },
|
|
vel = {x=rn()*.6, y=0, z=rn()*.6},
|
|
acc = {x=0, y=-10, z=0},
|
|
expirationtime = math.random()*2+1,
|
|
size = 1,
|
|
collisiondetection = true,
|
|
vertical = false,
|
|
texture = "waterican_droplet.png",
|
|
playername = user:get_player_name()
|
|
})
|
|
end
|
|
end
|
|
|
|
local function reg_waterican(def)
|
|
local img = "waterican_waterican.png"
|
|
if def.color then
|
|
img = img .. "^[colorize:" .. def.color .. "^waterican_waterican_alphaoverlay.png"
|
|
end
|
|
local matname = ""
|
|
if def.materialname then
|
|
matname = " (" .. def.materialname .. ")"
|
|
end
|
|
local toolname = MODNAME .. ":waterican_" .. def.material
|
|
minetest.register_tool(toolname, {
|
|
description = "Waterican" .. matname,
|
|
liquids_pointable = true,
|
|
inventory_image = img,
|
|
wield_image = img .. "^[transformFX",
|
|
wield_scale = {x = 1, y = 1, z = 6},
|
|
on_use = function(itemstack, user, pointed_thing)
|
|
local wear = itemstack:get_wear()
|
|
|
|
-- Refill if pointing at water and not already full
|
|
if pointed_thing.type == "node" then
|
|
local node = minetest.get_node(pointed_thing.under)
|
|
-- Don't check for default, since Watericans that
|
|
-- wear out are only available if default is.
|
|
if node.name == "default:water_source" then
|
|
if wear > 0 then
|
|
itemstack:set_wear(0)
|
|
minetest.set_node(pointed_thing.under, {name="air"})
|
|
return itemstack
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
-- Worn out = no more water.
|
|
if wear == 65534 then
|
|
return
|
|
end
|
|
|
|
if pointed_thing.type == "node" then
|
|
p = pointed_thing.under
|
|
if user:get_player_control().sneak then
|
|
water(user, {x=p.x,y=p.y-1,z=p.z}, p, def.chance)
|
|
else
|
|
water(user, {x=p.x-1,y=p.y-1,z=p.z-1}, {x=p.x+1,y=p.y,z=p.z+1}, def.chance)
|
|
end
|
|
end
|
|
if def.uses then
|
|
local wearadd = 0
|
|
if user:get_player_control().sneak then
|
|
wearadd = 65534/(def.uses*9)+1
|
|
else
|
|
wearadd = 65534/def.uses+1
|
|
end
|
|
wearadd = math.min(wearadd, 65534-wear)
|
|
itemstack:add_wear(wearadd)
|
|
return itemstack
|
|
end
|
|
end
|
|
})
|
|
return toolname
|
|
end
|
|
|
|
reg_waterican({material = "op", chance = 1})
|
|
if default then
|
|
local reg_craft = function(...) end
|
|
if bucket then
|
|
reg_craft = function (out, item)
|
|
minetest.register_craft({
|
|
output = out,
|
|
recipe = {
|
|
{"", "", item},
|
|
{item, "bucket:bucket_water", item},
|
|
{"", item, ""}
|
|
},
|
|
replacements = {
|
|
{"bucket:bucket_water", "bucket:bucket_empty", ""}
|
|
}
|
|
})
|
|
end
|
|
end
|
|
reg_craft(reg_waterican({material = "diamond", materialname = "Diamond", color = "#00FFFF", uses = 60, chance = 0.8}),
|
|
"default:diamond")
|
|
reg_craft(reg_waterican({material = "mese", materialname = "Mese", color = "#FFFF00", uses = 50, chance = 0.7}),
|
|
"default:mese_crystal")
|
|
reg_craft(reg_waterican({material = "gold", materialname = "Gold", color = "#E6C717", uses = 40, chance = 0.6}),
|
|
"default:gold_ingot")
|
|
reg_craft(reg_waterican({material = "steel", materialname = "Steel", color = "#CCCCCC", uses = 30, chance = 0.5}),
|
|
"default:steel_ingot")
|
|
reg_craft(reg_waterican({material = "bronze", materialname = "Bronze", color = "#FF873D", uses = 20, chance = 0.4}),
|
|
"default:bronze_ingot")
|
|
reg_craft(reg_waterican({material = "stone", materialname = "Stone", color = "#7F7F7F", uses = 15, chance = 0.3}),
|
|
"default:cobble")
|
|
reg_craft(reg_waterican({material = "wood", materialname = "Wood", color = "#6C4913", uses = 10, chance = 0.2}),
|
|
"group:wood")
|
|
end |