Add mods
|
@ -0,0 +1,22 @@
|
|||
Minetest 0.4 mod: doors
|
||||
=======================
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Casimir (CC BY-SA 3.0)
|
||||
Based on the work of Gambit
|
||||
door_steel_b.png
|
||||
door_wood_a.png
|
||||
door_wood_b.png
|
||||
|
||||
Gambit (CC BY-SA 4.0):
|
||||
doors_steel_bars.png
|
|
@ -0,0 +1 @@
|
|||
default
|
|
@ -0,0 +1,160 @@
|
|||
doors = {}
|
||||
|
||||
local floor_dir = {
|
||||
[0] = 15,
|
||||
[1] = 8,
|
||||
[2] = 17,
|
||||
[3] = 6,
|
||||
}
|
||||
|
||||
local ceil_dir = {
|
||||
[0] = 19,
|
||||
[1] = 4,
|
||||
[2] = 13,
|
||||
[3] = 10,
|
||||
}
|
||||
|
||||
local wall_dir = {
|
||||
[0] = 20,
|
||||
[1] = 23,
|
||||
[2] = 22,
|
||||
[3] = 21,
|
||||
}
|
||||
|
||||
function doors:register_door(name, def)
|
||||
local tiles = def.tiles
|
||||
|
||||
-- Change door status
|
||||
local function use(pos, replace_dir)
|
||||
local node = minetest.get_node(pos)
|
||||
local param2 = node.param2
|
||||
minetest.sound_play("default_dig_choppy", {pos, gain = 0.5, max_hear_distance = 32})
|
||||
minetest.swap_node(pos, {name=replace_dir, param2=param2})
|
||||
end
|
||||
|
||||
-- Check for other doors
|
||||
local function update(pos, dir)
|
||||
local node = minetest.get_node(pos)
|
||||
local status = minetest.registered_nodes[node.name].status
|
||||
|
||||
local pos_next = {x=pos.x, y=pos.y+dir, z=pos.z}
|
||||
local node_next = minetest.get_node(pos_next)
|
||||
local status_next = minetest.registered_nodes[node_next.name].status
|
||||
if status_next == nil then return end
|
||||
if status_next == status then
|
||||
update(pos_next, dir)
|
||||
local name = minetest.registered_nodes[node_next.name].base_name
|
||||
if status == 1 then
|
||||
use(pos_next, name.."_2")
|
||||
elseif status == 2 then
|
||||
use(pos_next, name.."_1")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function check_player_priv(pos, player)
|
||||
if not def.only_placer_can_open then
|
||||
return true
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
local playername = player:get_player_name()
|
||||
return meta:get_string("doors_owner") == playername
|
||||
end
|
||||
|
||||
-- Closed door
|
||||
minetest.register_node(":"..name.."_1", {
|
||||
description = def.description,
|
||||
inventory_image = def.inventory_image,
|
||||
tiles = {tiles[1].."^[transformR180", tiles[1].."^[transformR180", tiles[1], tiles[1], tiles[1], tiles[1].."^[transformfx"},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
drop = name.."_1",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1/16}
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1/16}
|
||||
},
|
||||
groups = def.groups,
|
||||
status = 1,
|
||||
base_name = name,
|
||||
on_rightclick = function(pos, node, user)
|
||||
if user:get_player_control().sneak then return end
|
||||
if not check_player_priv(pos, user) then return end
|
||||
update(pos, 1)
|
||||
update(pos, -1)
|
||||
use(pos, name.."_2")
|
||||
end,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if not pointed_thing.type == "node" then
|
||||
return itemstack
|
||||
end
|
||||
local ptu = pointed_thing.under
|
||||
local pta = pointed_thing.above
|
||||
local param2 = minetest.dir_to_facedir(placer:get_look_dir())
|
||||
local nodeunder = minetest.get_node(ptu)
|
||||
local nodeunder_def = minetest.registered_nodes[nodeunder.name]
|
||||
if nodeunder_def and nodeunder_def.on_rightclick then
|
||||
return nodeunder_def.on_rightclick(ptu, nodeunder, placer, itemstack)
|
||||
end
|
||||
|
||||
-- Place joint on the surface the placer is pointing to
|
||||
local face = param2
|
||||
if ptu.y < pta.y then
|
||||
face = floor_dir[param2]
|
||||
elseif ptu.y > pta.y then
|
||||
face = ceil_dir[param2]
|
||||
elseif (param2 == 0 and ptu.x > pta.x) or
|
||||
(param2 == 1 and ptu.z < pta.z) or
|
||||
(param2 == 2 and ptu.x < pta.x) or
|
||||
(param2 == 3 and ptu.z > pta.z) then
|
||||
face = wall_dir[param2]
|
||||
end
|
||||
-- In every other case place normal
|
||||
minetest.set_node(pta, {name=name.."_1", param2=face})
|
||||
|
||||
if def.only_placer_can_open then
|
||||
local playername = placer:get_player_name()
|
||||
local meta = minetest.get_meta(pta)
|
||||
meta:set_string("doors_owner", playername)
|
||||
meta:set_string("infotext", "Owned by "..playername)
|
||||
end
|
||||
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
itemstack:take_item()
|
||||
end
|
||||
minetest.sound_play("default_place_node", {ptu, gain = 0.5, max_hear_distance = 32})
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
-- Open door
|
||||
minetest.register_node(":"..name.."_2", {
|
||||
tiles = {tiles[1].."^[transformfy^[transformR270", tiles[1].."^[transformfy^[transformR90", tiles[1].."^[transformfx", tiles[1], tiles[1].."^[transformfx", tiles[1].."^[transformfx"},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
drop = name.."_1",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, -0.5+1/16, 0.5, 0.5}
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-0.5, -0.5, -0.5, -0.5+1/16, 0.5, 0.5}
|
||||
},
|
||||
groups = def.groups,
|
||||
status = 2,
|
||||
base_name = name,
|
||||
on_rightclick = function(pos, node, user)
|
||||
if user:get_player_control().sneak then return end
|
||||
if not check_player_priv(pos, user) then return end
|
||||
update(pos, 1)
|
||||
update(pos, -1)
|
||||
use(pos, name.."_1")
|
||||
end,
|
||||
})
|
||||
end
|
|
@ -0,0 +1,67 @@
|
|||
dofile(minetest.get_modpath("doors").."/functions.lua")
|
||||
|
||||
doors:register_door("doors:door_wood", {
|
||||
description = "Wooden Door",
|
||||
inventory_image = "doors_wood_b.png",
|
||||
groups = {snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=2, door=1},
|
||||
tiles = {"doors_wood_b.png"},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "doors:door_wood_1 2",
|
||||
recipe = {
|
||||
{"group:wood", "group:wood"},
|
||||
{"group:wood", "group:wood"},
|
||||
{"group:wood", "group:wood"}
|
||||
}
|
||||
})
|
||||
|
||||
doors:register_door("doors:door_wood_window", {
|
||||
description = "Wooden Window",
|
||||
inventory_image = "doors_wood_a.png",
|
||||
groups = {snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=2, door=1},
|
||||
tiles = {"doors_wood_a.png"},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "doors:door_wood_window_1 2",
|
||||
recipe = {
|
||||
{"group:wood", "group:wood"},
|
||||
{"group:stick", "group:stick"},
|
||||
{"group:wood", "group:wood"}
|
||||
}
|
||||
})
|
||||
|
||||
doors:register_door("doors:door_steel", {
|
||||
description = "Steel Door",
|
||||
inventory_image = "doors_steel_b.png",
|
||||
groups = {snappy=1, cracky=1, door=1},
|
||||
tiles = {"doors_steel_b.png"},
|
||||
only_placer_can_open = true,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "doors:door_steel 2",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:steel_ingot"},
|
||||
{"default:steel_ingot", "default:steel_ingot"}
|
||||
}
|
||||
})
|
||||
|
||||
doors:register_door("doors:door_steel_windows", {
|
||||
description = "Steel Window",
|
||||
inventory_image = "doors_steel_a.png",
|
||||
groups = {snappy=1, cracky=1, door=1},
|
||||
tiles = {"doors_steel_a.png"},
|
||||
only_placer_can_open = true,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "doors:steel_bars_1 2",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "default:steel_ingot"},
|
||||
{"default:stick", "default:stick"},
|
||||
{"default:steel_ingot", "default:steel_ingot"}
|
||||
}
|
||||
})
|
After Width: | Height: | Size: 613 B |
After Width: | Height: | Size: 593 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 546 B |
|
@ -0,0 +1,14 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
|
@ -0,0 +1 @@
|
|||
Install this by putting it in your .minetest/mods folder.
|
|
@ -0,0 +1,112 @@
|
|||
local age = 1 --how old an item has to be before collecting
|
||||
local radius_magnet = 2.5 --radius of item magnet
|
||||
local player_collect_height = 1.3 --added to their pos y value
|
||||
local adjuster_collect = 0.01 --Delay before collecting to visualize moveme
|
||||
|
||||
--Item collection
|
||||
minetest.register_globalstep(function(dtime)
|
||||
--collection
|
||||
for _,player in ipairs(minetest.get_connected_players()) do
|
||||
--don't magnetize to dead players
|
||||
if player:get_hp() > 0 then
|
||||
local pos = player:getpos()
|
||||
local inv = player:get_inventory()
|
||||
--radial detection
|
||||
for _,object in ipairs(minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y + player_collect_height,z=pos.z}, radius_magnet)) do
|
||||
if not object:is_player() and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" then
|
||||
if object:get_luaentity().age > age then
|
||||
if inv and inv:room_for_item("main", ItemStack(object:get_luaentity().itemstring)) then
|
||||
--collect
|
||||
if object:get_luaentity().collectioner == true and object:get_luaentity().age > age and object:get_luaentity().age > object:get_luaentity().age_stamp + adjuster_collect then
|
||||
if object:get_luaentity().itemstring ~= "" then
|
||||
inv:add_item("main", ItemStack(object:get_luaentity().itemstring))
|
||||
minetest.sound_play("item_drop_pickup", {
|
||||
pos = pos,
|
||||
max_hear_distance = 15,
|
||||
gain = 0.1,
|
||||
})
|
||||
object:get_luaentity().itemstring = ""
|
||||
object:remove()
|
||||
end
|
||||
|
||||
--magnet
|
||||
else
|
||||
--moveto for extreme speed boost
|
||||
local pos1 = pos
|
||||
pos1.y = pos1.y + player_collect_height
|
||||
object:moveto(pos1)
|
||||
object:get_luaentity().collectioner = true
|
||||
object:get_luaentity().age_stamp = object:get_luaentity().age
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
--Drop items on dig
|
||||
function minetest.handle_node_drops(pos, drops, digger)
|
||||
for _,item in ipairs(drops) do
|
||||
local count, name
|
||||
if type(item) == "string" then
|
||||
count = 1
|
||||
name = item
|
||||
else
|
||||
count = item:get_count()
|
||||
name = item:get_name()
|
||||
end
|
||||
--if not inv or not inv:contains_item("main", ItemStack(name)) then
|
||||
for i=1,count do
|
||||
local obj = minetest.add_item(pos, name)
|
||||
if obj ~= nil then
|
||||
obj:get_luaentity().collect = true
|
||||
obj:get_luaentity().age = age
|
||||
obj:setvelocity({x=math.random(-3,3), y=math.random(2,5), z=math.random(-3,3)})
|
||||
end
|
||||
end
|
||||
--end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
--Throw items using player's velocity
|
||||
function minetest.item_drop(itemstack, dropper, pos)
|
||||
|
||||
--if player then do modified item drop
|
||||
if dropper and minetest.get_player_information(dropper:get_player_name()) then
|
||||
local v = dropper:get_look_dir()
|
||||
local vel = dropper:get_player_velocity()
|
||||
local p = {x=pos.x, y=pos.y+player_collect_height, z=pos.z}
|
||||
local item = itemstack:to_string()
|
||||
local obj = core.add_item(p, item)
|
||||
if obj then
|
||||
v.x = (v.x*5)+vel.x
|
||||
v.y = ((v.y*5)+2)+vel.y
|
||||
v.z = (v.z*5)+vel.z
|
||||
obj:setvelocity(v)
|
||||
obj:get_luaentity().dropped_by = dropper:get_player_name()
|
||||
itemstack:clear()
|
||||
return itemstack
|
||||
end
|
||||
--machine
|
||||
else
|
||||
local v = dropper:get_look_dir()
|
||||
local item = itemstack:to_string()
|
||||
local obj = minetest.add_item({x=pos.x,y=pos.y+1.5,z=pos.z}, item) --{x=pos.x+v.x,y=pos.y+v.y+1.5,z=pos.z+v.z}
|
||||
if obj then
|
||||
v.x = (v.x*5)
|
||||
v.y = (v.y*5)
|
||||
v.z = (v.z*5)
|
||||
obj:setvelocity(v)
|
||||
obj:get_luaentity().dropped_by = nil
|
||||
itemstack:clear()
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
end
|
||||
if minetest.settings:get_bool("log_mods") then
|
||||
minetest.log("action", "Drops loaded")
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
name = drops
|
After Width: | Height: | Size: 933 B |
|
@ -0,0 +1,32 @@
|
|||
Minetest 0.4 mod: dye
|
||||
======================
|
||||
|
||||
See init.lua for documentation.
|
||||
|
||||
License of source code and media files:
|
||||
---------------------------------------
|
||||
Copyright (C) 2012 Perttu Ahola (celeron55) <celeron55@gmail.com>
|
||||
|
||||
License of source code:
|
||||
-----------------------
|
||||
Copyright (C) 2011-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
http://www.gnu.org/licenses/lgpl-2.1.html
|
||||
|
||||
License of media (textures and sounds)
|
||||
--------------------------------------
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
||||
|
||||
Authors of media files
|
||||
-----------------------
|
||||
Everything not listed in here:
|
||||
Copyright (C) 2010-2012 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||
|
||||
Casimir (CC BY-SA)
|
||||
dye_*
|
|
@ -0,0 +1,112 @@
|
|||
-- Other mods can use these for looping through available colors
|
||||
|
||||
dye = {}
|
||||
dye.basecolors = {"white", "grey", "black", "red", "yellow", "green", "cyan", "blue", "magenta"}
|
||||
dye.excolors = {"white", "lightgrey", "grey", "darkgrey", "black", "red", "orange", "yellow",
|
||||
"lime", "green", "aqua", "cyan", "sky_blue", "blue", "violet", "magenta", "red_violet"}
|
||||
|
||||
-- Make dye names and descriptions available globally
|
||||
|
||||
dye.dyes = {
|
||||
{"white", "White"},
|
||||
{"grey", "Grey"},
|
||||
{"dark_grey", "Dark grey"},
|
||||
{"black", "Black"},
|
||||
{"violet", "Violet"},
|
||||
{"blue", "Blue"},
|
||||
{"cyan", "Cyan"},
|
||||
{"dark_green", "Dark green"},
|
||||
{"green", "Green"},
|
||||
{"yellow", "Yellow"},
|
||||
{"brown", "Brown"},
|
||||
{"orange", "Orange"},
|
||||
{"red", "Red"},
|
||||
{"magenta", "Magenta"},
|
||||
{"pink", "Pink"},
|
||||
}
|
||||
|
||||
-- This collection of colors is partly a historic thing, partly something else
|
||||
|
||||
local dyes = {
|
||||
{"white", "White Dye", {dye=1, basecolor_white=1, excolor_white=1, unicolor_white=1, not_in_creative_inventory=1}},
|
||||
{"grey", "Grey Dye", {dye=1, basecolor_grey=1, excolor_grey=1, unicolor_grey=1, not_in_creative_inventory=1}},
|
||||
{"dark_grey", "Dark Grey Dye", {dye=1, basecolor_grey=1, excolor_darkgrey=1, unicolor_darkgrey=1, not_in_creative_inventory=1}},
|
||||
{"black", "Black Dye", {dye=1, basecolor_black=1, excolor_black=1, unicolor_black=1, not_in_creative_inventory=1}},
|
||||
{"violet", "Violet Dye", {dye=1, basecolor_magenta=1, excolor_violet=1, unicolor_violet=1, not_in_creative_inventory=1}},
|
||||
{"blue", "Blue Dye", {dye=1, basecolor_blue=1, excolor_blue=1, unicolor_blue=1, not_in_creative_inventory=1}},
|
||||
{"cyan", "Cyan Dye", {dye=1, basecolor_cyan=1, excolor_cyan=1, unicolor_cyan=1, not_in_creative_inventory=1}},
|
||||
{"dark_green", "Dark Green Dye", {dye=1, basecolor_green=1, excolor_green=1, unicolor_dark_green=1, not_in_creative_inventory=1}},
|
||||
{"green", "Green Dye", {dye=1, basecolor_green=1, excolor_green=1, unicolor_green=1, not_in_creative_inventory=1}},
|
||||
{"yellow", "Yellow Dye", {dye=1, basecolor_yellow=1, excolor_yellow=1, unicolor_yellow=1, not_in_creative_inventory=1}},
|
||||
{"brown", "Brown Dye", {dye=1, basecolor_brown=1, excolor_orange=1, unicolor_dark_orange=1, not_in_creative_inventory=1}},
|
||||
{"orange", "Orange Dye", {dye=1, basecolor_orange=1, excolor_orange=1, unicolor_orange=1, not_in_creative_inventory=1}},
|
||||
{"red", "Red Dye", {dye=1, basecolor_red=1, excolor_red=1, unicolor_red=1, not_in_creative_inventory=1}},
|
||||
{"magenta", "Magenta Dye", {dye=1, basecolor_magenta=1, excolor_red_violet=1, unicolor_red_violet=1, not_in_creative_inventory=1}},
|
||||
{"pink", "Pink Dye", {dye=1, basecolor_red=1, excolor_red=1, unicolor_light_red=1, not_in_creative_inventory=1}},
|
||||
}
|
||||
|
||||
-- Define items
|
||||
|
||||
for _, row in ipairs(dyes) do
|
||||
local name = row[1]
|
||||
local description = row[2]
|
||||
local groups = row[3]
|
||||
local item_name = "dye:" .. name
|
||||
local item_image = "dye_" .. name .. ".png"
|
||||
minetest.register_craftitem(item_name, {
|
||||
inventory_image = item_image,
|
||||
description = description,
|
||||
groups = groups
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = item_name .. " 4",
|
||||
recipe = {"group:flower,color_" .. name},
|
||||
})
|
||||
end
|
||||
|
||||
-- Manually add coal->black dye
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "dye:black 4",
|
||||
recipe = {"group:coal"},
|
||||
})
|
||||
|
||||
-- Mix recipes
|
||||
local dye_recipes = {
|
||||
-- src1, src2, dst
|
||||
-- RYB mixes
|
||||
{"red", "blue", "violet"}, -- "purple"
|
||||
{"yellow", "red", "orange"},
|
||||
{"yellow", "blue", "green"},
|
||||
-- RYB complementary mixes
|
||||
{"yellow", "violet", "dark_grey"},
|
||||
{"blue", "orange", "dark_grey"},
|
||||
-- CMY mixes - approximation
|
||||
{"cyan", "yellow", "green"},
|
||||
{"cyan", "magenta", "blue"},
|
||||
{"yellow", "magenta", "red"},
|
||||
-- other mixes that result in a color we have
|
||||
{"red", "green", "brown"},
|
||||
{"magenta", "blue", "violet"},
|
||||
{"green", "blue", "cyan"},
|
||||
{"pink", "violet", "magenta"},
|
||||
-- mixes with black
|
||||
{"white", "black", "grey"},
|
||||
{"grey", "black", "dark_grey"},
|
||||
{"green", "black", "dark_green"},
|
||||
{"orange", "black", "brown"},
|
||||
-- mixes with white
|
||||
{"white", "red", "pink"},
|
||||
{"white", "dark_grey", "grey"},
|
||||
{"white", "dark_green", "green"},
|
||||
}
|
||||
|
||||
for _, mix in pairs(dye_recipes) do
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = 'dye:' .. mix[3] .. ' 2',
|
||||
recipe = {'dye:' .. mix[1], 'dye:' .. mix[2]},
|
||||
})
|
||||
end
|
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 112 B |
After Width: | Height: | Size: 114 B |
After Width: | Height: | Size: 112 B |
After Width: | Height: | Size: 114 B |
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 116 B |
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 115 B |
After Width: | Height: | Size: 226 B |
After Width: | Height: | Size: 116 B |
|
@ -0,0 +1 @@
|
|||
hudbars?
|
|
@ -0,0 +1 @@
|
|||
Adds an experience attribute to players, used to level up mana, health, etc.
|
|
@ -0,0 +1,285 @@
|
|||
local S
|
||||
if (minetest.get_modpath("intllib")) then
|
||||
S = intllib.Getter()
|
||||
else
|
||||
S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end
|
||||
end
|
||||
|
||||
experience = {}
|
||||
experience.playerlist = {}
|
||||
experience.level = 2
|
||||
|
||||
experience.settings = {}
|
||||
experience.settings.default_max = 2
|
||||
|
||||
do
|
||||
local default_max = tonumber(minetest.setting_get("experience_default_max"))
|
||||
if default_max ~= nil then
|
||||
experience.settings.default_max = default_max
|
||||
end
|
||||
end
|
||||
|
||||
--[===[
|
||||
API functions
|
||||
]===]
|
||||
|
||||
function experience.set(playername, value)
|
||||
if value < 0 then
|
||||
minetest.log("info", "[experience] Warning: experience.set was called with negative value!")
|
||||
value = 0
|
||||
end
|
||||
value = experience.round(value)
|
||||
if value >= experience.playerlist[playername].maxexperience then
|
||||
minetest.chat_send_player(playername, "Level "..experience.playerlist[playername].level.."!")
|
||||
experience.playerlist[playername].level = experience.playerlist[playername].level + 1
|
||||
experience.playerlist[playername].maxexperience = 2 ^ experience.playerlist[playername].level
|
||||
experience.playerlist[playername].experience = 0
|
||||
mana.setmax(playername, 60 + (t.level * 20))
|
||||
value = 0
|
||||
experience.hud_update(playername)
|
||||
end
|
||||
if experience.playerlist[playername].experience ~= value then
|
||||
experience.playerlist[playername].experience = value
|
||||
experience.hud_update(playername)
|
||||
end
|
||||
end
|
||||
|
||||
function experience.setmax(playername, value)
|
||||
if value < 0 then
|
||||
value = 0
|
||||
minetest.log("info", "[experience] Warning: experience.setmax was called with negative value!")
|
||||
end
|
||||
value = experience.round(value)
|
||||
if experience.playerlist[playername].maxexperience ~= value then
|
||||
experience.playerlist[playername].maxexperience = value
|
||||
if(experience.playerlist[playername].experience > value) then
|
||||
experience.playerlist[playername].experience = value
|
||||
end
|
||||
experience.hud_update(playername)
|
||||
end
|
||||
end
|
||||
|
||||
function experience.get(playername)
|
||||
return experience.playerlist[playername].experience
|
||||
end
|
||||
|
||||
function experience.getlevel(playername)
|
||||
return experience.playerlist[playername].level
|
||||
end
|
||||
|
||||
function experience.getmax(playername)
|
||||
return experience.playerlist[playername].maxexperience
|
||||
end
|
||||
|
||||
function experience.add_up_to(playername, value)
|
||||
local t = experience.playerlist[playername]
|
||||
value = experience.round(value)
|
||||
if t.experience + value >= t.maxexperience then
|
||||
minetest.chat_send_player(playername, "Level "..t.level.."!")
|
||||
t.level = t.level + 1
|
||||
t.maxexperience = 2 ^ t.level
|
||||
t.experience = 0
|
||||
mana.setmax(playername, 60 + (t.level * 20))
|
||||
value = 0
|
||||
experience.hud_update(playername)
|
||||
end
|
||||
if(t ~= nil and value >= 0) then
|
||||
local excess
|
||||
if((t.experience + value) > t.maxexperience) then
|
||||
excess = (t.experience + value) - t.maxexperience
|
||||
t.experience = t.maxexperience
|
||||
else
|
||||
excess = 0
|
||||
t.experience = t.experience + value
|
||||
end
|
||||
experience.hud_update(playername)
|
||||
return true, excess
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function experience.add(playername, value)
|
||||
local t = experience.playerlist[playername]
|
||||
value = experience.round(value)
|
||||
if t.experience + value >= t.maxexperience then
|
||||
minetest.chat_send_player(playername, "Level "..t.level.."!")
|
||||
t.level = t.level + 1
|
||||
t.maxexperience = 2 ^ t.level
|
||||
t.experience = 0
|
||||
mana.setmax(playername, 60 + (t.level * 20))
|
||||
value = 0
|
||||
experience.hud_update(playername)
|
||||
end
|
||||
if(t ~= nil and ((t.experience + value) <= t.maxexperience) and value >= 0) then
|
||||
t.experience = t.experience + value
|
||||
experience.hud_update(playername)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function experience.subtract(playername, value)
|
||||
local t = experience.playerlist[playername]
|
||||
value = experience.round(value)
|
||||
if(t ~= nil and t.experience >= value and value >= 0) then
|
||||
t.experience = t.experience -value
|
||||
experience.hud_update(playername)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function experience.subtract_up_to(playername, value)
|
||||
local t = experience.playerlist[playername]
|
||||
value = experience.round(value)
|
||||
if(t ~= nil and value >= 0) then
|
||||
local missing
|
||||
if((t.experience - value) < 0) then
|
||||
missing = math.abs(t.experience - value)
|
||||
t.experience = 0
|
||||
else
|
||||
missing = 0
|
||||
t.experience = t.experience - value
|
||||
end
|
||||
experience.hud_update(playername)
|
||||
return true, missing
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
--[===[
|
||||
File handling, loading data, saving data, setting up stuff for players.
|
||||
]===]
|
||||
|
||||
|
||||
-- Load the playerlist from a previous session, if available.
|
||||
do
|
||||
local filepath = minetest.get_worldpath().."/experience.mt"
|
||||
local file = io.open(filepath, "r")
|
||||
if file then
|
||||
minetest.log("action", "[experience] experience.mt opened.")
|
||||
local string = file:read()
|
||||
io.close(file)
|
||||
if(string ~= nil) then
|
||||
local savetable = minetest.deserialize(string)
|
||||
experience.playerlist = savetable.playerlist
|
||||
minetest.debug("[experience] experience.mt successfully read.")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function experience.save_to_file()
|
||||
local savetable = {}
|
||||
savetable.playerlist = experience.playerlist
|
||||
|
||||
local savestring = minetest.serialize(savetable)
|
||||
|
||||
local filepath = minetest.get_worldpath().."/experience.mt"
|
||||
local file = io.open(filepath, "w")
|
||||
if file then
|
||||
file:write(savestring)
|
||||
io.close(file)
|
||||
minetest.log("action", "[experience] Wrote experience data into "..filepath..".")
|
||||
else
|
||||
minetest.log("error", "[experience] Failed to write experience data into "..filepath..".")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
local playername = player:get_player_name()
|
||||
experience.set(playername, 0)
|
||||
experience.hud_update(playername)
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local playername = player:get_player_name()
|
||||
if not minetest.get_modpath("hudbars") ~= nil then
|
||||
experience.hud_remove(playername)
|
||||
end
|
||||
experience.save_to_file()
|
||||
end)
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
minetest.log("action", "[experience] Server shuts down. Rescuing data into experience.mt")
|
||||
experience.save_to_file()
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local playername = player:get_player_name()
|
||||
|
||||
if experience.playerlist[playername] == nil then
|
||||
experience.playerlist[playername] = {}
|
||||
experience.playerlist[playername].experience = 0
|
||||
experience.playerlist[playername].maxexperience = experience.settings.default_max
|
||||
experience.playerlist[playername].level = 2
|
||||
experience.playerlist[playername].remainder = 0
|
||||
end
|
||||
|
||||
if minetest.get_modpath("hudbars") ~= nil then
|
||||
hb.init_hudbar(player, "experience", experience.get(playername), experience.getmax(playername))
|
||||
else
|
||||
experience.hud_add(playername)
|
||||
end
|
||||
end)
|
||||
|
||||
--[===[
|
||||
HUD functions
|
||||
]===]
|
||||
|
||||
if minetest.get_modpath("hudbars") ~= nil then
|
||||
hb.register_hudbar("experience", 0xFFFFFF, S("Experience"), { bar = "experience_bar.png", icon = "experience_icon.png", bgicon = "experience_bgicon.png" }, 0, experience.settings.default_max, false)
|
||||
|
||||
function experience.hud_update(playername)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
if player ~= nil then
|
||||
hb.change_hudbar(player, "experience", experience.get(playername), experience.getmax(playername))
|
||||
end
|
||||
end
|
||||
|
||||
function experience.hud_remove(playername)
|
||||
end
|
||||
|
||||
else
|
||||
function experience.experiencestring(playername)
|
||||
return S("Experience: @1/@2", experience.get(playername), experience.getmax(playername))
|
||||
end
|
||||
|
||||
function experience.hud_add(playername)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
local id = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = { x = 0.5, y=1 },
|
||||
text = experience.experiencestring(playername),
|
||||
scale = { x = 0, y = 0 },
|
||||
alignment = { x = 1, y = 0},
|
||||
direction = 1,
|
||||
number = 0xFFFFFF,
|
||||
offset = { x = -262, y = -103}
|
||||
})
|
||||
experience.playerlist[playername].hudid = id
|
||||
return id
|
||||
end
|
||||
|
||||
function experience.hud_update(playername)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
player:hud_change(experience.playerlist[playername].hudid, "text", experience.experiencestring(playername))
|
||||
end
|
||||
|
||||
function experience.hud_remove(playername)
|
||||
local player = minetest.get_player_by_name(playername)
|
||||
player:hud_remove(experience.playerlist[playername].hudid)
|
||||
end
|
||||
end
|
||||
|
||||
--[===[
|
||||
Helper functions
|
||||
]===]
|
||||
experience.round = function(x)
|
||||
return math.ceil(math.floor(x+0.5))
|
||||
end
|
After Width: | Height: | Size: 138 B |
After Width: | Height: | Size: 157 B |
After Width: | Height: | Size: 240 B |
|
@ -0,0 +1,40 @@
|
|||
Minetest Game mod: farming
|
||||
==========================
|
||||
See license.txt for license information.
|
||||
|
||||
Authors of source code
|
||||
----------------------
|
||||
Originally by PilzAdam (MIT)
|
||||
webdesigner97 (MIT)
|
||||
Various Minetest developers and contributors (MIT)
|
||||
|
||||
Authors of media (textures)
|
||||
---------------------------
|
||||
Created by PilzAdam (CC BY 3.0):
|
||||
farming_bread.png
|
||||
farming_soil.png
|
||||
farming_soil_wet.png
|
||||
farming_soil_wet_side.png
|
||||
farming_string.png
|
||||
|
||||
Created by BlockMen (CC BY 3.0):
|
||||
farming_tool_diamondhoe.png
|
||||
farming_tool_mesehoe.png
|
||||
farming_tool_bronzehoe.png
|
||||
farming_tool_steelhoe.png
|
||||
farming_tool_stonehoe.png
|
||||
farming_tool_woodhoe.png
|
||||
|
||||
Created by MasterGollum (CC BY 3.0):
|
||||
farming_straw.png
|
||||
|
||||
Created by Gambit (CC BY 3.0):
|
||||
farming_wheat.png
|
||||
farming_wheat_*.png
|
||||
farming_cotton_*.png
|
||||
farming_flour.png
|
||||
farming_cotton_seed.png
|
||||
farming_wheat_seed.png
|
||||
|
||||
Created by Napiophelios (CC BY-SA 3.0):
|
||||
farming_cotton.png
|
|
@ -0,0 +1,398 @@
|
|||
|
||||
-- Wear out hoes, place soil
|
||||
-- TODO Ignore group:flower
|
||||
farming.registered_plants = {}
|
||||
|
||||
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 = minetest.get_node(pt.under)
|
||||
local p = {x=pt.under.x, y=pt.under.y+1, z=pt.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
|
||||
|
||||
-- check if pointing at soil
|
||||
if minetest.get_item_group(under.name, "soil") ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if (wet) soil defined
|
||||
local regN = minetest.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 minetest.is_protected(pt.under, user:get_player_name()) then
|
||||
minetest.record_protection_violation(pt.under, user:get_player_name())
|
||||
return
|
||||
end
|
||||
if minetest.is_protected(pt.above, user:get_player_name()) then
|
||||
minetest.record_protection_violation(pt.above, user:get_player_name())
|
||||
return
|
||||
end
|
||||
|
||||
-- turn the node into soil and play sound
|
||||
minetest.set_node(pt.under, {name = regN[under.name].soil.dry})
|
||||
minetest.sound_play("default_dig_crumbly", {
|
||||
pos = pt.under,
|
||||
gain = 0.5,
|
||||
})
|
||||
|
||||
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/(uses-1))
|
||||
-- tool break sound
|
||||
if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
|
||||
minetest.sound_play(wdef.sound.breaks, {pos = pt.above, gain = 0.5})
|
||||
end
|
||||
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
|
||||
minetest.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,
|
||||
groups = def.groups,
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
})
|
||||
-- Register its recipe
|
||||
if def.material == nil then
|
||||
minetest.register_craft({
|
||||
output = name:sub(2),
|
||||
recipe = def.recipe
|
||||
})
|
||||
else
|
||||
minetest.register_craft({
|
||||
output = name:sub(2),
|
||||
recipe = {
|
||||
{def.material, def.material, ""},
|
||||
{"", "group:stick", ""},
|
||||
{"", "group:stick", ""}
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
-- how often node timers for plants will tick, +/- some random value
|
||||
local function tick(pos)
|
||||
minetest.get_node_timer(pos):start(math.random(166, 286))
|
||||
end
|
||||
-- how often a growth failure tick is retried (e.g. too dark)
|
||||
local function tick_again(pos)
|
||||
minetest.get_node_timer(pos):start(math.random(40, 80))
|
||||
end
|
||||
|
||||
-- Seed placement
|
||||
farming.place_seed = function(itemstack, placer, pointed_thing, plantname)
|
||||
local pt = pointed_thing
|
||||
-- check if pointing at a node
|
||||
if not pt then
|
||||
return itemstack
|
||||
end
|
||||
if pt.type ~= "node" then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local under = minetest.get_node(pt.under)
|
||||
local above = minetest.get_node(pt.above)
|
||||
|
||||
local player_name = placer and placer:get_player_name() or ""
|
||||
|
||||
if minetest.is_protected(pt.under, player_name) then
|
||||
minetest.record_protection_violation(pt.under, player_name)
|
||||
return
|
||||
end
|
||||
if minetest.is_protected(pt.above, player_name) then
|
||||
minetest.record_protection_violation(pt.above, player_name)
|
||||
return
|
||||
end
|
||||
|
||||
-- return if any of the nodes is not registered
|
||||
if not minetest.registered_nodes[under.name] then
|
||||
return itemstack
|
||||
end
|
||||
if not minetest.registered_nodes[above.name] then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- check if pointing at the top of the node
|
||||
if pt.above.y ~= pt.under.y+1 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
|
||||
|
||||
-- check if pointing at soil
|
||||
if minetest.get_item_group(under.name, "soil") < 2 then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- add the node and remove 1 item from the itemstack
|
||||
minetest.add_node(pt.above, {name = plantname, param2 = 1})
|
||||
tick(pt.above)
|
||||
if not (creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(player_name)) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
farming.grow_plant = function(pos, elapsed)
|
||||
local node = minetest.get_node(pos)
|
||||
local name = node.name
|
||||
local def = minetest.registered_nodes[name]
|
||||
|
||||
if not def.next_plant then
|
||||
-- disable timer for fully grown plant
|
||||
return
|
||||
end
|
||||
|
||||
-- grow seed
|
||||
if minetest.get_item_group(node.name, "seed") and def.fertility then
|
||||
local soil_node = minetest.get_node_or_nil({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if not soil_node then
|
||||
tick_again(pos)
|
||||
return
|
||||
end
|
||||
-- omitted is a check for light, we assume seeds can germinate in the dark.
|
||||
for _, v in pairs(def.fertility) do
|
||||
if minetest.get_item_group(soil_node.name, v) ~= 0 then
|
||||
local placenode = {name = def.next_plant}
|
||||
if def.place_param2 then
|
||||
placenode.param2 = def.place_param2
|
||||
end
|
||||
minetest.swap_node(pos, placenode)
|
||||
if minetest.registered_nodes[def.next_plant].next_plant then
|
||||
tick(pos)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- check if on wet soil
|
||||
local below = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
|
||||
if minetest.get_item_group(below.name, "soil") < 3 then
|
||||
tick_again(pos)
|
||||
return
|
||||
end
|
||||
|
||||
-- check light
|
||||
local light = minetest.get_node_light(pos)
|
||||
if not light or light < def.minlight or light > def.maxlight then
|
||||
tick_again(pos)
|
||||
return
|
||||
end
|
||||
|
||||
-- grow
|
||||
local placenode = {name = def.next_plant}
|
||||
if def.place_param2 then
|
||||
placenode.param2 = def.place_param2
|
||||
end
|
||||
minetest.swap_node(pos, placenode)
|
||||
|
||||
-- new timer needed?
|
||||
if minetest.registered_nodes[def.next_plant].next_plant then
|
||||
tick(pos)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Register plants
|
||||
farming.register_plant = function(name, def)
|
||||
local mname = name:split(":")[1]
|
||||
local pname = name:split(":")[2]
|
||||
|
||||
-- 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
|
||||
|
||||
farming.registered_plants[pname] = def
|
||||
|
||||
-- Register seed
|
||||
local lbm_nodes = {mname .. ":seed_" .. pname}
|
||||
local g = {seed = 1, snappy = 3, attached_node = 1, flammable = 2}
|
||||
for k, v in pairs(def.fertility) do
|
||||
g[v] = 1
|
||||
end
|
||||
minetest.register_node(":" .. mname .. ":seed_" .. pname, {
|
||||
description = def.description,
|
||||
tiles = {def.inventory_image},
|
||||
inventory_image = def.inventory_image,
|
||||
wield_image = def.inventory_image,
|
||||
drawtype = "signlike",
|
||||
groups = g,
|
||||
paramtype = "light",
|
||||
paramtype2 = "wallmounted",
|
||||
place_param2 = def.place_param2 or nil, -- this isn't actually used for placement
|
||||
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,
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
dig = {name = "", gain = 0},
|
||||
dug = {name = "default_grass_footstep", gain = 0.2},
|
||||
place = {name = "default_place_node", gain = 0.25},
|
||||
}),
|
||||
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local under = pointed_thing.under
|
||||
local node = minetest.get_node(under)
|
||||
local udef = minetest.registered_nodes[node.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(under, node, placer, itemstack,
|
||||
pointed_thing) or itemstack
|
||||
end
|
||||
|
||||
return farming.place_seed(itemstack, placer, pointed_thing, mname .. ":seed_" .. pname)
|
||||
end,
|
||||
next_plant = mname .. ":" .. pname .. "_1",
|
||||
on_timer = farming.grow_plant,
|
||||
minlight = def.minlight,
|
||||
maxlight = def.maxlight,
|
||||
})
|
||||
|
||||
-- Register harvest
|
||||
minetest.register_craftitem(":" .. mname .. ":" .. pname, {
|
||||
description = pname:gsub("^%l", string.upper),
|
||||
inventory_image = mname .. "_" .. pname .. ".png",
|
||||
groups = {flammable = 2},
|
||||
})
|
||||
|
||||
-- Register growing steps
|
||||
for i = 1, def.steps do
|
||||
local base_rarity = 1
|
||||
if def.steps ~= 1 then
|
||||
base_rarity = 8 - (i - 1) * 7 / (def.steps - 1)
|
||||
end
|
||||
local drop = {
|
||||
items = {
|
||||
{items = {mname .. ":" .. pname}, rarity = base_rarity},
|
||||
{items = {mname .. ":" .. pname}, rarity = base_rarity * 2},
|
||||
{items = {mname .. ":seed_" .. pname}, rarity = base_rarity},
|
||||
{items = {mname .. ":seed_" .. pname}, rarity = base_rarity * 2},
|
||||
}
|
||||
}
|
||||
local nodegroups = {snappy = 3, flammable = 2, plant = 1, not_in_creative_inventory = 1, attached_node = 1}
|
||||
nodegroups[pname] = i
|
||||
|
||||
local next_plant = nil
|
||||
|
||||
if i < def.steps then
|
||||
next_plant = mname .. ":" .. pname .. "_" .. (i + 1)
|
||||
lbm_nodes[#lbm_nodes + 1] = mname .. ":" .. pname .. "_" .. i
|
||||
end
|
||||
|
||||
minetest.register_node(":" .. mname .. ":" .. pname .. "_" .. i, {
|
||||
drawtype = "plantlike",
|
||||
waving = 1,
|
||||
tiles = {mname .. "_" .. pname .. "_" .. i .. ".png"},
|
||||
paramtype = "light",
|
||||
paramtype2 = def.paramtype2 or nil,
|
||||
place_param2 = def.place_param2 or nil,
|
||||
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(),
|
||||
next_plant = next_plant,
|
||||
on_timer = farming.grow_plant,
|
||||
minlight = def.minlight,
|
||||
maxlight = def.maxlight,
|
||||
})
|
||||
end
|
||||
|
||||
-- replacement LBM for pre-nodetimer plants
|
||||
minetest.register_lbm({
|
||||
name = ":" .. mname .. ":start_nodetimer_" .. pname,
|
||||
nodenames = lbm_nodes,
|
||||
action = function(pos, node)
|
||||
tick_again(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Return
|
||||
local r = {
|
||||
seed = mname .. ":seed_" .. pname,
|
||||
harvest = mname .. ":" .. pname
|
||||
}
|
||||
return r
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
default
|
||||
wool
|
||||
stairs
|
|
@ -0,0 +1,35 @@
|
|||
farming.register_hoe(":farming:hoe_wood", {
|
||||
description = "Wooden Hoe",
|
||||
inventory_image = "farming_tool_woodhoe.png",
|
||||
max_uses = 30,
|
||||
material = "group:wood",
|
||||
groups = {flammable = 2},
|
||||
})
|
||||
|
||||
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_copper", {
|
||||
description = "Copper Hoe",
|
||||
inventory_image = "farming_tool_copperhoe.png",
|
||||
max_uses = 130,
|
||||
material = "default:copper_ingot"
|
||||
})
|
||||
|
||||
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", {
|
||||
description = "Bronze Hoe",
|
||||
inventory_image = "farming_tool_bronzehoe.png",
|
||||
max_uses = 220,
|
||||
material = "default:bronze_ingot"
|
||||
})--]]
|
|
@ -0,0 +1,159 @@
|
|||
-- Global farming namespace
|
||||
|
||||
farming = {}
|
||||
farming.path = minetest.get_modpath("farming")
|
||||
|
||||
|
||||
-- Load files
|
||||
|
||||
dofile(farming.path .. "/api.lua")
|
||||
dofile(farming.path .. "/nodes.lua")
|
||||
dofile(farming.path .. "/hoes.lua")
|
||||
|
||||
-- WEED
|
||||
|
||||
minetest.register_node("farming:weed", {
|
||||
description = "Jungleweed",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
waving = 1,
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
drawtype = "plantlike",
|
||||
tiles = {"farming_weed.png"},
|
||||
inventory_image = "farming_weed.png",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5, -0.5, -0.5, 0.5, -0.5+4/16, 0.5}
|
||||
},
|
||||
},
|
||||
groups = {snappy=3, flammable=2, sickle=1, falling_node=1},
|
||||
sounds = default.node_sound_leaves_defaults()
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"farming:soil_wet", "farming:soil"},
|
||||
interval = 23,
|
||||
chance = 23,
|
||||
action = function(pos, node)
|
||||
pos.y = pos.y+1
|
||||
if minetest.get_node(pos).name == "air" then
|
||||
node.name = "farming:weed"
|
||||
minetest.set_node(pos, node)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "farming:weed",
|
||||
burntime = 1
|
||||
})
|
||||
|
||||
-- WHEAT
|
||||
|
||||
farming.register_plant("farming:wheat", {
|
||||
description = "Wheat Seed",
|
||||
paramtype2 = "meshoptions",
|
||||
inventory_image = "farming_wheat_seed.png",
|
||||
steps = 4,
|
||||
minlight = 13,
|
||||
maxlight = default.LIGHT_MAX,
|
||||
fertility = {"grassland"},
|
||||
groups = {flammable = 4},
|
||||
place_param2 = 3,
|
||||
})
|
||||
|
||||
minetest.register_craftitem("farming:flour", {
|
||||
description = "Flour",
|
||||
inventory_image = "farming_flour.png",
|
||||
groups = {flammable = 1},
|
||||
})
|
||||
|
||||
minetest.register_craftitem("farming:bread", {
|
||||
description = "Bread",
|
||||
inventory_image = "farming_bread.png",
|
||||
on_use = minetest.item_eat(5),
|
||||
groups = {flammable = 2},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:flour",
|
||||
recipe = {"farming:wheat", "farming:wheat", "farming:wheat", "farming:wheat"}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
cooktime = 15,
|
||||
output = "farming:bread",
|
||||
recipe = "farming:flour"
|
||||
})
|
||||
|
||||
|
||||
-- Cotton
|
||||
|
||||
farming.register_plant("farming:cotton", {
|
||||
description = "Cotton Seed",
|
||||
inventory_image = "farming_cotton_seed.png",
|
||||
steps = 3,
|
||||
minlight = 13,
|
||||
maxlight = default.LIGHT_MAX,
|
||||
fertility = {"grassland", "desert"},
|
||||
groups = {flammable = 4},
|
||||
})
|
||||
|
||||
minetest.register_craftitem("farming:string", {
|
||||
description = "String",
|
||||
inventory_image = "farming_string.png",
|
||||
groups = {flammable = 2},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "wool:white",
|
||||
recipe = {
|
||||
{"farming:cotton", "farming:cotton"},
|
||||
{"farming:cotton", "farming:cotton"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "farming:string 2",
|
||||
recipe = {
|
||||
{"farming:cotton"},
|
||||
{"farming:cotton"},
|
||||
}
|
||||
})
|
||||
|
||||
-- Fuels
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "farming:straw",
|
||||
burntime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "farming:wheat",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "farming:cotton",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "farming:string",
|
||||
burntime = 1,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "farming:hoe_wood",
|
||||
burntime = 5,
|
||||
})
|
|
@ -0,0 +1,61 @@
|
|||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2012-2016 PilzAdam
|
||||
Copyright (C) 2014-2016 webdesigner97
|
||||
Copyright (C) 2012-2016 Various Minetest developers and contributors
|
||||
|
||||
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
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
|
||||
License of media (textures)
|
||||
---------------------------
|
||||
|
||||
Attribution 3.0 Unported (CC BY 3.0)
|
||||
Copyright (C) 2012-2016 PilzAdam
|
||||
Copyright (C) 2014-2016 BlockMen
|
||||
Copyright (C) 2015-2016 MasterGollum
|
||||
Copyright (C) 2015-2016 Gambit
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by/3.0/
|
|
@ -0,0 +1,125 @@
|
|||
minetest.override_item("default:dirt", {
|
||||
soil = {
|
||||
base = "default:dirt",
|
||||
dry = "farming:soil",
|
||||
wet = "farming:soil_wet"
|
||||
}
|
||||
})
|
||||
|
||||
minetest.override_item("default:dirt_with_grass", {
|
||||
soil = {
|
||||
base = "default:dirt_with_grass",
|
||||
dry = "farming:soil",
|
||||
wet = "farming:soil_wet"
|
||||
}
|
||||
})
|
||||
|
||||
minetest.override_item("default:dirt_with_snow", {
|
||||
soil = {
|
||||
base = "default:dirt_with_snow",
|
||||
dry = "farming:soil",
|
||||
wet = "farming:soil_wet"
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_node("farming:soil", {
|
||||
description = "Soil",
|
||||
tiles = {"default_dirt.png^farming_soil.png", "default_dirt.png"},
|
||||
drop = "default:dirt",
|
||||
groups = {crumbly=3, not_in_creative_inventory=1, soil=2, grassland = 1, field = 1},
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.1},
|
||||
}),
|
||||
soil = {
|
||||
base = "default:dirt",
|
||||
dry = "farming:soil",
|
||||
wet = "farming:soil_wet"
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_node("farming:soil_wet", {
|
||||
description = "Wet Soil",
|
||||
tiles = {"default_dirt.png^farming_soil_wet.png", "default_dirt.png^farming_soil_wet_side.png"},
|
||||
drop = "default:dirt",
|
||||
groups = {crumbly=3, not_in_creative_inventory=1, soil=3, wet = 1, grassland = 1, field = 1},
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name="default_grass_footstep", gain=0.1},
|
||||
}),
|
||||
soil = {
|
||||
base = "default:dirt",
|
||||
dry = "farming:soil",
|
||||
wet = "farming:soil_wet"
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
label = "Farming soil",
|
||||
nodenames = {"group:field"},
|
||||
interval = 15,
|
||||
chance = 4,
|
||||
action = function(pos, node)
|
||||
local n_def = minetest.registered_nodes[node.name] or nil
|
||||
local wet = n_def.soil.wet or nil
|
||||
local base = n_def.soil.base or nil
|
||||
local dry = n_def.soil.dry or nil
|
||||
if not n_def or not n_def.soil or not wet or not base or not dry then
|
||||
return
|
||||
end
|
||||
|
||||
pos.y = pos.y + 1
|
||||
local nn = minetest.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
|
||||
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})
|
||||
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
|
||||
-- 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})
|
||||
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
|
||||
-- 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})
|
||||
end
|
||||
|
||||
-- if its wet turn it back into dry soil
|
||||
elseif wet_lvl == 1 then
|
||||
minetest.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'}},
|
||||
}
|
||||
}})
|
After Width: | Height: | Size: 297 B |
After Width: | Height: | Size: 237 B |
After Width: | Height: | Size: 277 B |
After Width: | Height: | Size: 322 B |
After Width: | Height: | Size: 404 B |
After Width: | Height: | Size: 150 B |
After Width: | Height: | Size: 287 B |
After Width: | Height: | Size: 272 B |
After Width: | Height: | Size: 152 B |
After Width: | Height: | Size: 158 B |
After Width: | Height: | Size: 144 B |
After Width: | Height: | Size: 908 B |
After Width: | Height: | Size: 411 B |
After Width: | Height: | Size: 335 B |
After Width: | Height: | Size: 341 B |
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 345 B |
After Width: | Height: | Size: 397 B |
After Width: | Height: | Size: 359 B |
After Width: | Height: | Size: 322 B |
After Width: | Height: | Size: 629 B |
After Width: | Height: | Size: 711 B |
After Width: | Height: | Size: 968 B |
After Width: | Height: | Size: 141 B |