Add Rapeseed

This commit is contained in:
Desour 2020-03-24 18:22:19 +01:00
parent 0a96bac46d
commit c822f94785
24 changed files with 541 additions and 44 deletions

View file

@ -370,7 +370,11 @@ The farming API allows you to easily register plants and hoes.
steps = 8, -- How many steps the plant has to grow, until it can be harvested 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) -- ^ Always provide a plant texture for each step, format: modname_plantname_i.png (i = stepnumber)
minlight = 13, -- Minimum light to grow minlight = 13, -- Minimum light to grow
maxlight = default.LIGHT_MAX -- Maximum light to grow maxlight = default.LIGHT_MAX, -- Maximum light to grow
only_seed = false, -- If true, plant will only drop
-- seeds. plant name is used as
-- name for seed
-- plus some other fields that someone was to lazy to document
} }

View file

@ -45,25 +45,61 @@ for _, row in ipairs(dye.dyes) do
{"group:flower,color_" .. name} {"group:flower,color_" .. name}
}, },
}) })
minetest.register_craft({
type = "shapeless",
output = "dye:" .. name .. " 8",
recipe = {
"group:flower,color_" .. name,
"farming:glass_bottle_with_rapeseed_oil"
},
replacements = {{"farming:glass_bottle_with_rapeseed_oil",
"vessels:glass_bottle"}},
})
end end
-- Manually add coal -> black dye if minetest.get_modpath("default") then
-- Manually add coal -> black dye
minetest.register_craft({ minetest.register_craft({
output = "dye:black 4", output = "dye:black 4",
recipe = { recipe = {
{"group:coal"} {"group:coal"}
}, },
}) })
-- Manually add blueberries->violet dye minetest.register_craft({
type = "shapeless",
output = "dye:black 8",
recipe = {
"group:coal",
"farming:glass_bottle_with_rapeseed_oil"
},
replacements = {{"farming:glass_bottle_with_rapeseed_oil",
"vessels:glass_bottle"}},
})
minetest.register_craft({ -- Manually add blueberries->violet dye
output = "dye:violet 2",
recipe = { minetest.register_craft({
{"default:blueberries"} output = "dye:violet 2",
}, recipe = {
}) {"default:blueberries"}
},
})
minetest.register_craft({
type = "shapeless",
output = "dye:violet 8",
recipe = {
"default:blueberries",
"default:blueberries",
"farming:glass_bottle_with_rapeseed_oil"
},
replacements = {{"farming:glass_bottle_with_rapeseed_oil",
"vessels:glass_bottle"}},
})
end
-- Mix recipes -- Mix recipes

View file

@ -253,8 +253,7 @@ end
-- Register plants -- Register plants
farming.register_plant = function(name, def) farming.register_plant = function(name, def)
local mname = name:split(":")[1] local mname, pname = unpack(name:split(":"))
local pname = name:split(":")[2]
-- Check def table -- Check def table
if not def.description then if not def.description then
@ -278,16 +277,22 @@ farming.register_plant = function(name, def)
if not def.fertility then if not def.fertility then
def.fertility = {} def.fertility = {}
end end
if not def.only_seed then
def.only_seed = false
end
farming.registered_plants[pname] = def farming.registered_plants[pname] = def
local seed_name = def.only_seed and mname .. ":" .. pname
or mname .. ":seed_" .. pname
-- Register seed -- Register seed
local lbm_nodes = {mname .. ":seed_" .. pname} local lbm_nodes = {seed_name}
local g = {seed = 1, snappy = 3, attached_node = 1, flammable = 2} local g = {seed = 1, snappy = 3, attached_node = 1, flammable = 2}
for k, v in pairs(def.fertility) do for k, v in pairs(def.fertility) do
g[v] = 1 g[v] = 1
end end
minetest.register_node(":" .. mname .. ":seed_" .. pname, { minetest.register_node(":" .. seed_name, {
description = def.description, description = def.description,
tiles = {def.inventory_image}, tiles = {def.inventory_image},
inventory_image = def.inventory_image, inventory_image = def.inventory_image,
@ -321,7 +326,7 @@ farming.register_plant = function(name, def)
pointed_thing) or itemstack pointed_thing) or itemstack
end end
return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname) return farming.place_seed(itemstack, placer, pointed_thing, seed_name)
end, end,
next_plant = mname .. ":" .. pname .. "_1", next_plant = mname .. ":" .. pname .. "_1",
on_timer = farming.grow_plant, on_timer = farming.grow_plant,
@ -330,11 +335,13 @@ farming.register_plant = function(name, def)
}) })
-- Register harvest -- Register harvest
minetest.register_craftitem(":" .. mname .. ":" .. pname, { if not def.only_seed then
description = def.harvest_description, minetest.register_craftitem(":" .. mname .. ":" .. pname, {
inventory_image = mname .. "_" .. pname .. ".png", description = def.harvest_description,
groups = def.groups or {flammable = 2}, inventory_image = mname .. "_" .. pname .. ".png",
}) groups = def.groups or {flammable = 2},
})
end
-- Register growing steps -- Register growing steps
for i = 1, def.steps do for i = 1, def.steps do
@ -343,11 +350,15 @@ farming.register_plant = function(name, def)
base_rarity = 8 - (i - 1) * 7 / (def.steps - 1) base_rarity = 8 - (i - 1) * 7 / (def.steps - 1)
end end
local drop = { local drop = {
items = { items = def.only_seed and {
{items = {seed_name}, rarity = base_rarity},
{items = {seed_name}, rarity = base_rarity * 2},
{items = {seed_name}, rarity = base_rarity * 2},
} or {
{items = {mname .. ":" .. pname}, rarity = base_rarity}, {items = {mname .. ":" .. pname}, rarity = base_rarity},
{items = {mname .. ":" .. pname}, rarity = base_rarity * 2}, {items = {mname .. ":" .. pname}, rarity = base_rarity * 2},
{items = {mname .. ":seed_" .. pname}, rarity = base_rarity}, {items = {seed_name}, rarity = base_rarity},
{items = {mname .. ":seed_" .. pname}, rarity = base_rarity * 2}, {items = {seed_name}, rarity = base_rarity * 2},
} }
} }
local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1} local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1}
@ -393,9 +404,8 @@ farming.register_plant = function(name, def)
}) })
-- Return -- Return
local r = { return {
seed = mname .. ":seed_" .. pname, seed = seed_name,
harvest = mname .. ":" .. pname harvest = mname .. ":" .. pname
} }
return r
end end

View file

@ -113,6 +113,22 @@ minetest.register_craft({
}) })
-- Rapeseed
farming.register_plant("farming:rapeseed", {
description = S("Rapeseed"),
inventory_image = "farming_rapeseed.png",
steps = 8,
minlight = 13,
maxlight = default.LIGHT_MAX,
only_seed = true,
fertility = {"grassland", "desert"},
groups = {flammable = 4},
})
dofile(farming.path .. "/rapeseed_oil.lua")
-- Straw -- Straw
minetest.register_craft({ minetest.register_craft({

View file

@ -4,7 +4,7 @@ License of source code
The MIT License (MIT) The MIT License (MIT)
Copyright (C) 2012-2016 PilzAdam Copyright (C) 2012-2016 PilzAdam
Copyright (C) 2014-2016 webdesigner97 Copyright (C) 2014-2016 webdesigner97
Copyright (C) 2012-2016 Various Minetest developers and contributors Copyright (C) 2012-2020 Various Minetest developers and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software software and associated documentation files (the "Software"), to deal in the Software
@ -34,6 +34,7 @@ Copyright (C) 2012-2016 PilzAdam
Copyright (C) 2014-2016 BlockMen Copyright (C) 2014-2016 BlockMen
Copyright (C) 2015-2016 MasterGollum Copyright (C) 2015-2016 MasterGollum
Copyright (C) 2015-2016 Gambit Copyright (C) 2015-2016 Gambit
Copyright (C) 2020 DS
You are free to: You are free to:
Share — copy and redistribute the material in any medium or format. Share — copy and redistribute the material in any medium or format.

View file

@ -1,4 +1,4 @@
name = farming name = farming
description = Minetest Game mod: farming description = Minetest Game mod: farming
depends = default, wool, stairs depends = default, wool, stairs, vessels
optional_depends = dungeon_loot optional_depends = dungeon_loot, creative

View file

@ -233,7 +233,7 @@ minetest.register_abm({
-- Make default:grass_* occasionally drop wheat seed -- Make default:grass_* occasionally drop wheat seed
for i = 1, 5 do for i = 1, 5 do
minetest.override_item("default:grass_"..i, {drop = { minetest.override_item("default:grass_" .. i, {drop = {
max_items = 1, max_items = 1,
items = { items = {
{items = {"farming:seed_wheat"}, rarity = 5}, {items = {"farming:seed_wheat"}, rarity = 5},
@ -280,3 +280,14 @@ minetest.register_node("farming:cotton_wild", {
fixed = {-6 / 16, -8 / 16, -6 / 16, 6 / 16, 5 / 16, 6 / 16}, fixed = {-6 / 16, -8 / 16, -6 / 16, 6 / 16, 5 / 16, 6 / 16},
}, },
}) })
-- Make default:dry_shrub occasionally drop rapeseed.
minetest.override_item("default:dry_shrub", {drop = {
max_items = 1,
items = {
{items = {"farming:rapeseed"}, rarity = 10},
{items = {"default:dry_shrub"}},
}
}})

View file

@ -0,0 +1,419 @@
----------------
-- Lookup tables
----------------
-- Contains which mortar you get when you put a rapeseed into a mortar
local put_seed_into_mortar = {
["farming:mortar"] = "farming:mortar_with_1_rapeseed",
["farming:mortar_with_1_rapeseed"] = "farming:mortar_with_2_rapeseed",
["farming:mortar_with_2_rapeseed"] = "farming:mortar_with_3_rapeseed",
}
-- Contains which mortar you get when you take oil from a mortar with a bottle
local take_oil_from_mortar = {
["farming:mortar_with_1_rapeseed_oil"] = "farming:mortar",
["farming:mortar_with_2_rapeseed_oil"] = "farming:mortar_with_1_rapeseed_oil",
["farming:mortar_with_3_rapeseed_oil"] = "farming:mortar_with_2_rapeseed_oil",
}
-- Conatins what will be in the mortar after the player used the pestle often enough
-- How often the pestle has to be used is calculated in get_num_poundings
local pound_with_pestle = {
["farming:mortar_with_1_rapeseed"] = {
after = "farming:mortar_with_1_rapeseed_oil",
base_min = 1,
base_max = 2,
prob = 0.5,
},
["farming:mortar_with_2_rapeseed"] = {
after = "farming:mortar_with_2_rapeseed_oil",
base_min = 2,
base_max = 3,
prob = 0.3,
},
["farming:mortar_with_3_rapeseed"] = {
after = "farming:mortar_with_3_rapeseed_oil",
base_min = 3,
base_max = 4,
prob = 0.2,
},
}
-- Returns for an entry in pound_with_pestle, how often the player has to use the
-- pestle
local function get_num_poundings(entry)
local ret = math.random(entry.base_min, entry.base_max)
-- todo: make this more efficient
while math.random() > entry.prob do
ret = ret + 1
end
return ret
end
----------------------------------
-- Tables that are used at runtime
----------------------------------
-- Contains for hashed node positions how many step pounding uses are still needed
local pending_poundings = {}
---------------------------------
-- Basic helpers for registration
---------------------------------
local function get_mortar_nodebox(fill_num)
-- the mortar's sides are 2/16 high
-- we do not want the mortar to be filled completely => 1.8 / 16
-- there can be up to 3 seeds or layers oil in the mortar => / 3
local fill_offset = fill_num * (1.8 / 16 / 3)
return {
type = "fixed",
fixed = {
{-3/16, -0.5, -3/16, 3/16, -7/16 + fill_offset, 3/16}, -- ground plate + filling
{-1/4, -7/16, -3/16, -3/16, -5/16, 3/16}, -- 4 sides
{-3/16, -7/16, -1/4, 3/16, -5/16, -3/16},
{3/16, -7/16, -3/16, 1/4, -5/16, 3/16},
{-3/16, -7/16, 3/16, 3/16, -5/16, 1/4}
},
}
end
local mortar_box_simple = {
type = "fixed",
fixed = {-1/4, -0.5, -1/4, 1/4, -5/16, 1/4},
}
local function mortar_on_flood(pos)
-- drop the mortar as item
pos = vector.new(pos)
pos.y = pos.y - 0.3
minetest.add_item(pos, "farming:mortar")
end
local function poundable_mortar_on_destruct(pos)
-- remove the entry in pending_poundings
local pos_hash = minetest.hash_node_position(pos)
pending_poundings[pos_hash] = nil
end
----------------------------------------------
-- Function for using the pestle on the mortar
----------------------------------------------
local function pestle_on_use(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
local node = minetest.get_node(pos)
-- find out if the node is a mortar and get its pounding target
local target = pound_with_pestle[node.name]
if not target then
return
end
-- check for protection
local user_name = user and minetest.is_player(user) and
user:get_player_name() or ""
if minetest.is_protected(pos, user_name) then
return
end
-- get how often the player still has to use the pestle
local pos_hash = minetest.hash_node_position(pos)
local remaining_hits = pending_poundings[pos_hash]
-- if not found, generate new amount from specs
remaining_hits = remaining_hits or get_num_poundings(target)
remaining_hits = remaining_hits - 1
if remaining_hits == 0 then
-- replace with target node
node.name = target.after
minetest.swap_node(pos, node)
-- clean up
pending_poundings[pos_hash] = nil
else
-- write back
pending_poundings[pos_hash] = remaining_hits
end
minetest.sound_play({name = "default_hard_footstep", gain = 1.0},
{pos = pos}, true)
-- add tool wear
if not minetest.global_exists("creative") or
not creative.is_enabled_for(user_name) then
itemstack:add_wear(1024)
if itemstack:is_empty() then
-- item broke
minetest.sound_play("default_tool_breaks", {pos = pos, gain = 0.5},
true)
end
end
return itemstack
end
--------------------------
-- Mortar and Pestle Items
--------------------------
-- the empty mortar
minetest.register_node("farming:mortar", {
description = "Mortar",
groups = {cracky = 3},
stack_max = 16,
drawtype = "nodebox",
tiles = {"default_clay.png"},
paramtype = "light",
paramtype2 = "none",
is_ground_content = false,
floodable = true,
node_box = get_mortar_nodebox(0),
selection_box = mortar_box_simple,
collision_box = mortar_box_simple,
sounds = default.node_sound_stone_defaults(),
on_flood = mortar_on_flood,
})
-- filled mortars
for _, item in ipairs({"rapeseed", "rapeseed_oil"}) do
local top_tile, on_destruct
if item == "rapeseed" then
top_tile = "farming_rapeseed_in_mortar.png"
on_destruct = poundable_mortar_on_destruct
else
top_tile = "(farming_rapeseed_oil.png^[mask:farming_mortar_mask.png)"
end
top_tile = "default_clay.png^" .. top_tile
for fillstate = 1, 3 do
minetest.register_node(string.format("farming:mortar_with_%i_%s", fillstate,
item), {
groups = {cracky = 3, not_in_creative_inventory = 1},
drawtype = "nodebox",
tiles = {top_tile, "default_clay.png"},
paramtype = "light",
paramtype2 = "none",
is_ground_content = false,
floodable = true,
node_box = get_mortar_nodebox(fillstate),
selection_box = mortar_box_simple,
collision_box = mortar_box_simple,
sounds = default.node_sound_stone_defaults(),
drop = "farming:mortar",
on_flood = mortar_on_flood,
on_destruct = on_destruct,
})
end
end
minetest.register_tool("farming:pestle", {
description = "Pestle",
groups = {},
inventory_image = "farming_pestle.png",
wield_image = "farming_pestle.png^[transformR270",
stack_max = 1,
range = 2.0,
sound = {breaks = "default_tool_breaks"},
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level = 0,
groupcaps = {},
damage_groups = {},
},
on_use = pestle_on_use,
})
------------------------------------------
-- Overrides for seed and glass bottle
-- (for putting into / taking from mortar)
------------------------------------------
-- implement putting seeds into the mortar
local old_rapeseed_on_place = minetest.registered_items["farming:rapeseed"].on_place
minetest.override_item("farming:rapeseed", {
node_placement_prediction = "", -- deactivate prediction (it looks bad)
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return old_rapeseed_on_place(itemstack, placer, pointed_thing)
end
-- do protection checks and check if mortar is clicked
local pos = pointed_thing.under
local node = minetest.get_node(pos)
local new_node_name = put_seed_into_mortar[node.name]
local placer_name = placer and minetest.is_player(placer) and
placer:get_player_name() or ""
if minetest.is_protected(pos, placer_name) or not new_node_name then
return old_rapeseed_on_place(itemstack, placer, pointed_thing)
end
-- replace the node
node.name = new_node_name
minetest.swap_node(pos, node)
-- clear pending_poundings (the player has to start over)
pending_poundings[minetest.hash_node_position(pos)] = nil
-- remove the seed from inventory
if not minetest.global_exists("creative") or
not creative.is_enabled_for(placer_name) then
itemstack:take_item()
end
return itemstack
end,
})
-- implement taking oil from the mortar with glass bottle
local old_glass_bottle_on_use = minetest.registered_items["vessels:glass_bottle"].on_use
or function(itemstack, user, pointed_thing)
-- default behaviour when leftclicking with item
if pointed_thing.type == "object" then
pointed_thing.ref:punch(user, 1.0, {full_punch_interval = 1.0}, nil)
return user:get_wielded_item()
elseif pointed_thing.type == "node" then
local node = minetest.get_node(pointed_thing.under)
local node_def = minetest.registered_nodes[node.name]
if node_def then
node_def.on_punch(pointed_thing.under, node, user, pointed_thing)
end
return user:get_wielded_item()
end
end
minetest.override_item("vessels:glass_bottle", {
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return old_glass_bottle_on_use(itemstack, user, pointed_thing)
end
-- do protection checks and check if mortar is clicked
local pos = pointed_thing.under
local node = minetest.get_node(pos)
local new_node_name = take_oil_from_mortar[node.name]
local user_is_player = user and minetest.is_player(user)
local user_name = user_is_player and user:get_player_name() or ""
if minetest.is_protected(pos, user_name) or not new_node_name then
return old_glass_bottle_on_use(itemstack, user, pointed_thing)
end
-- replace the node
node.name = new_node_name
minetest.swap_node(pos, node)
-- fill the bottle
local creative_enabled = minetest.global_exists("creative") and
creative.is_enabled_for(user_name)
local item_count = itemstack:get_count()
-- try to replace
if item_count == 1 and not creative_enabled then
itemstack:set_name("farming:glass_bottle_with_rapeseed_oil")
return itemstack
end
-- do not take in creative
if not creative_enabled then
itemstack:take_item()
end
-- add full bottle to inventory or drop it
local full_bottle = ItemStack("farming:glass_bottle_with_rapeseed_oil")
if user_is_player then
local inv = user:get_inventory()
if inv then
full_bottle = inv:add_item("main", full_bottle)
end
end
if not full_bottle:is_empty() then
-- no space => drop full bottle
minetest.add_item(pos, full_bottle)
end
return itemstack
end,
})
-------------
-- Craftitems
-------------
minetest.register_craftitem("farming:raw_mortar", {
description = "Raw Mortar",
groups = {},
inventory_image = "farming_raw_mortar.png",
stack_max = 16,
})
minetest.register_craftitem("farming:raw_pestle", {
description = "Raw Pestle",
groups = {},
inventory_image = "farming_raw_pestle.png",
stack_max = 1,
})
minetest.register_craftitem("farming:glass_bottle_with_rapeseed_oil", {
description = "Bottle with Rapeseed Oil",
groups = {},
inventory_image = "farming_rapeseed_oil.png^[mask:vessels_glass_bottle_liquidmask.png"
.. "^vessels_glass_bottle.png",
on_use = minetest.item_eat(3, "vessels:glass_bottle"),
})
-----------
-- Crafting
-----------
minetest.register_craft({
output = "farming:raw_mortar",
recipe = {
{"default:clay_lump", "", "default:clay_lump"},
{"", "default:clay_lump", ""},
},
})
minetest.register_craft({
type = "cooking",
output = "farming:mortar",
recipe = "farming:raw_mortar",
cooktime = 3,
})
minetest.register_craft({
output = "farming:raw_pestle",
recipe = {
{"default:clay_lump"},
{"default:clay_lump"},
},
})
minetest.register_craft({
type = "cooking",
output = "farming:pestle",
recipe = "farming:raw_pestle",
cooktime = 3,
})
minetest.register_craft({
type = "fuel",
recipe = "farming:glass_bottle_with_rapeseed_oil",
burntime = 13,
replacements = {{"farming:glass_bottle_with_rapeseed_oil", "vessels:glass_bottle"}},
})
minetest.register_craft({
output = "default:torch 4",
recipe = {
{"farming:glass_bottle_with_rapeseed_oil"},
{"farming:cotton"},
{"group:stick"},
},
replacements = {{"farming:glass_bottle_with_rapeseed_oil", "vessels:glass_bottle"}},
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 590 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 266 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 284 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 B