Rewrite Farming with timers, no abms
Now it doesn't matter anymore if a plant has got three or eight steps, the time that is needed to grow the crop can be set in seconds (average). Average time to grow: wheat: 500s cotton: 520s potato: 450s You can change near everything of the nodes / items now. I also cleaned up code of hoes a little bit. Updated / Improved the documentation. Rewrote complete farming mod ~85-90%! ~8h of work, with testing, bug fixing and documentation writing...master
parent
59bf16dc25
commit
401b8c1df7
92
game_api.txt
92
game_api.txt
|
@ -137,35 +137,89 @@ Farming API
|
|||
-----------
|
||||
The farming API allows you to easily register plants and hoes.
|
||||
|
||||
farming.register_hoe(name, hoe definition)
|
||||
-> Register a new hoe, see [#hoe definition]
|
||||
farming.register_hoe(name, def)
|
||||
-> name: The name/itemstring of the hoe (e.g. "farming:hoe_diamond")
|
||||
-> def: See [#Hoe definition]
|
||||
|
||||
farming.register_plant(name, Plant definition)
|
||||
-> Register a new growing plant, see [#Plant definition]
|
||||
farming.register_crop(name, def)
|
||||
-> name: The name of the crop (e.g. "wheat")
|
||||
-> def: See [#Plant definition]
|
||||
|
||||
#Hoe Definition
|
||||
---------------
|
||||
{
|
||||
description = "", -- Description for tooltip
|
||||
inventory_image = "unknown_item.png", -- Image to be used as wield- and inventory image
|
||||
max_uses = 30, -- Uses until destroyed
|
||||
material = "", -- Material for recipes
|
||||
recipe = { -- Craft recipe, if material isn't used
|
||||
{"air", "air", "air"},
|
||||
{"", "group:stick"},
|
||||
{"", "group:stick"},
|
||||
}
|
||||
description = "Diamond Hoe",
|
||||
^ Description for tooltip
|
||||
|
||||
inventory_image = "farming_tool_diamondhoe.png",
|
||||
^ Image to be used as wield- and inventory image
|
||||
|
||||
max_uses = 540,
|
||||
^ Uses until destroyed
|
||||
|
||||
material = "default:diamond",
|
||||
^ Material for recipes
|
||||
|
||||
recipe = {
|
||||
^ Craft recipe, if material isn't used
|
||||
{"air", "air" },
|
||||
{"", "group:stick"},
|
||||
{"", "group:stick"},
|
||||
},
|
||||
}
|
||||
|
||||
#Plant definition
|
||||
-----------------
|
||||
{
|
||||
description = "", -- Description of seed item
|
||||
inventory_image = "unknown_item.png", -- Image to be used as seed's wield- and inventory image
|
||||
steps = 8, -- How many steps the plant has to grow, until it can be harvested
|
||||
^ Always provide a plant texture for each step, format: modname_plantname_i.png (i = stepnumber)
|
||||
minlight = 13, -- Minimum light to grow
|
||||
maxlight = default.LIGHT_MAX -- Maximum light to grow
|
||||
description = "Wheat",
|
||||
^ Description of the crop / harvest. Required!
|
||||
If no special seed description is specified then it'll be description.." Seed"
|
||||
|
||||
texture_prefix = "farming_wheat",
|
||||
^ This will be used for all textures as a prefix.
|
||||
If it's not defined it'll equal "farming_" .. name -> "farming_wheat"
|
||||
|
||||
Here are some examples:
|
||||
seed: texture_prefix .. "_seed.png" -> "farming_wheat_seed.png"
|
||||
harvest: texture_prefix .. ".png" -> "farming_wheat.png"
|
||||
plant steps: texture_prefix .. "_" .. step .. ".png" -> "farming_wheat_1.png"
|
||||
|
||||
steps = 8,
|
||||
^ How many steps the plant has to grow, until it can be harvested. Required!
|
||||
|
||||
growtime = 500,
|
||||
^ The average time that is needed to grow the plant (all steps). Required!
|
||||
|
||||
has_seed = true,
|
||||
^ If a seed of the plant should be registered. (default value: true)
|
||||
If false, you'll be able to implant the harvest directly.
|
||||
|
||||
cond = {
|
||||
^ Conditions for growing
|
||||
fertility = {"grassland"},
|
||||
^ The fertility of the soil (wheat can't grow on desert sand soil, but on normal soil)
|
||||
|
||||
light = {min = 13, max = default.LIGHT_MAX},
|
||||
^ The minimum and maximum light level to grow
|
||||
},
|
||||
|
||||
craft_seed_by_harvest = true,
|
||||
^ Should the harvest be craftable into a seed (default value: false)
|
||||
|
||||
plant = {
|
||||
-- Here you can add special properties for all steps of the plant
|
||||
-- See [Node definition]
|
||||
},
|
||||
|
||||
seed = {
|
||||
-- Here you can add special properties for the seed
|
||||
-- See [Item definition]
|
||||
},
|
||||
|
||||
harvest = {
|
||||
-- Here you can add special properties for the harvest
|
||||
-- See [Item definition]
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -438,7 +438,7 @@ core.register_biome({
|
|||
--node_river_water = "",
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
heat_point = 95,
|
||||
heat_point = 90,
|
||||
humidity_point = 50,
|
||||
})
|
||||
|
||||
|
@ -456,7 +456,7 @@ core.register_biome({
|
|||
--node_river_water = "",
|
||||
y_min = -3,
|
||||
y_max = 0,
|
||||
heat_point = 95,
|
||||
heat_point = 90,
|
||||
humidity_point = 50,
|
||||
})
|
||||
|
||||
|
@ -474,7 +474,7 @@ core.register_biome({
|
|||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = -4,
|
||||
heat_point = 95,
|
||||
heat_point = 90,
|
||||
humidity_point = 50,
|
||||
})
|
||||
|
||||
|
@ -492,7 +492,7 @@ core.register_biome({
|
|||
--node_river_water = "",
|
||||
y_min = 1,
|
||||
y_max = 31000,
|
||||
heat_point = 95,
|
||||
heat_point = 80,
|
||||
humidity_point = 90,
|
||||
})
|
||||
|
||||
|
@ -510,7 +510,7 @@ core.register_biome({
|
|||
--node_river_water = "",
|
||||
y_min = -3,
|
||||
y_max = 0,
|
||||
heat_point = 95,
|
||||
heat_point = 80,
|
||||
humidity_point = 90,
|
||||
})
|
||||
|
||||
|
@ -528,7 +528,7 @@ core.register_biome({
|
|||
--node_river_water = "",
|
||||
y_min = -112,
|
||||
y_max = -4,
|
||||
heat_point = 95,
|
||||
heat_point = 80,
|
||||
humidity_point = 90,
|
||||
})
|
||||
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
This mod is part of Minetest TNG
|
||||
================================
|
||||
Farming++
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
Copyright (C) 2016 LNJ <lnj.git@gmail.com>
|
||||
Copyright (C) 2014 webdesigner97
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
at your option) any later version.
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
core.register_alias("farming:seed_wheat", "farming:wheat_seed")
|
||||
core.register_alias("farming:seed_cotton", "farming:cotton_seed")
|
||||
|
||||
core.register_alias("farming:string", "farming:cotton")
|
|
@ -1,124 +1,3 @@
|
|||
-- Wear out hoes, place soil
|
||||
-- TODO Ignore group:flower
|
||||
farming.hoe_on_use = function(itemstack, user, pointed_thing, uses)
|
||||
local pt = pointed_thing
|
||||
-- check if pointing at a node
|
||||
if not pt then
|
||||
return
|
||||
end
|
||||
if pt.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local under = core.get_node(pt.under)
|
||||
local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z}
|
||||
local above = core.get_node(p)
|
||||
|
||||
-- return if any of the nodes is not registered
|
||||
if not core.registered_nodes[under.name] then
|
||||
return
|
||||
end
|
||||
if not core.registered_nodes[above.name] then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if the node above the pointed thing is air
|
||||
if above.name ~= "air" then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if pointing at soil
|
||||
if core.get_item_group(under.name, "soil") ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if (wet) soil defined
|
||||
local regN = core.registered_nodes
|
||||
if regN[under.name].soil == nil or regN[under.name].soil.wet == nil or regN[under.name].soil.dry == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if core.is_protected(pt.under, user:get_player_name()) then
|
||||
core.record_protection_violation(pt.under, user:get_player_name())
|
||||
return
|
||||
end
|
||||
if core.is_protected(pt.above, user:get_player_name()) then
|
||||
core.record_protection_violation(pt.above, user:get_player_name())
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- turn the node into soil, wear out item and play sound
|
||||
core.set_node(pt.under, {name = regN[under.name].soil.dry})
|
||||
core.sound_play("default_dig_crumbly", {
|
||||
pos = pt.under,
|
||||
gain = 0.5,
|
||||
})
|
||||
|
||||
if not core.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/(uses-1))
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Register new hoes
|
||||
farming.register_hoe = function(name, def)
|
||||
-- Check for : prefix (register new hoes in your mod's namespace)
|
||||
if name:sub(1, 1) ~= ":" then
|
||||
name = ":" .. name
|
||||
end
|
||||
-- Check def table
|
||||
if def.description == nil then
|
||||
def.description = "Hoe"
|
||||
end
|
||||
if def.inventory_image == nil then
|
||||
def.inventory_image = "unknown_item.png"
|
||||
end
|
||||
if def.recipe == nil then
|
||||
def.recipe = {
|
||||
{"air","air",""},
|
||||
{"","group:stick",""},
|
||||
{"","group:stick",""}
|
||||
}
|
||||
end
|
||||
if def.max_uses == nil then
|
||||
def.max_uses = 30
|
||||
end
|
||||
-- Register the tool
|
||||
core.register_tool(name, {
|
||||
description = def.description,
|
||||
inventory_image = def.inventory_image,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
return farming.hoe_on_use(itemstack, user, pointed_thing, def.max_uses)
|
||||
end
|
||||
})
|
||||
-- Register its recipe
|
||||
if def.material == nil then
|
||||
core.register_craft({
|
||||
output = name:sub(2),
|
||||
recipe = def.recipe
|
||||
})
|
||||
else
|
||||
core.register_craft({
|
||||
output = name:sub(2),
|
||||
recipe = {
|
||||
{def.material, def.material, ""},
|
||||
{"", "group:stick", ""},
|
||||
{"", "group:stick", ""}
|
||||
}
|
||||
})
|
||||
-- Reverse Recipe
|
||||
core.register_craft({
|
||||
output = name:sub(2),
|
||||
recipe = {
|
||||
{"", def.material, def.material},
|
||||
{"", "group:stick", ""},
|
||||
{"", "group:stick", ""}
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- Seed placement
|
||||
farming.place_seed = function(itemstack, placer, pointed_thing, plantname)
|
||||
local pt = pointed_thing
|
||||
|
@ -167,202 +46,230 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname)
|
|||
end
|
||||
|
||||
-- add the node and remove 1 item from the itemstack
|
||||
local ndef = core.registered_items[plantname]
|
||||
if ndef and not ndef.drawtype then
|
||||
plantname = plantname .. "_1"
|
||||
end
|
||||
core.set_node(pt.above, {name = plantname, param2 = 1})
|
||||
|
||||
if not core.setting_getbool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Register plants
|
||||
farming.register_plant = function(def)
|
||||
local mname = "farming" or def.modname
|
||||
local pname = def.plantname
|
||||
|
||||
-- Check def table
|
||||
if not def.description then
|
||||
def.description = "Seed"
|
||||
end
|
||||
if not def.inventory_image then
|
||||
def.inventory_image = "unknown_item.png"
|
||||
end
|
||||
if not def.steps then
|
||||
return nil
|
||||
end
|
||||
if not def.minlight then
|
||||
def.minlight = 1
|
||||
end
|
||||
if not def.maxlight then
|
||||
def.maxlight = 14
|
||||
end
|
||||
if not def.fertility then
|
||||
def.fertility = {}
|
||||
end
|
||||
if def.has_seed ~= false then
|
||||
def.has_seed = true
|
||||
end
|
||||
if not def.seed then
|
||||
def.seed = {}
|
||||
end
|
||||
if not def.harvest then
|
||||
def.harvest = {}
|
||||
end
|
||||
|
||||
|
||||
local groups = {seed = 1, snappy = 3, attached_node = 1}
|
||||
for k, v in pairs(def.fertility) do
|
||||
groups[v] = 1
|
||||
end
|
||||
|
||||
if def.has_seed then
|
||||
-- Register seed
|
||||
core.register_node(":" .. mname .. ":seed_" .. pname, {
|
||||
description = def.seed.description,
|
||||
tiles = {def.seed.inventory_image},
|
||||
inventory_image = def.seed.inventory_image,
|
||||
wield_image = def.seed.inventory_image,
|
||||
drawtype = "signlike",
|
||||
groups = groups,
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
walkable = false,
|
||||
sunlight_propagates = true,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
fertility = def.fertility,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname)
|
||||
end,
|
||||
on_use = def.on_use,
|
||||
})
|
||||
|
||||
-- Register harvest
|
||||
core.register_craftitem(":" .. mname .. ":" .. pname, {
|
||||
description = def.harvest.description,
|
||||
inventory_image = def.harvest.inventory_image,
|
||||
})
|
||||
else
|
||||
core.register_craftitem(":" .. mname .. ":" .. pname, {
|
||||
description = def.description,
|
||||
tiles = {def.inventory_image},
|
||||
inventory_image = def.inventory_image,
|
||||
wield_image = def.inventory_image,
|
||||
groups = groups,
|
||||
fertility = def.fertility,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":" .. pname)
|
||||
end,
|
||||
on_use = def.on_use,
|
||||
})
|
||||
end
|
||||
|
||||
-- Register growing steps
|
||||
local max_step = def.steps + 1
|
||||
for i = 1, def.steps do
|
||||
local drop = def.drop or {
|
||||
items = {
|
||||
{items = {mname .. ":" .. pname}, rarity = max_step - i},
|
||||
{items = {mname .. ":" .. pname}, rarity = (max_step - i) * 2},
|
||||
{items = {mname .. ":seed_" .. pname}, rarity = max_step - i},
|
||||
{items = {mname .. ":seed_" .. pname}, rarity = (max_step - i) * 2},
|
||||
}
|
||||
}
|
||||
if def.has_seed == false then
|
||||
drop.items[3] = {items = {mname .. ":" .. pname}, rarity = (max_step - i) * 4}
|
||||
drop.items[4] = {items = {mname .. ":" .. pname}, rarity = (max_step - i) * 6}
|
||||
function farming.can_grow_crop(pos, cond)
|
||||
if not pos or not cond then return false end
|
||||
|
||||
-- Soil
|
||||
soilnode = core.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not soilnode then return false end
|
||||
|
||||
-- Check soil fertility
|
||||
local fert = false
|
||||
for _, f in pairs(cond.fertility) do
|
||||
if core.get_item_group(soilnode.name, f) ~= 0 then
|
||||
fert = true
|
||||
end
|
||||
|
||||
|
||||
local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1}
|
||||
nodegroups[pname] = i
|
||||
core.register_node(":" .. mname .. ":" .. pname .. "_" .. i, {
|
||||
drawtype = "plantlike",
|
||||
waving = 1,
|
||||
tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
drop = drop,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
},
|
||||
groups = nodegroups,
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
})
|
||||
end
|
||||
|
||||
-- Growing ABM
|
||||
core.register_abm({
|
||||
nodenames = {"group:" .. pname, "group:seed"},
|
||||
neighbors = {"group:soil"},
|
||||
interval = 90,
|
||||
chance = 2,
|
||||
action = function(pos, node)
|
||||
local plant_height = core.get_item_group(node.name, pname)
|
||||
|
||||
-- return if already full grown
|
||||
if plant_height == def.steps then
|
||||
return
|
||||
end
|
||||
|
||||
local node_def = core.registered_items[node.name] or nil
|
||||
|
||||
-- grow seed
|
||||
if def.has_seed and core.get_item_group(node.name, "seed") and node_def.fertility then
|
||||
local can_grow = false
|
||||
local soil_node = core.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not soil_node then
|
||||
return
|
||||
end
|
||||
for _, v in pairs(node_def.fertility) do
|
||||
if core.get_item_group(soil_node.name, v) ~= 0 then
|
||||
can_grow = true
|
||||
end
|
||||
end
|
||||
if can_grow then
|
||||
core.set_node(pos, {name = node.name:gsub("seed_", "") .. "_1"})
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- check if on wet soil
|
||||
pos.y = pos.y - 1
|
||||
local n = core.get_node(pos)
|
||||
if core.get_item_group(n.name, "soil") < 3 then
|
||||
return
|
||||
end
|
||||
pos.y = pos.y + 1
|
||||
|
||||
-- check light
|
||||
local light_level = core.get_node_light(pos)
|
||||
|
||||
if not light_level or light_level < def.minlight or light_level > def.maxlight then
|
||||
return
|
||||
end
|
||||
|
||||
-- grow
|
||||
core.set_node(pos, {name = mname .. ":" .. pname .. "_" .. plant_height + 1})
|
||||
end
|
||||
})
|
||||
|
||||
-- Return definition table
|
||||
local retval = {
|
||||
seed = mname .. ":seed_" .. pname,
|
||||
harvest = mname .. ":" .. pname
|
||||
}
|
||||
|
||||
if def.has_seed == false then
|
||||
retval = {
|
||||
seed = mname .. ":" .. pname,
|
||||
harvest = mname .. ":" .. pname
|
||||
}
|
||||
if fert == false then return false end
|
||||
|
||||
-- Check if soil is wet
|
||||
if core.get_item_group(soilnode.name, "soil") < 3 then -- dont grow if on dry soil
|
||||
return false
|
||||
end
|
||||
|
||||
-- Check light
|
||||
local light = core.get_node_light(pos)
|
||||
|
||||
if not light or light < cond.light.min or light > cond.light.max then
|
||||
return false
|
||||
end
|
||||
|
||||
--[[
|
||||
-- Check heat
|
||||
local heat = core.get_heat(pos)
|
||||
|
||||
if not heat or heat < cond.heat.min or heat > cond.heat.max then
|
||||
return false
|
||||
end
|
||||
|
||||
-- Check humidity
|
||||
local humidity = core.get_humidity(pos)
|
||||
|
||||
if not humidity or humidity < cond.humidity.min or humidity > cond.humidity.max then
|
||||
return false
|
||||
end
|
||||
--]]
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function start_timer(pos, growtime)
|
||||
growtime = growtime * default.GROW_TIME_FACTOR
|
||||
|
||||
core.get_node_timer(pos):start(math.random(growtime * 0.6, growtime * 1.8))
|
||||
end
|
||||
|
||||
local function next_step(pos, new_name, growtime, cond)
|
||||
if farming.can_grow_crop(pos, cond) == false then
|
||||
start_timer(pos, growtime / 3) -- retry; only a third of the normal growing time
|
||||
return
|
||||
end
|
||||
-- update plant
|
||||
core.set_node(pos, {name = new_name})
|
||||
end
|
||||
|
||||
function farming.register_crop(name, def)
|
||||
if not def.steps or not def.growtime then return false end
|
||||
|
||||
def.texture_prefix = def.texture_prefix or "farming_" .. name
|
||||
|
||||
def.harvest = def.harvest or {}
|
||||
def.seed = def.seed or {}
|
||||
def.plant = def.plant or {}
|
||||
|
||||
def.cond = def.cond or {}
|
||||
def.cond.fertility = def.cond.fertility or {}
|
||||
def.cond.light = def.cond.light or {min = 13, max = default.LIGHT_MAX}
|
||||
-- def.cond.heat = def.cond.heat or {min = 30, max = 80}
|
||||
-- def.cond.humidity = def.cond.humidity or {min = 22, max = 95}
|
||||
|
||||
if def.has_seed ~= false then def.has_seed = true end
|
||||
|
||||
-- +-----------------------------------------------------------------------------+
|
||||
-- | Plant Steps |
|
||||
-- +-----------------------------------------------------------------------------+
|
||||
|
||||
local plantdef = {}
|
||||
plantdef[0] = def.plant
|
||||
|
||||
-- properties for all steps
|
||||
plantdef[0].drawtype = "plantlike"
|
||||
plantdef[0].waving = 1
|
||||
plantdef[0].paramtype = "light"
|
||||
plantdef[0].walkable = false
|
||||
plantdef[0].buildable_to = true
|
||||
plantdef[0].selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
|
||||
}
|
||||
plantdef[0].sounds = plantdef[0].sounds or default.node_sound_leaves_defaults()
|
||||
plantdef[0].groups = plantdef[0].groups or {snappy = 3, flammable = 2, attached_node = 1}
|
||||
plantdef[0].groups.plant = 1
|
||||
plantdef[0].groups.not_in_creative_inventory = 1
|
||||
for k, v in pairs(def.cond.fertility) do
|
||||
plantdef[0].groups[v] = 1
|
||||
end
|
||||
|
||||
|
||||
for i = 1, def.steps do
|
||||
local percent = 100 / def.steps * i
|
||||
|
||||
-- properties (different from step to step)
|
||||
plantdef[i] = table.copy(plantdef[0])
|
||||
|
||||
plantdef[i].description = (def.description or "Plant") .. " (" .. percent .. "% Grown)"
|
||||
plantdef[i].tiles = {def.texture_prefix .. "_" .. i .. ".png"}
|
||||
plantdef[i].groups[name] = i
|
||||
|
||||
|
||||
-- growing
|
||||
if def.steps == i then -- if already fully grown, do not grow
|
||||
plantdef[i].on_timer = nil
|
||||
plantdef[i].on_construct = nil
|
||||
else
|
||||
plantdef[i].on_construct = function(pos)
|
||||
start_timer(pos, def.growtime / def.steps)
|
||||
end
|
||||
|
||||
plantdef[i].on_timer = function(pos, elapsed)
|
||||
next_step(pos, "farming:" .. name .. "_" .. i + 1, def.growtime / def.steps, def.cond) -- see above
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Drop
|
||||
--
|
||||
|
||||
-- seed and harvest name
|
||||
local seedname_ = def.seed.name or "farming:" .. name .. "_seed"
|
||||
if def.has_seed == false then
|
||||
seedname_ = def.harvest.name or "farming:" .. name
|
||||
end
|
||||
|
||||
local harvestname_ = def.harvest.name or "farming:" .. name
|
||||
|
||||
plantdef[i].drop = {items = {}}
|
||||
|
||||
|
||||
-- ever drop a seed
|
||||
table.insert(plantdef[i].drop.items, {items = {seedname_}, rarity = 1})
|
||||
-- if fully grown
|
||||
if def.steps == i then
|
||||
-- random a second seed
|
||||
table.insert(plantdef[i].drop.items, {items = {seedname_}, rarity = 2})
|
||||
|
||||
-- harvest
|
||||
table.insert(plantdef[i].drop.items, {items = {harvestname_}, rarity = 1})
|
||||
table.insert(plantdef[i].drop.items, {items = {harvestname_}, rarity = 2})
|
||||
end
|
||||
|
||||
|
||||
core.register_node(":farming:" .. name .. "_" .. i, plantdef[i])
|
||||
end
|
||||
|
||||
|
||||
-- +-----------------------------------------------------------------------------+
|
||||
-- | Items |
|
||||
-- +-----------------------------------------------------------------------------+
|
||||
|
||||
--
|
||||
-- Seed
|
||||
--
|
||||
|
||||
if def.has_seed then
|
||||
local seeddef = def.seed
|
||||
local seedname = def.seed.name or ":farming:" .. name .. "_seed"
|
||||
seeddef.name = nil
|
||||
|
||||
-- properties
|
||||
seeddef.description = seeddef.description or def.description .. " Seed"
|
||||
seeddef.inventory_image = seeddef.inventory_image or def.texture_prefix .. "_seed.png"
|
||||
|
||||
seeddef.on_place = function(itemstack, placer, pointed_thing)
|
||||
return farming.place_seed(itemstack, placer, pointed_thing, "farming:" .. name .. "_1")
|
||||
end
|
||||
|
||||
core.register_craftitem(seedname, seeddef)
|
||||
end
|
||||
|
||||
--
|
||||
-- Harvest
|
||||
--
|
||||
|
||||
local harvestdef = def.harvest
|
||||
local harvestname = def.harvest.name or ":farming:" .. name
|
||||
|
||||
harvestdef.name = nil
|
||||
|
||||
harvestdef.inventory_image = harvestdef.inventory_image or def.texture_prefix .. ".png"
|
||||
harvestdef.description = harvestdef.description or def.description
|
||||
|
||||
if def.harvest_plantable == true or def.has_seed == false then
|
||||
harvestdef.on_place = function(itemstack, placer, pointed_thing)
|
||||
return farming.place_seed(itemstack, placer, pointed_thing, "farming:" .. name .. "_1")
|
||||
end
|
||||
end
|
||||
|
||||
core.register_craftitem(harvestname, harvestdef)
|
||||
|
||||
--
|
||||
-- Crafting
|
||||
--
|
||||
|
||||
if def.craft_seed_by_harvest == true then
|
||||
core.register_craft({
|
||||
output = def.seed.name or "farming:" .. name .. "_seed",
|
||||
recipe = {
|
||||
{def.harvest.name or "farming:" .. name}
|
||||
}
|
||||
})
|
||||
end
|
||||
return retval
|
||||
end
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
farming.hoe_on_use = function(itemstack, user, pointed_thing, uses)
|
||||
local pt = pointed_thing
|
||||
-- check if pointing at a node
|
||||
if not pt then
|
||||
return
|
||||
end
|
||||
if pt.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local under = core.get_node(pt.under)
|
||||
local p = {x = pt.under.x, y = pt.under.y + 1, z = pt.under.z}
|
||||
local above = core.get_node(p)
|
||||
|
||||
-- return if any of the nodes is not registered
|
||||
if not core.registered_nodes[under.name] then
|
||||
return
|
||||
end
|
||||
if not core.registered_nodes[above.name] then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if the node above the pointed thing is air
|
||||
if above.name ~= "air" then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if pointing at soil
|
||||
if core.get_item_group(under.name, "soil") ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if (wet) soil defined
|
||||
local regN = core.registered_nodes
|
||||
if regN[under.name].soil == nil or regN[under.name].soil.wet == nil or regN[under.name].soil.dry == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if core.is_protected(pt.under, user:get_player_name()) then
|
||||
core.record_protection_violation(pt.under, user:get_player_name())
|
||||
return
|
||||
end
|
||||
if core.is_protected(pt.above, user:get_player_name()) then
|
||||
core.record_protection_violation(pt.above, user:get_player_name())
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
-- turn the node into soil, wear out item and play sound
|
||||
core.set_node(pt.under, {name = regN[under.name].soil.dry})
|
||||
core.sound_play("default_dig_crumbly", {
|
||||
pos = pt.under,
|
||||
gain = 0.5,
|
||||
})
|
||||
|
||||
if not core.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/(uses-1))
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Register new hoes
|
||||
farming.register_hoe = function(name, def)
|
||||
-- Check for : prefix (register new hoes in your mod's namespace)
|
||||
if name:sub(1, 1) ~= ":" then
|
||||
name = ":" .. name
|
||||
end
|
||||
|
||||
local recipe = def.recipe or {
|
||||
{def.material or "air", def.material or "air"},
|
||||
{"", "group:stick"},
|
||||
{"", "group:stick"}
|
||||
}
|
||||
|
||||
-- clean up
|
||||
def.material = nil
|
||||
def.recipe = nil
|
||||
|
||||
|
||||
-- Check def table
|
||||
def.description = def.description or "Hoe"
|
||||
def.inventory_image = def.inventory_image or "unknown_item.png"
|
||||
def.max_uses = def.max_uses or 30
|
||||
|
||||
def.on_use = function(itemstack, user, pointed_thing)
|
||||
return farming.hoe_on_use(itemstack, user, pointed_thing, def.max_uses)
|
||||
end
|
||||
|
||||
-- Register the tool
|
||||
core.register_tool(name, def)
|
||||
|
||||
|
||||
-- Register its recipe
|
||||
if not recipe or def.no_craft then
|
||||
core.register_craft({
|
||||
output = name:sub(2),
|
||||
recipe = recipe
|
||||
})
|
||||
end
|
||||
end
|
|
@ -1 +1 @@
|
|||
default
|
||||
default
|
|
@ -1,41 +1,41 @@
|
|||
farming.register_hoe(":farming:hoe_wood", {
|
||||
farming.register_hoe("farming:hoe_wood", {
|
||||
description = "Wooden Hoe",
|
||||
inventory_image = "farming_tool_woodhoe.png",
|
||||
max_uses = 30,
|
||||
material = "group:wood"
|
||||
})
|
||||
|
||||
farming.register_hoe(":farming:hoe_stone", {
|
||||
farming.register_hoe("farming:hoe_stone", {
|
||||
description = "Stone Hoe",
|
||||
inventory_image = "farming_tool_stonehoe.png",
|
||||
max_uses = 90,
|
||||
material = "group:stone"
|
||||
})
|
||||
|
||||
farming.register_hoe(":farming:hoe_steel", {
|
||||
farming.register_hoe("farming:hoe_steel", {
|
||||
description = "Steel Hoe",
|
||||
inventory_image = "farming_tool_steelhoe.png",
|
||||
max_uses = 200,
|
||||
material = "default:steel_ingot"
|
||||
})
|
||||
|
||||
farming.register_hoe(":farming:hoe_bronze", {
|
||||
farming.register_hoe("farming:hoe_bronze", {
|
||||
description = "Bronze Hoe",
|
||||
inventory_image = "farming_tool_bronzehoe.png",
|
||||
max_uses = 220,
|
||||
max_uses = 280,
|
||||
material = "default:bronze_ingot"
|
||||
})
|
||||
|
||||
farming.register_hoe(":farming:hoe_mese", {
|
||||
farming.register_hoe("farming:hoe_mese", {
|
||||
description = "Mese Hoe",
|
||||
inventory_image = "farming_tool_mesehoe.png",
|
||||
max_uses = 350,
|
||||
max_uses = 400,
|
||||
material = "default:mese_crystal"
|
||||
})
|
||||
|
||||
farming.register_hoe(":farming:hoe_diamond", {
|
||||
farming.register_hoe("farming:hoe_diamond", {
|
||||
description = "Diamond Hoe",
|
||||
inventory_image = "farming_tool_diamondhoe.png",
|
||||
max_uses = 500,
|
||||
max_uses = 540,
|
||||
material = "default:diamond"
|
||||
})
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
farming = {}
|
||||
farming.path = minetest.get_modpath("farming")
|
||||
-- This file is part of Minetest TNG
|
||||
-- =================================
|
||||
-- mods/farming/init.lua
|
||||
--
|
||||
-- See README.txt for licensing and other information.
|
||||
--
|
||||
|
||||
-- Load files
|
||||
dofile(farming.path .. "/api.lua")
|
||||
dofile(farming.path .. "/nodes.lua")
|
||||
dofile(farming.path .. "/hoes.lua")
|
||||
dofile(farming.path .. "/plants.lua")
|
||||
dofile(farming.path .. "/misc.lua")
|
||||
farming = {}
|
||||
|
||||
local modpath = core.get_modpath("farming")
|
||||
|
||||
dofile(modpath .. "/api.lua")
|
||||
dofile(modpath .. "/api_hoes.lua")
|
||||
dofile(modpath .. "/plants.lua")
|
||||
dofile(modpath .. "/soil.lua")
|
||||
dofile(modpath .. "/hoes.lua")
|
||||
dofile(modpath .. "/misc.lua")
|
||||
dofile(modpath .. "/aliases.lua")
|
||||
|
|
|
@ -1,4 +1,34 @@
|
|||
core.register_alias("farming:string", "farming:cotton")
|
||||
default.register_node("farming:straw", {
|
||||
register = {stair = true, slab = true},
|
||||
description = "Straw",
|
||||
tiles = {"farming_straw.png"},
|
||||
is_ground_content = false,
|
||||
groups = {snappy = 3, flammable = 4},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
stair = {legacy_alias = "stairs:stair_straw"},
|
||||
slab = {legacy_alias = "stairs:slab_straw"},
|
||||
})
|
||||
|
||||
|
||||
for i = 1, 5 do
|
||||
core.override_item("default:grass_"..i, {drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {'farming:seed_wheat'}, rarity = 5},
|
||||
{items = {'default:grass_1'}},
|
||||
}
|
||||
}})
|
||||
end
|
||||
|
||||
core.override_item("default:junglegrass", {
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {'farming:seed_cotton'}, rarity = 8},
|
||||
{items = {'default:junglegrass'}},
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
-- Wool
|
||||
core.register_craft({
|
||||
|
@ -34,4 +64,4 @@ core.register_craft({
|
|||
replacements = {
|
||||
{"bucket:bucket_water", "bucket:bucket_empty"}
|
||||
},
|
||||
})
|
||||
})
|
|
@ -1,46 +1,36 @@
|
|||
-- Wheat
|
||||
farming.register_plant({
|
||||
plantname = "wheat",
|
||||
seed = {
|
||||
description = "Wheat Seed",
|
||||
inventory_image = "farming_wheat_seed.png",
|
||||
},
|
||||
harvest = {
|
||||
description = "Wheat",
|
||||
inventory_image = "farming_wheat.png",
|
||||
},
|
||||
farming.register_crop("wheat", {
|
||||
description = "Wheat",
|
||||
steps = 8,
|
||||
minlight = 13,
|
||||
maxlight = default.LIGHT_MAX,
|
||||
fertility = {"grassland"}
|
||||
growtime = 500,
|
||||
has_seed = true,
|
||||
craft_seed_by_harvest = true,
|
||||
cond = {
|
||||
fertility = {"grassland"},
|
||||
light = {min = 13, max = default.LIGHT_MAX},
|
||||
},
|
||||
})
|
||||
|
||||
-- Cotton
|
||||
farming.register_plant({
|
||||
plantname = "cotton",
|
||||
seed = {
|
||||
description = "Cotton Seeds",
|
||||
inventory_image = "farming_cotton_seed.png",
|
||||
},
|
||||
harvest = {
|
||||
description = "Cotton",
|
||||
inventory_image = "farming_cotton.png",
|
||||
},
|
||||
farming.register_crop("cotton", {
|
||||
description = "Cotton",
|
||||
steps = 8,
|
||||
minlight = 13,
|
||||
maxlight = default.LIGHT_MAX,
|
||||
fertility = {"grassland", "desert"}
|
||||
growtime = 520,
|
||||
has_seed = true,
|
||||
cond = {
|
||||
fertility = {"grassland", "desert"},
|
||||
light = {min = 13, max = default.LIGHT_MAX},
|
||||
},
|
||||
})
|
||||
|
||||
-- Potato
|
||||
farming.register_plant({
|
||||
plantname = "potato",
|
||||
farming.register_crop("potato", {
|
||||
description = "Potato",
|
||||
inventory_image = "farming_potato.png",
|
||||
steps = 3,
|
||||
growtime = 450,
|
||||
has_seed = false,
|
||||
minlight = 13,
|
||||
maxlight = default.LIGHT_MAX,
|
||||
fertility = {"grassland"},
|
||||
on_use = minetest.item_eat(1)
|
||||
cond = {
|
||||
fertility = {"grassland"},
|
||||
light = {min = 13, max = default.LIGHT_MAX},
|
||||
},
|
||||
harvest = {
|
||||
on_use = core.item_eat(1),
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
minetest.override_item("default:dirt", {
|
||||
core.override_item("default:dirt", {
|
||||
groups = {crumbly = 3, soil = 1},
|
||||
soil = {
|
||||
base = "default:dirt",
|
||||
|
@ -7,7 +7,7 @@ minetest.override_item("default:dirt", {
|
|||
}
|
||||
})
|
||||
|
||||
minetest.override_item("default:dirt_with_grass", {
|
||||
core.override_item("default:dirt_with_grass", {
|
||||
groups = {crumbly = 3, soil = 1},
|
||||
soil = {
|
||||
base = "default:dirt_with_grass",
|
||||
|
@ -49,7 +49,7 @@ default.register_node("farming:garden_soil", {
|
|||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
minetest.override_item("default:desert_sand", {
|
||||
core.override_item("default:desert_sand", {
|
||||
groups = {crumbly = 3, falling_node = 1, sand = 1, soil = 1},
|
||||
soil = {
|
||||
base = "default:desert_sand",
|
||||
|
@ -83,23 +83,12 @@ default.register_node("farming:desert_sand_soil_wet", {
|
|||
}
|
||||
})
|
||||
|
||||
default.register_node("farming:straw", {
|
||||
register = {stair = true, slab = true},
|
||||
description = "Straw",
|
||||
tiles = {"farming_straw.png"},
|
||||
is_ground_content = false,
|
||||
groups = {snappy = 3, flammable = 4},
|
||||
sounds = default.node_sound_leaves_defaults(),
|
||||
stair = {legacy_alias = "stairs:stair_straw"},
|
||||
slab = {legacy_alias = "stairs:slab_straw"},
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
core.register_abm({
|
||||
nodenames = {"group:field"},
|
||||
interval = 15,
|
||||
chance = 4,
|
||||
action = function(pos, node)
|
||||
local n_def = minetest.registered_nodes[node.name] or nil
|
||||
local n_def = core.registered_nodes[node.name] or nil
|
||||
if not n_def or not n_def.soil or not n_def.soil.wet or not n_def.soil.base or not n_def.soil.dry then
|
||||
return
|
||||
end
|
||||
|
@ -109,61 +98,40 @@ minetest.register_abm({
|
|||
local dry = n_def.soil.dry
|
||||
|
||||
pos.y = pos.y + 1
|
||||
local nn = minetest.get_node_or_nil(pos)
|
||||
local nn = core.get_node_or_nil(pos)
|
||||
if not nn or not nn.name then
|
||||
return
|
||||
end
|
||||
local nn_def = minetest.registered_nodes[nn.name] or nil
|
||||
local nn_def = core.registered_nodes[nn.name] or nil
|
||||
pos.y = pos.y - 1
|
||||
|
||||
if nn_def and nn_def.walkable and minetest.get_item_group(nn.name, "plant") == 0 then
|
||||
minetest.set_node(pos, {name = base})
|
||||
if nn_def and nn_def.walkable and core.get_item_group(nn.name, "plant") == 0 then
|
||||
core.set_node(pos, {name = base})
|
||||
return
|
||||
end
|
||||
-- check if there is water nearby
|
||||
local wet_lvl = minetest.get_item_group(node.name, "wet")
|
||||
if minetest.find_node_near(pos, 3, {"group:water"}) then
|
||||
local wet_lvl = core.get_item_group(node.name, "wet")
|
||||
if core.find_node_near(pos, 3, {"group:water"}) then
|
||||
-- if it is dry soil and not base node, turn it into wet soil
|
||||
if wet_lvl == 0 then
|
||||
minetest.set_node(pos, {name = wet})
|
||||
core.set_node(pos, {name = wet})
|
||||
end
|
||||
else
|
||||
-- only turn back if there are no unloaded blocks (and therefore
|
||||
-- possible water sources) nearby
|
||||
if not minetest.find_node_near(pos, 3, {"ignore"}) then
|
||||
if not core.find_node_near(pos, 3, {"ignore"}) then
|
||||
-- turn it back into base if it is already dry
|
||||
if wet_lvl == 0 then
|
||||
-- only turn it back if there is no plant/seed on top of it
|
||||
if minetest.get_item_group(nn.name, "plant") == 0 and minetest.get_item_group(nn.name, "seed") == 0 then
|
||||
minetest.set_node(pos, {name = base})
|
||||
if core.get_item_group(nn.name, "plant") == 0 and core.get_item_group(nn.name, "seed") == 0 then
|
||||
core.set_node(pos, {name = base})
|
||||
end
|
||||
|
||||
-- if its wet turn it back into dry soil
|
||||
elseif wet_lvl == 1 then
|
||||
minetest.set_node(pos, {name = dry})
|
||||
core.set_node(pos, {name = dry})
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
for i = 1, 5 do
|
||||
minetest.override_item("default:grass_"..i, {drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {'farming:seed_wheat'}, rarity = 5},
|
||||
{items = {'default:grass_1'}},
|
||||
}
|
||||
}})
|
||||
end
|
||||
|
||||
minetest.override_item("default:junglegrass", {
|
||||
drop = {
|
||||
max_items = 1,
|
||||
items = {
|
||||
{items = {'farming:seed_cotton'}, rarity = 8},
|
||||
{items = {'default:junglegrass'}},
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue