Add files via upload

This commit is contained in:
Shad MOrdre 2018-01-19 11:53:48 -08:00 committed by GitHub
parent 70fbb8ddb9
commit 4669b94b46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 4709 additions and 0 deletions

378
anvil.lua Normal file
View File

@ -0,0 +1,378 @@
---------------------------------------------------------------------------------------
-- simple anvil that can be used to repair tools
---------------------------------------------------------------------------------------
-- * can be used to repair tools
-- * the hammer gets dammaged a bit at each repair step
---------------------------------------------------------------------------------------
anvil = {
setting = {
item_displacement = 7/16,
}
}
minetest.register_alias("castle:anvil", "anvil:anvil", "cottages:anvil")
-- internationalization boilerplate
--local MP = minetest.get_modpath(minetest.get_current_modname())
--local S, NS = dofile(MP.."/intllib.lua")
local S = lib_tools.S
-- the hammer for the anvil
minetest.register_tool("lib_tools:anvil_hammer", {
description = S("Steel blacksmithing hammer"),
_doc_items_longdesc = S("A tool for repairing other tools at a blacksmith's anvil."),
_doc_items_usagehelp = S("Use this hammer to strike blows upon an anvil bearing a damaged tool and you can repair it. It can also be used for smashing stone, but it is not well suited to this task."),
image = "anvil_tool_steelhammer.png",
inventory_image = "anvil_tool_steelhammer.png",
tool_capabilities = {
full_punch_interval = 0.8,
max_drop_level=1,
groupcaps={
-- about equal to a stone pick (it's not intended as a tool)
cracky={times={[2]=2.00, [3]=1.20}, uses=30, maxlevel=1},
},
damage_groups = {fleshy=6},
}
})
local tmp = {}
minetest.register_entity("lib_tools:anvil_item",{
hp_max = 1,
visual="wielditem",
visual_size={x=.33,y=.33},
collisionbox = {0,0,0,0,0,0},
physical=false,
textures={"air"},
on_activate = function(self, staticdata)
if tmp.nodename ~= nil and tmp.texture ~= nil then
self.nodename = tmp.nodename
tmp.nodename = nil
self.texture = tmp.texture
tmp.texture = nil
else
if staticdata ~= nil and staticdata ~= "" then
local data = staticdata:split(';')
if data and data[1] and data[2] then
self.nodename = data[1]
self.texture = data[2]
end
end
end
if self.texture ~= nil then
self.object:set_properties({textures={self.texture}})
end
end,
get_staticdata = function(self)
if self.nodename ~= nil and self.texture ~= nil then
return self.nodename .. ';' .. self.texture
end
return ""
end,
})
local remove_item = function(pos, node)
local objs = minetest.get_objects_inside_radius({x = pos.x, y = pos.y + anvil.setting.item_displacement, z = pos.z}, .5)
if objs then
for _, obj in ipairs(objs) do
if obj and obj:get_luaentity() and obj:get_luaentity().name == "lib_tools:anvil_item" then
obj:remove()
end
end
end
end
local update_item = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("input") then
pos.y = pos.y + anvil.setting.item_displacement
tmp.nodename = node.name
tmp.texture = inv:get_stack("input", 1):get_name()
local e = minetest.add_entity(pos,"lib_tools:anvil_item")
local yaw = math.pi*2 - node.param2 * math.pi/2
e:setyaw(yaw)
end
end
local metal_sounds
-- Apparently node_sound_metal_defaults is a newer thing, I ran into games using an older version of the default mod without it.
if default.node_sound_metal_defaults ~= nil then
metal_sounds = default.node_sound_metal_defaults()
else
metal_sounds = default.node_sound_stone_defaults()
end
minetest.register_node("lib_tools:anvil", {
drawtype = "nodebox",
description = S("Anvil"),
_doc_items_longdesc = S("A tool for repairing other tools in conjunction with a blacksmith's hammer."),
_doc_items_usagehelp = S("Right-click on this anvil with a damaged tool to place the damaged tool upon it. You can then repair the damaged tool by striking it with a blacksmith's hammer. Repeated blows may be necessary to fully repair a badly worn tool. To retrieve the tool either punch or right-click the anvil with an empty hand."),
tiles = {"default_stone.png"},
paramtype = "light",
paramtype2 = "facedir",
groups = {cracky=2},
sounds = metal_sounds,
-- the nodebox model comes from realtest
node_box = {
type = "fixed",
fixed = {
{-0.5,-0.5,-0.3,0.5,-0.4,0.3},
{-0.35,-0.4,-0.25,0.35,-0.3,0.25},
{-0.3,-0.3,-0.15,0.3,-0.1,0.15},
{-0.35,-0.1,-0.2,0.35,0.1,0.2},
},
},
selection_box = {
type = "fixed",
fixed = {
{-0.5,-0.5,-0.3,0.5,-0.4,0.3},
{-0.35,-0.4,-0.25,0.35,-0.3,0.25},
{-0.3,-0.3,-0.15,0.3,-0.1,0.15},
{-0.35,-0.1,-0.2,0.35,0.1,0.2},
}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("input", 1)
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("input") then
return false
end
return true
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
if listname~="input" then
return 0
end
if (listname=='input'
and(stack:get_wear() == 0
or minetest.get_item_group(stack:get_name(), "not_repaired_by_anvil") ~= 0
or stack:get_name() == "technic:water_can"
or stack:get_name() == "technic:lava_can" )) then
minetest.chat_send_player( player:get_player_name(), S('This anvil is for damaged tools only.'))
return 0
end
if meta:get_inventory():room_for_item("input", stack) then
return stack:get_count()
end
return 0
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if listname~="input" then
return 0
end
return stack:get_count()
end,
on_rightclick = function(pos, node, clicker, itemstack)
if itemstack:get_count() == 0 then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("input") then
local return_stack = inv:get_stack("input", 1)
inv:set_stack("input", 1, nil)
local wield_index = clicker:get_wield_index()
clicker:get_inventory():set_stack("main", wield_index, return_stack)
remove_item(pos, node)
return return_stack
end
end
local this_def = minetest.registered_nodes[node.name]
if this_def.allow_metadata_inventory_put(pos, "input", 1, itemstack:peek_item(), clicker) > 0 then
local s = itemstack:take_item()
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:add_item("input", s)
update_item(pos,node)
end
return itemstack
end,
on_punch = function(pos, node, puncher)
if( not( pos ) or not( node ) or not( puncher )) then
return
end
local wielded = puncher:get_wielded_item()
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if wielded:get_count() == 0 then
if not inv:is_empty("input") then
local return_stack = inv:get_stack("input", 1)
inv:set_stack("input", 1, nil)
local wield_index = puncher:get_wield_index()
puncher:get_inventory():set_stack("main", wield_index, return_stack)
remove_item(pos, node)
end
end
-- only punching with the hammer is supposed to work
if wielded:get_name() ~= 'lib_tools:anvil_hammer' then
return
end
local input = inv:get_stack('input',1)
-- only tools can be repaired
if( not( input )
or input:is_empty()
or input:get_name() == "technic:water_can"
or input:get_name() == "technic:lava_can" ) then
return
end
-- 65535 is max damage
local damage_state = 40-math.floor(input:get_wear()/1638)
local tool_name = input:get_name()
local hud2 = nil
local hud3 = nil
if( input:get_wear()>0 ) then
hud2 = puncher:hud_add({
hud_elem_type = "statbar",
text = "default_cloud.png^[colorize:#ff0000:256",
number = 40,
direction = 0, -- left to right
position = {x=0.5, y=0.65},
alignment = {x = 0, y = 0},
offset = {x = -320, y = 0},
size = {x=32, y=32},
})
hud3 = puncher:hud_add({
hud_elem_type = "statbar",
text = "default_cloud.png^[colorize:#00ff00:256",
number = damage_state,
direction = 0, -- left to right
position = {x=0.5, y=0.65},
alignment = {x = 0, y = 0},
offset = {x = -320, y = 0},
size = {x=32, y=32},
})
end
minetest.after(2, function()
if( puncher ) then
puncher:hud_remove(hud2)
puncher:hud_remove(hud3)
end
end)
-- tell the player when the job is done
if( input:get_wear() == 0 ) then
local tool_desc
if minetest.registered_items[tool_name] and minetest.registered_items[tool_name].description then
tool_desc = minetest.registered_items[tool_name].description
else
tool_desc = tool_name
end
minetest.chat_send_player( puncher:get_player_name(), S('Your @1 has been repaired successfully.', tool_desc))
return
else
--pos.y = pos.y + anvil_item_displacement
pos.y = pos.y + 7/16
minetest.sound_play({name="anvil_clang"}, {pos=pos})
minetest.add_particlespawner({
amount = 10,
time = 0.1,
minpos = pos,
maxpos = pos,
minvel = {x=2, y=3, z=2},
maxvel = {x=-2, y=1, z=-2},
minacc = {x=0, y= -10, z=0},
maxacc = {x=0, y= -10, z=0},
minexptime = 0.5,
maxexptime = 1,
minsize = 1,
maxsize = 1,
collisiondetection = true,
vertical = false,
texture = "anvil_spark.png",
})
end
-- do the actual repair
input:add_wear( -5000 ) -- equals to what technic toolshop does in 5 seconds
inv:set_stack("input", 1, input)
-- damage the hammer slightly
wielded:add_wear( 100 )
puncher:set_wielded_item( wielded )
end,
is_ground_content = false,
})
-- automatically restore entities lost due to /clearobjects or similar
minetest.register_lbm({
name = "lib_tools:anvil_item_restoration",
nodenames = { "lib_tools:anvil" },
run_at_every_load = true,
action = function(pos, node, active_object_count, active_object_count_wider)
--local test_pos = {x=pos.x, y=pos.y + anvil_item_displacement, z=pos.z}
local test_pos = {x=pos.x, y=pos.y + 7/16, z=pos.z}
if #minetest.get_objects_inside_radius(test_pos, 0.5) > 0 then return end
update_item(pos, node)
end
})
-- Transfer the hammer from the old hammer storage slot to the main slot, or else drop it in world
minetest.register_lbm({
name = "lib_tools:hammer_ejection",
nodenames = "lib_tools:anvil",
run_at_every_load = false,
action = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("anvil_hammer") then
local hammer = inv:get_stack("anvil_hammer", 1)
inv:set_stack("anvil_hammer", 1, nil)
inv:set_size("anvil_hammer", 0)
if inv:is_empty("input") then
inv:set_stack("input", 1, hammer) -- the abm will ensure there's an entity showing the hammer is here
else
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, hammer)
end
end
end
})
---------------------------------------------------------------------------------------
-- crafting receipes
---------------------------------------------------------------------------------------
minetest.register_craft({
output = "lib_tools:anvil",
recipe = {
{"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
{'', "default:steel_ingot",'' },
{"default:steel_ingot","default:steel_ingot","default:steel_ingot"} },
})
minetest.register_craft({
output = "lib_tools:anvil_hammer",
recipe = {
{"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
{"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
{'', "group:stick", '' } }
})

625
chess.lua Normal file
View File

@ -0,0 +1,625 @@
local realchess = {}
screwdriver = screwdriver or {}
local function index_to_xy(idx)
idx = idx - 1
local x = idx % 8
local y = (idx - x) / 8
return x, y
end
local function xy_to_index(x, y)
return x + y * 8 + 1
end
function realchess.init(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local formspec = [[ size[8,8.6;]
bgcolor[#080808BB;true]
background[0,0;8,8;chess_bg.png]
button[3.1,7.8;2,2;new;New game]
list[context;board;0,0;8,8;]
listcolors[#00000000;#00000000;#00000000;#30434C;#FFF] ]]
meta:set_string("formspec", formspec)
meta:set_string("infotext", "Chess Board")
meta:set_string("playerBlack", "")
meta:set_string("playerWhite", "")
meta:set_string("lastMove", "")
meta:set_string("winner", "")
meta:set_int("lastMoveTime", 0)
meta:set_int("castlingBlackL", 1)
meta:set_int("castlingBlackR", 1)
meta:set_int("castlingWhiteL", 1)
meta:set_int("castlingWhiteR", 1)
inv:set_list("board", {
"realchess:rook_black_1",
"realchess:knight_black_1",
"realchess:bishop_black_1",
"realchess:queen_black",
"realchess:king_black",
"realchess:bishop_black_2",
"realchess:knight_black_2",
"realchess:rook_black_2",
"realchess:pawn_black_1",
"realchess:pawn_black_2",
"realchess:pawn_black_3",
"realchess:pawn_black_4",
"realchess:pawn_black_5",
"realchess:pawn_black_6",
"realchess:pawn_black_7",
"realchess:pawn_black_8",
'','','','','','','','','','','','','','','','',
'','','','','','','','','','','','','','','','',
"realchess:pawn_white_1",
"realchess:pawn_white_2",
"realchess:pawn_white_3",
"realchess:pawn_white_4",
"realchess:pawn_white_5",
"realchess:pawn_white_6",
"realchess:pawn_white_7",
"realchess:pawn_white_8",
"realchess:rook_white_1",
"realchess:knight_white_1",
"realchess:bishop_white_1",
"realchess:queen_white",
"realchess:king_white",
"realchess:bishop_white_2",
"realchess:knight_white_2",
"realchess:rook_white_2"
})
inv:set_size("board", 64)
end
function realchess.move(pos, from_list, from_index, to_list, to_index, _, player)
if from_list ~= "board" and to_list ~= "board" then
return 0
end
local playerName = player:get_player_name()
local meta = minetest.get_meta(pos)
if meta:get_string("winner") ~= "" then
minetest.chat_send_player(playerName, "This game is over.")
return 0
end
local inv = meta:get_inventory()
local pieceFrom = inv:get_stack(from_list, from_index):get_name()
local pieceTo = inv:get_stack(to_list, to_index):get_name()
local lastMove = meta:get_string("lastMove")
local thisMove -- will replace lastMove when move is legal
local playerWhite = meta:get_string("playerWhite")
local playerBlack = meta:get_string("playerBlack")
if pieceFrom:find("white") then
if playerWhite ~= "" and playerWhite ~= playerName then
minetest.chat_send_player(playerName, "Someone else plays white pieces!")
return 0
end
if lastMove ~= "" and lastMove ~= "black" then
minetest.chat_send_player(playerName, "It's not your turn, wait for your opponent to play.")
return 0
end
if pieceTo:find("white") then
-- Don't replace pieces of same color
return 0
end
playerWhite = playerName
thisMove = "white"
elseif pieceFrom:find("black") then
if playerBlack ~= "" and playerBlack ~= playerName then
minetest.chat_send_player(playerName, "Someone else plays black pieces!")
return 0
end
if lastMove ~= "" and lastMove ~= "white" then
minetest.chat_send_player(playerName, "It's not your turn, wait for your opponent to play.")
return 0
end
if pieceTo:find("black") then
-- Don't replace pieces of same color
return 0
end
playerBlack = playerName
thisMove = "black"
end
-- DETERMINISTIC MOVING
local from_x, from_y = index_to_xy(from_index)
local to_x, to_y = index_to_xy(to_index)
if pieceFrom:sub(11,14) == "pawn" then
if thisMove == "white" then
local pawnWhiteMove = inv:get_stack(from_list, xy_to_index(from_x, from_y - 1)):get_name()
-- white pawns can go up only
if from_y - 1 == to_y then
if from_x == to_x then
if pieceTo ~= "" then
return 0
elseif to_index >= 1 and to_index <= 8 then
inv:set_stack(from_list, from_index, "realchess:queen_white")
end
elseif from_x - 1 == to_x or from_x + 1 == to_x then
if not pieceTo:find("black") then
return 0
elseif to_index >= 1 and to_index <= 8 then
inv:set_stack(from_list, from_index, "realchess:queen_white")
end
else
return 0
end
elseif from_y - 2 == to_y then
if pieceTo ~= "" or from_y < 6 or pawnWhiteMove ~= "" then
return 0
end
else
return 0
end
elseif thisMove == "black" then
local pawnBlackMove = inv:get_stack(from_list, xy_to_index(from_x, from_y + 1)):get_name()
-- black pawns can go down only
if from_y + 1 == to_y then
if from_x == to_x then
if pieceTo ~= "" then
return 0
elseif to_index >= 57 and to_index <= 64 then
inv:set_stack(from_list, from_index, "realchess:queen_black")
end
elseif from_x - 1 == to_x or from_x + 1 == to_x then
if not pieceTo:find("white") then
return 0
elseif to_index >= 57 and to_index <= 64 then
inv:set_stack(from_list, from_index, "realchess:queen_black")
end
else
return 0
end
elseif from_y + 2 == to_y then
if pieceTo ~= "" or from_y > 1 or pawnBlackMove ~= "" then
return 0
end
else
return 0
end
-- if x not changed,
-- ensure that destination cell is empty
-- elseif x changed one unit left or right
-- ensure the pawn is killing opponent piece
-- else
-- move is not legal - abort
if from_x == to_x then
if pieceTo ~= "" then
return 0
end
elseif from_x - 1 == to_x or from_x + 1 == to_x then
if not pieceTo:find("white") then
return 0
end
else
return 0
end
else
return 0
end
elseif pieceFrom:sub(11,14) == "rook" then
if from_x == to_x then
-- moving vertically
if from_y < to_y then
-- moving down
-- ensure that no piece disturbs the way
for i = from_y + 1, to_y - 1 do
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
return 0
end
end
else
-- mocing up
-- ensure that no piece disturbs the way
for i = to_y + 1, from_y - 1 do
if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then
return 0
end
end
end
elseif from_y == to_y then
-- mocing horizontally
if from_x < to_x then
-- mocing right
-- ensure that no piece disturbs the way
for i = from_x + 1, to_x - 1 do
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
return 0
end
end
else
-- mocing left
-- ensure that no piece disturbs the way
for i = to_x + 1, from_x - 1 do
if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then
return 0
end
end
end
else
-- attempt to move arbitrarily -> abort
return 0
end
if thisMove == "white" or thisMove == "black" then
if pieceFrom:sub(-1) == "1" then
meta:set_int("castlingWhiteL", 0)
elseif pieceFrom:sub(-1) == "2" then
meta:set_int("castlingWhiteR", 0)
end
end
elseif pieceFrom:sub(11,16) == "knight" then
-- get relative pos
local dx = from_x - to_x
local dy = from_y - to_y
-- get absolute values
if dx < 0 then dx = -dx end
if dy < 0 then dy = -dy end
-- sort x and y
if dx > dy then dx, dy = dy, dx end
-- ensure that dx == 1 and dy == 2
if dx ~= 1 or dy ~= 2 then
return 0
end
-- just ensure that destination cell does not contain friend piece
-- ^ it was done already thus everything ok
elseif pieceFrom:sub(11,16) == "bishop" then
-- get relative pos
local dx = from_x - to_x
local dy = from_y - to_y
-- get absolute values
if dx < 0 then dx = -dx end
if dy < 0 then dy = -dy end
-- ensure dx and dy are equal
if dx ~= dy then return 0 end
if from_x < to_x then
if from_y < to_y then
-- moving right-down
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
return 0
end
end
else
-- moving right-up
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
return 0
end
end
end
else
if from_y < to_y then
-- moving left-down
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
return 0
end
end
else
-- moving left-up
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
return 0
end
end
end
end
elseif pieceFrom:sub(11,15) == "queen" then
local dx = from_x - to_x
local dy = from_y - to_y
-- get absolute values
if dx < 0 then dx = -dx end
if dy < 0 then dy = -dy end
-- ensure valid relative move
if dx ~= 0 and dy ~= 0 and dx ~= dy then
return 0
end
if from_x == to_x then
if from_y < to_y then
-- goes down
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x, from_y + i)):get_name() ~= "" then
return 0
end
end
else
-- goes up
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x, from_y - i)):get_name() ~= "" then
return 0
end
end
end
elseif from_x < to_x then
if from_y == to_y then
-- goes right
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x + i, from_y)):get_name() ~= "" then
return 0
end
end
elseif from_y < to_y then
-- goes right-down
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then
return 0
end
end
else
-- goes right-up
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then
return 0
end
end
end
else
if from_y == to_y then
-- goes left
-- ensure that no piece disturbs the way and destination cell does
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x - i, from_y)):get_name() ~= "" then
return 0
end
end
elseif from_y < to_y then
-- goes left-down
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then
return 0
end
end
else
-- goes left-up
-- ensure that no piece disturbs the way
for i = 1, dx - 1 do
if inv:get_stack(from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then
return 0
end
end
end
end
elseif pieceFrom:sub(11,14) == "king" then
local dx = from_x - to_x
local dy = from_y - to_y
local check = true
if thisMove == "white" then
if from_y == 7 and to_y == 7 then
if to_x == 1 then
local castlingWhiteL = meta:get_int("castlingWhiteL")
local idx57 = inv:get_stack(from_list, 57):get_name()
if castlingWhiteL == 1 and idx57 == "realchess:rook_white_1" then
for i = 58, from_index - 1 do
if inv:get_stack(from_list, i):get_name() ~= "" then
return 0
end
end
inv:set_stack(from_list, 57, "")
inv:set_stack(from_list, 59, "realchess:rook_white_1")
check = false
end
elseif to_x == 6 then
local castlingWhiteR = meta:get_int("castlingWhiteR")
local idx64 = inv:get_stack(from_list, 64):get_name()
if castlingWhiteR == 1 and idx64 == "realchess:rook_white_2" then
for i = from_index + 1, 63 do
if inv:get_stack(from_list, i):get_name() ~= "" then
return 0
end
end
inv:set_stack(from_list, 62, "realchess:rook_white_2")
inv:set_stack(from_list, 64, "")
check = false
end
end
end
elseif thisMove == "black" then
if from_y == 0 and to_y == 0 then
if to_x == 1 then
local castlingBlackL = meta:get_int("castlingBlackL")
local idx1 = inv:get_stack(from_list, 1):get_name()
if castlingBlackL == 1 and idx1 == "realchess:rook_black_1" then
for i = 2, from_index - 1 do
if inv:get_stack(from_list, i):get_name() ~= "" then
return 0
end
end
inv:set_stack(from_list, 1, "")
inv:set_stack(from_list, 3, "realchess:rook_black_1")
check = false
end
elseif to_x == 6 then
local castlingBlackR = meta:get_int("castlingBlackR")
local idx8 = inv:get_stack(from_list, 1):get_name()
if castlingBlackR == 1 and idx8 == "realchess:rook_black_2" then
for i = from_index + 1, 7 do
if inv:get_stack(from_list, i):get_name() ~= "" then
return 0
end
end
inv:set_stack(from_list, 6, "realchess:rook_black_2")
inv:set_stack(from_list, 8, "")
check = false
end
end
end
end
if check then
if dx < 0 then dx = -dx end
if dy < 0 then dy = -dy end
if dx > 1 or dy > 1 then return 0 end
end
if thisMove == "white" then
meta:set_int("castlingWhiteL", 0)
meta:set_int("castlingWhiteR", 0)
elseif thisMove == "black" then
meta:set_int("castlingBlackL", 0)
meta:set_int("castlingBlackR", 0)
end
end
meta:set_string("playerWhite", playerWhite)
meta:set_string("playerBlack", playerBlack)
meta:set_string("lastMove", thisMove)
meta:set_int("lastMoveTime", minetest.get_gametime())
local lastMove = meta:get_string("lastMove")
if lastMove == "black" then
minetest.chat_send_player(playerWhite, "["..os.date("%H:%M:%S").."] "..
playerName.." moved a "..pieceFrom:match(":(%a+)")..", it's now your turn.")
elseif lastMove == "white" then
minetest.chat_send_player(playerBlack, "["..os.date("%H:%M:%S").."] "..
playerName.." moved a "..pieceFrom:match(":(%a+)")..", it's now your turn.")
end
if pieceTo:sub(11,14) == "king" then
minetest.chat_send_player(playerBlack, playerName.." won the game.")
minetest.chat_send_player(playerWhite, playerName.." won the game.")
meta:set_string("winner", thisMove)
end
return 1
end
local function timeout_format(timeout_limit)
local time_remaining = timeout_limit - minetest.get_gametime()
local minutes = math.floor(time_remaining / 60)
local seconds = time_remaining % 60
if minutes == 0 then return seconds.." sec." end
return minutes.." min. "..seconds.." sec."
end
function realchess.fields(pos, _, fields, sender)
local playerName = sender:get_player_name()
local meta = minetest.get_meta(pos)
local timeout_limit = meta:get_int("lastMoveTime") + 300
local playerWhite = meta:get_string("playerWhite")
local playerBlack = meta:get_string("playerBlack")
local lastMoveTime = meta:get_int("lastMoveTime")
if fields.quit then return end
-- timeout is 5 min. by default for resetting the game (non-players only)
if fields.new and (playerWhite == playerName or playerBlack == playerName) then
realchess.init(pos)
elseif fields.new and lastMoveTime ~= 0 and minetest.get_gametime() >= timeout_limit and
(playerWhite ~= playerName or playerBlack ~= playerName) then
realchess.init(pos)
else
minetest.chat_send_player(playerName, "[!] You can't reset the chessboard, a game has been started.\n"..
"If you are not a current player, try again in "..timeout_format(timeout_limit))
end
end
function realchess.dig(pos, player)
local meta = minetest.get_meta(pos)
local playerName = player:get_player_name()
local timeout_limit = meta:get_int("lastMoveTime") + 300
local lastMoveTime = meta:get_int("lastMoveTime")
-- timeout is 5 min. by default for digging the chessboard (non-players only)
return (lastMoveTime == 0 and minetest.get_gametime() > timeout_limit) or
minetest.chat_send_player(playerName, "[!] You can't dig the chessboard, a game has been started.\n"..
"Reset it first if you're a current player, or dig again in "..timeout_format(timeout_limit))
end
function realchess.on_move(pos, from_list, from_index)
local inv = minetest.get_meta(pos):get_inventory()
inv:set_stack(from_list, from_index, '')
return false
end
minetest.register_node(":realchess:chessboard", {
description = "Chess Board",
drawtype = "nodebox",
paramtype = "light",
paramtype2 = "facedir",
inventory_image = "chessboard_top.png",
wield_image = "chessboard_top.png",
tiles = {"chessboard_top.png", "chessboard_top.png", "chessboard_sides.png"},
groups = {choppy=3, oddly_breakable_by_hand=2, flammable=3},
sounds = default.node_sound_wood_defaults(),
node_box = {type = "fixed", fixed = {-.375, -.5, -.375, .375, -.4375, .375}},
sunlight_propagates = true,
on_rotate = screwdriver.rotate_simple,
can_dig = realchess.dig,
on_construct = realchess.init,
on_receive_fields = realchess.fields,
allow_metadata_inventory_move = realchess.move,
on_metadata_inventory_move = realchess.on_move,
allow_metadata_inventory_take = function() return 0 end
})
local function register_piece(name, count)
for _, color in pairs({"black", "white"}) do
if not count then
minetest.register_craftitem(":realchess:"..name.."_"..color, {
description = color:gsub("^%l", string.upper).." "..name:gsub("^%l", string.upper),
inventory_image = name.."_"..color..".png",
stack_max = 1,
groups = {not_in_creative_inventory=1}
})
else
for i = 1, count do
minetest.register_craftitem(":realchess:"..name.."_"..color.."_"..i, {
description = color:gsub("^%l", string.upper).." "..name:gsub("^%l", string.upper),
inventory_image = name.."_"..color..".png",
stack_max = 1,
groups = {not_in_creative_inventory=1}
})
end
end
end
end
register_piece("pawn", 8)
register_piece("rook", 2)
register_piece("knight", 2)
register_piece("bishop", 2)
register_piece("queen")
register_piece("king")

44
config.lua Normal file
View File

@ -0,0 +1,44 @@
lib_tools.config = lib_tools.config or Settings(minetest.get_worldpath().."/lib_tools.conf")
local conf_table = lib_tools.config:to_table()
local defaults = {
enable_mining_drill = "false",
enable_mining_laser = "false",
enable_flashlight = "true",
enable_wind_mill = "false",
enable_frames = "false",
enable_corium_griefing = "false",
enable_radiation_protection = "true",
enable_entity_radiation_damage = "true",
enable_longterm_radiation_damage = "true",
enable_nuclear_reactor_digiline_selfdestruct = "false",
enable_granite_generation = "true",
enable_marble_generation = "true",
enable_rubber_tree_generation = "true",
}
for k, v in pairs(defaults) do
if conf_table[k] == nil then
lib_tools.config:set(k, v)
end
end
lib_tools.power_tools = {}
function lib_tools.register_power_tool(craftitem, max_charge)
lib_tools.power_tools[craftitem] = max_charge
end
--- Fully charge RE chargeable item.
-- Must be defined early to reference in item definitions.
function lib_tools.refill_RE_charge(stack)
local max_charge = lib_tools.power_tools[stack:get_name()]
if not max_charge then return stack end
lib_tools.set_RE_wear(stack, max_charge, max_charge)
local meta = minetest.deserialize(stack:get_metadata()) or {}
meta.charge = max_charge
stack:set_metadata(minetest.serialize(meta))
return stack
end

200
cooking.lua Normal file
View File

@ -0,0 +1,200 @@
local cauldron, sounds = {}, {}
-- Add more ingredients here that make a soup.
local ingredients_list = {
"apple", "mushroom", "honey", "pumpkin", "egg", "bread", "meat",
"chicken", "carrot", "potato", "melon", "rhubarb", "cucumber",
"corn", "beans", "berries", "grapes", "tomato", "wheat"
}
cauldron.cbox = {
{0, 0, 0, 16, 16, 0},
{0, 0, 16, 16, 16, 0},
{0, 0, 0, 0, 16, 16},
{16, 0, 0, 0, 16, 16},
{0, 0, 0, 16, 8, 16}
}
function cauldron.stop_sound(pos)
local spos = minetest.hash_node_position(pos)
if sounds[spos] then minetest.sound_stop(sounds[spos]) end
end
function cauldron.idle_construct(pos)
local timer = minetest.get_node_timer(pos)
timer:start(10.0)
cauldron.stop_sound(pos)
end
function cauldron.boiling_construct(pos)
local spos = minetest.hash_node_position(pos)
sounds[spos] = minetest.sound_play("xdecor_boiling_water", {
pos=pos, max_hear_distance=5, gain=0.8, loop=true
})
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Cauldron (active) - Drop some foods inside to make a soup")
local timer = minetest.get_node_timer(pos)
timer:start(5.0)
end
function cauldron.filling(pos, node, clicker, itemstack)
local inv = clicker:get_inventory()
local wield_item = clicker:get_wielded_item():get_name()
if wield_item:sub(1,7) == "bucket:" then
if wield_item:sub(-6) == "_empty" and not (node.name:sub(-6) == "_empty") then
if itemstack:get_count() > 1 then
if inv:room_for_item("main", "bucket:bucket_water 1") then
itemstack:take_item()
inv:add_item("main", "bucket:bucket_water 1")
else
minetest.chat_send_player(clicker:get_player_name(),
"No room in your inventory to add a bucket of water.")
return itemstack
end
else
itemstack:replace("bucket:bucket_water")
end
minetest.set_node(pos, {name="lib_tools:cauldron_empty", param2=node.param2})
elseif wield_item:sub(-6) == "_water" and node.name:sub(-6) == "_empty" then
minetest.set_node(pos, {name="lib_tools:cauldron_idle", param2=node.param2})
itemstack:replace("bucket:bucket_empty")
end
return itemstack
end
end
function cauldron.idle_timer(pos)
local below_node = {x=pos.x, y=pos.y-1, z=pos.z}
if not minetest.get_node(below_node).name:find("fire") then
return true
end
local node = minetest.get_node(pos)
minetest.set_node(pos, {name="lib_tools:cauldron_boiling", param2=node.param2})
return true
end
-- Ugly hack to determine if an item has the function `minetest.item_eat` in its definition.
local function eatable(itemstring)
local item = itemstring:match("[%w_:]+")
local on_use_def = minetest.registered_items[item].on_use
if not on_use_def then return end
return string.format("%q", string.dump(on_use_def)):find("item_eat")
end
function cauldron.boiling_timer(pos)
local node = minetest.get_node(pos)
local objs = minetest.get_objects_inside_radius(pos, 0.5)
if not next(objs) then return true end
local ingredients = {}
for _, obj in pairs(objs) do
if obj and not obj:is_player() and obj:get_luaentity().itemstring then
local itemstring = obj:get_luaentity().itemstring
local food = itemstring:match(":([%w_]+)")
for _, ingredient in pairs(ingredients_list) do
if food and (eatable(itemstring) or food:find(ingredient)) then
ingredients[#ingredients+1] = food break
end
end
end
end
if #ingredients >= 2 then
for _, obj in pairs(objs) do obj:remove() end
minetest.set_node(pos, {name="lib_tools:cauldron_soup", param2=node.param2})
end
local node_under = {x=pos.x, y=pos.y-1, z=pos.z}
if not minetest.get_node(node_under).name:find("fire") then
minetest.set_node(pos, {name="lib_tools:cauldron_idle", param2=node.param2})
end
return true
end
function cauldron.take_soup(pos, node, clicker, itemstack)
local inv = clicker:get_inventory()
local wield_item = clicker:get_wielded_item()
if wield_item:get_name() == "lib_tools:bowl" then
if wield_item:get_count() > 1 then
if inv:room_for_item("main", "lib_tools:bowl_soup 1") then
itemstack:take_item()
inv:add_item("main", "lib_tools:bowl_soup 1")
else
minetest.chat_send_player(clicker:get_player_name(),
"No room in your inventory to add a bowl of soup.")
return itemstack
end
else
itemstack:replace("lib_tools:bowl_soup 1")
end
minetest.set_node(pos, {name="lib_tools:cauldron_empty", param2=node.param2})
end
return itemstack
end
lib_tools.register("cauldron_empty", {
description = "Cauldron",
groups = {cracky=2, oddly_breakable_by_hand=1},
on_rotate = screwdriver.rotate_simple,
tiles = {"xdecor_cauldron_top_empty.png", "xdecor_cauldron_sides.png"},
infotext = "Cauldron (empty)",
on_construct = function(pos)
cauldron.stop_sound(pos)
end,
on_rightclick = cauldron.filling,
collision_box = lib_tools.pixelbox(16, cauldron.cbox)
})
lib_tools.register("cauldron_idle", {
groups = {cracky=2, oddly_breakable_by_hand=1, not_in_creative_inventory=1},
on_rotate = screwdriver.rotate_simple,
tiles = {"xdecor_cauldron_top_idle.png", "xdecor_cauldron_sides.png"},
drop = "lib_tools:cauldron_empty",
infotext = "Cauldron (idle)",
collision_box = lib_tools.pixelbox(16, cauldron.cbox),
on_rightclick = cauldron.filling,
on_construct = cauldron.idle_construct,
on_timer = cauldron.idle_timer
})
lib_tools.register("cauldron_boiling", {
groups = {cracky=2, oddly_breakable_by_hand=1, not_in_creative_inventory=1},
on_rotate = screwdriver.rotate_simple,
drop = "lib_tools:cauldron_empty",
infotext = "Cauldron (active) - Drop foods inside to make a soup",
damage_per_second = 2,
tiles = {{name="xdecor_cauldron_top_anim_boiling_water.png",
animation={type="vertical_frames", length=3.0}},
"xdecor_cauldron_sides.png"},
collision_box = lib_tools.pixelbox(16, cauldron.cbox),
on_rightclick = cauldron.filling,
on_construct = cauldron.boiling_construct,
on_destruct = function(pos)
cauldron.stop_sound(pos)
end,
on_timer = cauldron.boiling_timer
})
lib_tools.register("cauldron_soup", {
groups = {cracky=2, oddly_breakable_by_hand=1, not_in_creative_inventory=1},
on_rotate = screwdriver.rotate_simple,
drop = "lib_tools:cauldron_empty",
infotext = "Cauldron (active) - Use a bowl to eat the soup",
damage_per_second = 2,
tiles = {{name="xdecor_cauldron_top_anim_soup.png",
animation={type="vertical_frames", length=3.0}},
"xdecor_cauldron_sides.png"},
collision_box = lib_tools.pixelbox(16, cauldron.cbox),
on_rightclick = cauldron.take_soup,
on_destruct = function(pos)
cauldron.stop_sound(pos)
end
})

156
craftguide.lua Normal file
View File

@ -0,0 +1,156 @@
local craftguide, datas, npp = {}, {}, 8*3
function craftguide:get_recipe(item)
if item:sub(1,6) == "group:" then
if item:sub(-4) == "wool" or item:sub(-3) == "dye" then
item = item:sub(7)..":white"
elseif minetest.registered_items["default:"..item:sub(7)] then
item = item:gsub("group:", "default:")
else for node, def in pairs(minetest.registered_items) do
if def.groups[item:match("[^,:]+$")] then item = node end
end
end
end
return item
end
function craftguide:set_formspec(player_name, pagenum, recipe_num)
local data = datas[player_name]
local formspec = [[ size[8,6.6;]
tablecolumns[color;text;color;text]
tableoptions[background=#00000000;highlight=#00000000;border=false]
button[5.4,0;0.8,0.95;prev;<]
button[7.2,0;0.8,0.95;next;>]
button[2.5,0.2;0.8,0.5;search;?]
button[3.2,0.2;0.8,0.5;clear;X]
tooltip[search;Search]
tooltip[clear;Reset]
table[6,0.18;1.1,0.5;pagenum;#FFFF00,]]..
pagenum..",#FFFFFF,/ "..data.pagemax.."]"..
"field[0.3,0.32;2.6,1;filter;;"..data.filter.."]"..
default.gui_bg..default.gui_bg_img
local i, s = 0, 0
for _, name in pairs(data.items) do
if s < (pagenum - 1) * npp then
s = s + 1
else if i >= npp then break end
local X = i % 8
local Y = ((i-X) / 8) + 1
formspec = formspec.."item_image_button["..X..","..Y..";1,1;"..
name..";"..name..";]"
i = i + 1
end
end
if data.item and minetest.registered_items[data.item] then
local recipes = minetest.get_all_craft_recipes(data.item)
if recipe_num > #recipes then recipe_num = 1 end
if #recipes > 1 then formspec = formspec..
[[ button[0,6;1.6,1;alternate;Alternate]
label[0,5.5;Recipe ]]..recipe_num.." of "..#recipes.."]"
end
local type = recipes[recipe_num].type
if type == "cooking" then formspec = formspec..
"image[3.75,4.6;0.5,0.5;default_furnace_front.png]"
end
local items = recipes[recipe_num].items
local width = recipes[recipe_num].width
if width == 0 then width = math.min(3, #items) end
-- Lua 5.3 removed `table.maxn`, use `lib_tools.maxn` in case of breakage.
local rows = math.ceil(table.maxn(items) / width)
for i, v in pairs(items) do
local X = (i-1) % width + 4.5
local Y = math.floor((i-1) / width + (6 - math.min(2, rows)))
local label = ""
if v:sub(1,6) == "group:" then label = "\nG" end
formspec = formspec.."item_image_button["..X..","..Y..";1,1;"..
self:get_recipe(v)..";"..self:get_recipe(v)..";"..label.."]"
end
local output = recipes[recipe_num].output
formspec = formspec..[[ image[3.5,5;1,1;gui_furnace_arrow_bg.png^[transformR90]
item_image_button[2.5,5;1,1;]]..output..";"..data.item..";]"
end
data.formspec = formspec
minetest.show_formspec(player_name, "lib_tools:craftguide", formspec)
end
function craftguide:get_items(player_name)
local items_list, data = {}, datas[player_name]
for name, def in pairs(minetest.registered_items) do
if not (def.groups.not_in_creative_inventory == 1) and
minetest.get_craft_recipe(name).items and
def.description and def.description ~= "" and
(def.name:find(data.filter, 1, true) or
def.description:lower():find(data.filter, 1, true)) then
items_list[#items_list+1] = name
end
end
table.sort(items_list)
data.items = items_list
data.size = #items_list
data.pagemax = math.ceil(data.size / npp)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "lib_tools:craftguide" then return end
local player_name = player:get_player_name()
local data = datas[player_name]
local formspec = data.formspec
local pagenum = tonumber(formspec:match("#FFFF00,(%d+)")) or 1
if fields.clear then
data.filter, data.item = "", nil
craftguide:get_items(player_name)
craftguide:set_formspec(player_name, 1, 1)
elseif fields.alternate then
local recipe_num = tonumber(formspec:match("Recipe%s(%d+)")) or 1
recipe_num = recipe_num + 1
craftguide:set_formspec(player_name, pagenum, recipe_num)
elseif fields.search then
data.filter = fields.filter:lower()
craftguide:get_items(player_name)
craftguide:set_formspec(player_name, 1, 1)
elseif fields.prev or fields.next then
if fields.prev then pagenum = pagenum - 1
else pagenum = pagenum + 1 end
if pagenum > data.pagemax then pagenum = 1
elseif pagenum == 0 then pagenum = data.pagemax end
craftguide:set_formspec(player_name, pagenum, 1)
else for item in pairs(fields) do
if minetest.get_craft_recipe(item).items then
data.item = item
craftguide:set_formspec(player_name, pagenum, 1)
end
end
end
end)
minetest.register_craftitem("lib_tools:crafting_guide", {
description = "Crafting Guide",
inventory_image = "lib_tools_crafting_guide.png",
wield_image = "lib_tools_crafting_guide.png",
stack_max = 1,
groups = {book=1},
on_use = function(itemstack, user)
local player_name = user:get_player_name()
if not datas[player_name] then
datas[player_name] = {}
datas[player_name].filter = ""
craftguide:get_items(player_name)
craftguide:set_formspec(player_name, 1, 1)
else
minetest.show_formspec(player_name, "lib_tools:craftguide", datas[player_name].formspec)
end
end
})

9
depends.txt Normal file
View File

@ -0,0 +1,9 @@
default
wool
3d_armor?
pipeworks?
bucket?
screwdriver?
mesecons?
mesecons_mvps?
intllib?

283
enchanting.lua Normal file
View File

@ -0,0 +1,283 @@
local enchanting = {}
screwdriver = screwdriver or {}
-- Cost in Mese crystal(s) for enchanting.
local mese_cost = 1
-- Force of the enchantments.
enchanting.uses = 1.2 -- Durability
enchanting.times = 0.1 -- Efficiency
enchanting.damages = 1 -- Sharpness
enchanting.strength = 1.2 -- Armor strength (3d_armor only)
enchanting.speed = 0.2 -- Player speed (3d_armor only)
enchanting.jump = 0.2 -- Player jumping (3d_armor only)
function enchanting.formspec(pos, num)
local meta = minetest.get_meta(pos)
local formspec = [[ size[9,9;]
bgcolor[#080808BB;true]
background[0,0;9,9;ench_ui.png]
list[context;tool;0.9,2.9;1,1;]
list[context;mese;2,2.9;1,1;]
list[current_player;main;0.5,4.5;8,4;]
image[2,2.9;1,1;mese_layout.png]
tooltip[sharp;Your weapon inflicts more damages]
tooltip[durable;Your tool last longer]
tooltip[fast;Your tool digs faster]
tooltip[strong;Your armor is more resistant]
tooltip[speed;Your speed is increased] ]]
..default.gui_slots..default.get_hotbar_bg(0.5,4.5)
local enchant_buttons = {
[[ image_button[3.9,0.85;4,0.92;bg_btn.png;fast;Efficiency]
image_button[3.9,1.77;4,1.12;bg_btn.png;durable;Durability] ]],
"image_button[3.9,0.85;4,0.92;bg_btn.png;strong;Strength]",
"image_button[3.9,2.9;4,0.92;bg_btn.png;sharp;Sharpness]",
[[ image_button[3.9,0.85;4,0.92;bg_btn.png;strong;Strength]
image_button[3.9,1.77;4,1.12;bg_btn.png;speed;Speed] ]]
}
formspec = formspec..(enchant_buttons[num] or "")
meta:set_string("formspec", formspec)
end
function enchanting.on_put(pos, listname, _, stack)
if listname == "tool" then
local stackname = stack:get_name()
local tool_groups = {
"axe, pick, shovel",
"chestplate, leggings, helmet",
"sword", "boots"
}
for idx, tools in pairs(tool_groups) do
if tools:find(stackname:match(":(%w+)")) then
enchanting.formspec(pos, idx)
end
end
end
end
function enchanting.fields(pos, _, fields, sender)
if fields.quit then return end
local inv = minetest.get_meta(pos):get_inventory()
local tool = inv:get_stack("tool", 1)
local mese = inv:get_stack("mese", 1)
local orig_wear = tool:get_wear()
local mod, name = tool:get_name():match("(.*):(.*)")
local enchanted_tool = (mod or "")..":enchanted_"..(name or "").."_"..next(fields)
if mese:get_count() >= mese_cost and minetest.registered_tools[enchanted_tool] then
minetest.sound_play("xdecor_enchanting", {to_player=sender:get_player_name(), gain=0.8})
tool:replace(enchanted_tool)
tool:add_wear(orig_wear)
mese:take_item(mese_cost)
inv:set_stack("mese", 1, mese)
inv:set_stack("tool", 1, tool)
end
end
function enchanting.dig(pos)
local inv = minetest.get_meta(pos):get_inventory()
return inv:is_empty("tool") and inv:is_empty("mese")
end
local function allowed(tool)
for item in pairs(minetest.registered_tools) do
if item:find("enchanted_"..tool) then return true end
end
return false
end
function enchanting.put(_, listname, _, stack)
local item = stack:get_name():match("[^:]+$")
if listname == "mese" and item == "mese_crystal" then
return stack:get_count()
elseif listname == "tool" and allowed(item) then
return 1
end
return 0
end
function enchanting.on_take(pos, listname)
if listname == "tool" then enchanting.formspec(pos, nil) end
end
function enchanting.construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Enchantment Table")
enchanting.formspec(pos, nil)
local inv = meta:get_inventory()
inv:set_size("tool", 1)
inv:set_size("mese", 1)
minetest.add_entity({x=pos.x, y=pos.y+0.85, z=pos.z}, "lib_tools:book_open")
local timer = minetest.get_node_timer(pos)
timer:start(5.0)
end
function enchanting.destruct(pos)
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do
if obj and obj:get_luaentity() and
obj:get_luaentity().name == "lib_tools:book_open" then
obj:remove() break
end
end
end
function enchanting.timer(pos)
local node = minetest.get_node(pos)
local num = #minetest.get_objects_inside_radius(pos, 0.9)
if num == 0 then
minetest.add_entity({x=pos.x, y=pos.y+0.85, z=pos.z}, "lib_tools:book_open")
end
local minp = {x=pos.x-2, y=pos.y, z=pos.z-2}
local maxp = {x=pos.x+2, y=pos.y+1, z=pos.z+2}
local bookshelves = minetest.find_nodes_in_area(minp, maxp, "default:bookshelf")
if #bookshelves == 0 then return true end
local bookshelf_pos = bookshelves[math.random(1, #bookshelves)]
local x = pos.x - bookshelf_pos.x
local y = bookshelf_pos.y - pos.y
local z = pos.z - bookshelf_pos.z
if tostring(x..z):find(2) then
minetest.add_particle({
pos = bookshelf_pos,
velocity = {x=x, y=2-y, z=z},
acceleration = {x=0, y=-2.2, z=0},
expirationtime = 1,
size = 2,
texture = "xdecor_glyph"..math.random(1,18)..".png"
})
end
return true
end
lib_tools.register("enchantment_table", {
description = "Enchantment Table",
tiles = {"xdecor_enchantment_top.png", "xdecor_enchantment_bottom.png",
"xdecor_enchantment_side.png", "xdecor_enchantment_side.png",
"xdecor_enchantment_side.png", "xdecor_enchantment_side.png"},
groups = {cracky=1, level=1},
sounds = default.node_sound_stone_defaults(),
on_rotate = screwdriver.rotate_simple,
can_dig = enchanting.dig,
on_timer = enchanting.timer,
on_construct = enchanting.construct,
on_destruct = enchanting.destruct,
on_receive_fields = enchanting.fields,
on_metadata_inventory_put = enchanting.on_put,
on_metadata_inventory_take = enchanting.on_take,
allow_metadata_inventory_put = enchanting.put,
allow_metadata_inventory_move = function() return 0 end
})
minetest.register_entity("lib_tools:book_open", {
visual = "sprite",
visual_size = {x=0.75, y=0.75},
collisionbox = {0},
physical = false,
textures = {"xdecor_book_open.png"},
on_activate = function(self)
local pos = self.object:getpos()
local pos_under = {x=pos.x, y=pos.y-1, z=pos.z}
if minetest.get_node(pos_under).name ~= "lib_tools:enchantment_table" then
self.object:remove()
end
end
})
local function cap(S) return S:gsub("^%l", string.upper) end
function enchanting:register_tools(mod, def)
for tool in pairs(def.tools) do
for material in def.materials:gmatch("[%w_]+") do
for enchant in def.tools[tool].enchants:gmatch("[%w_]+") do
local original_tool = minetest.registered_tools[mod..":"..tool.."_"..material]
if not original_tool then return end
if original_tool.tool_capabilities then
local original_damage_groups = original_tool.tool_capabilities.damage_groups
local original_groupcaps = original_tool.tool_capabilities.groupcaps
local groupcaps = table.copy(original_groupcaps)
local fleshy = original_damage_groups.fleshy
local full_punch_interval = original_tool.tool_capabilities.full_punch_interval
local max_drop_level = original_tool.tool_capabilities.max_drop_level
local group = next(original_groupcaps)
if enchant == "durable" then
groupcaps[group].uses = math.ceil(original_groupcaps[group].uses * enchanting.uses)
elseif enchant == "fast" then
for i, time in pairs(original_groupcaps[group].times) do
groupcaps[group].times[i] = time - enchanting.times
end
elseif enchant == "sharp" then
fleshy = fleshy + enchanting.damages
end
minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, {
description = "Enchanted "..cap(material).." "..cap(tool).." ("..cap(enchant)..")",
inventory_image = original_tool.inventory_image.."^[colorize:violet:50",
wield_image = original_tool.wield_image,
groups = {not_in_creative_inventory=1},
tool_capabilities = {
groupcaps = groupcaps, damage_groups = {fleshy = fleshy},
full_punch_interval = full_punch_interval, max_drop_level = max_drop_level
}
})
end
if mod == "3d_armor" then
local original_armor_groups = original_tool.groups
local armorcaps = {}
armorcaps.not_in_creative_inventory = 1
for armor_group, value in pairs(original_armor_groups) do
if enchant == "strong" then
armorcaps[armor_group] = math.ceil(value * enchanting.strength)
elseif enchant == "speed" then
armorcaps[armor_group] = value
armorcaps.physics_speed = enchanting.speed
armorcaps.physics_jump = enchanting.jump
end
end
minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, {
description = "Enchanted "..cap(material).." "..cap(tool).." ("..cap(enchant)..")",
inventory_image = original_tool.inventory_image,
texture = "3d_armor_"..tool.."_"..material,
wield_image = original_tool.wield_image,
groups = armorcaps,
wear = 0
})
end
end
end
end
end
enchanting:register_tools("default", {
materials = "steel, bronze, mese, diamond",
tools = {
axe = {enchants = "durable, fast"},
pick = {enchants = "durable, fast"},
shovel = {enchants = "durable, fast"},
sword = {enchants = "sharp"}
}
})
enchanting:register_tools("3d_armor", {
materials = "steel, bronze, gold, diamond",
tools = {
boots = {enchants = "strong, speed"},
chestplate = {enchants = "strong"},
helmet = {enchants = "strong"},
leggings = {enchants = "strong"}
}
})

743
enchanting3.lua Normal file
View File

@ -0,0 +1,743 @@
local enchanting3 = {}
screwdriver = screwdriver or {}
local tmp_crystal = {}
local tmp_item = {}
local max_objs = tonumber(minetest.setting_get("max_objects_per_block")) or 49
local S = lib_tools.S
-- Cost in Mese crystal(s) for enchanting.
local mese_cost = 1
local current_enchant = ""
local max_enchant = 65535
-- Force of the enchantments.
enchanting3.uses = 1.2 -- Durability
enchanting3.times = 0.1 -- Efficiency
enchanting3.damages = 1 -- Sharpness
enchanting3.strength = 1.2 -- Armor strength (3d_armor only)
enchanting3.speed = 0.2 -- Player speed (3d_armor only)
enchanting3.jump = 0.2 -- Player jumping (3d_armor only)
-- the scroll for casting enchantments
minetest.register_tool("lib_tools:enchanting_wand", {
description = S("Enchanting Scroll"),
_doc_items_longdesc = S("A scroll to cast an enchantment on a tool or armor item."),
_doc_items_usagehelp = S("Punch the Enchanting Stand to cast the scroll spell as an enchantment on the tool or armor item."),
image = "wand_mese.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
-- about equal to a stone pick (it's not intended as a tool)
casting={maxlevel=3, uses=1, times={[1]=4.00}},
},
}
})
minetest.register_entity("lib_tools:slot_crystal", {
hp_max = 1,
visual="wielditem",
visual_size={x = 0.15, y = 0.15},
collisionbox = {0, 0, 0, 0, 0, 0},
physical = false,
textures = {"air"},
on_activate = function(self, staticdata)
if (mobs and mobs.entity and mobs.entity == false)
or not self then
self.object:remove()
return
end
if tmp_crystal.nodename ~= nil
and tmp_crystal.texture ~= nil then
self.nodename = tmp_crystal.nodename
tmp_crystal.nodename = nil
self.texture = tmp_crystal.texture
tmp_crystal.texture = nil
else
if staticdata ~= nil
and staticdata ~= "" then
local data = staticdata:split(';')
if data and data[1] and data[2] then
self.nodename = data[1]
self.texture = data[2]
end
end
end
if self.texture ~= nil then
self.object:set_properties({textures = {self.texture}})
end
self.object:set_properties({automatic_rotate = 1})
end,
get_staticdata = function(self)
if self.nodename ~= nil
and self.texture ~= nil then
return self.nodename .. ';' .. self.texture
end
return ""
end,
})
minetest.register_entity("lib_tools:slot_item", {
hp_max = 1,
visual="wielditem",
visual_size={x = 0.50, y = 0.50},
collisionbox = {0, 0, 0, 0, 0, 0},
physical = false,
textures = {"air"},
on_activate = function(self, staticdata)
if (mobs and mobs.entity and mobs.entity == false)
or not self then
self.object:remove()
return
end
if tmp_item.nodename ~= nil
and tmp_item.texture ~= nil then
self.nodename = tmp_item.nodename
tmp_item.nodename = nil
self.texture = tmp_item.texture
tmp_item.texture = nil
else
if staticdata ~= nil
and staticdata ~= "" then
local data = staticdata:split(';')
if data and data[1] and data[2] then
self.nodename = data[1]
self.texture = data[2]
end
end
end
if self.texture ~= nil then
self.object:set_properties({textures = {self.texture}})
end
end,
get_staticdata = function(self)
if self.nodename ~= nil
and self.texture ~= nil then
return self.nodename .. ';' .. self.texture
end
return ""
end,
})
-- functions
local remove_tool = function(pos, node)
local objs = minetest.get_objects_inside_radius({x = pos.x, y = pos.y + anvil.setting.item_displacement, z = pos.z}, .5)
if objs then
for _, obj in ipairs(objs) do
if obj and obj:get_luaentity() and obj:get_luaentity().name == "lib_tools:slot_item" then
obj:remove()
end
end
end
end
local remove_crystal = function(pos, node)
local objs = minetest.get_objects_inside_radius({x = pos.x, y = pos.y + anvil.setting.item_displacement, z = pos.z}, .5)
if objs then
for _, obj in ipairs(objs) do
if obj and obj:get_luaentity() and obj:get_luaentity().name == "lib_tools:slot_crystal" then
obj:remove()
end
end
end
end
local update_tool = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("tool") then
remove_tool(pos, node)
pos.y = pos.y + 0.75
tmp_item.nodename = node.name
tmp_item.texture = inv:get_stack("tool", 1):get_name()
local e = minetest.add_entity(pos,"lib_tools:slot_item")
pos.y = pos.y - 0.75
else
remove_tool(pos, node)
end
end
local update_crystal = function(pos, node)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("mese") then
remove_crystal(pos, node)
pos.y = pos.y + 0.35
tmp_crystal.nodename = node.name
tmp_crystal.texture = inv:get_stack("mese", 1):get_name()
local e = minetest.add_entity(pos,"lib_tools:slot_crystal")
pos.y = pos.y - 0.35
local yaw = math.pi*2 - node.param2 * math.pi/2
e:setyaw(yaw)
else
remove_crystal(pos, node)
end
end
local function allowed_tools(tool)
if not tool then
return
end
for item in pairs(minetest.registered_tools) do
if item:find("enchanted_"..tool) then return true end
end
return false
end
local function allowed_crystals(crystal)
if not crystal then
return
end
for item in pairs(minetest.registered_craftitems) do
if item:find(crystal) then
return true
end
end
return false
-- if crystal == "mese_crystal" then
-- return true
-- end
-- return false
end
--RENAME TO enchanting_altar
lib_tools.register("altar_of_enchanting", {
description = "Altar Of Enchanting",
_doc_items_longdesc = S("An altar for enchanting armor and tools in conjunction with a mese crystal and magic scroll."),
_doc_items_usagehelp = S("Right-click on this enchantment_table with a mese crystal to enable enchanting. Right click with an armor piece or tool to place the item upon it. You can then enchant the item by punching it with a scroll. Repeated punches may be necessary, depending on the enchantment, to fully an item. To retrieve the item either punch or right-click the anvil with an empty hand."),
drawtype = "nodebox",
tiles = {"altar_01_top.png^mese_layout.png", "altar_01_top.png",
"altar_02_side.png", "altar_02_side.png",
"altar_02_side.png", "altar_02_side.png"},
use_texture_alpha = true,
paramtype = "light",
post_effect_color = { r=128, g=128, b=128, a=128 },
light_source = 0,
groups = {cracky=1, level=1},
sounds = default.node_sound_stone_defaults(),
on_rotate = screwdriver.rotate_simple,
can_dig = enchanting3.dig,
node_box = {
type = "fixed",
fixed = {
{-0.25, -0.5, -0.25, 0.25, 0.125, 0.25}, -- NodeBox1
{-0.5, 0, -0.0625, 0.5, 0.125, 0.0625}, -- NodeBox2
{-0.0625, 0, -0.5, 0.0625, 0.125, 0.5}, -- NodeBox3
{-0.5, 0.125, -0.0625, -0.4375, 0.5, 0.0625}, -- NodeBox4
{-0.0625, 0.125, 0.4375, 0.0625, 0.5, 0.5}, -- NodeBox5
{0.4375, 0.125, -0.0625, 0.5, 0.5, 0.0625}, -- NodeBox6
{-0.0625, 0, -0.5, 0.0625, 0.5, -0.4375}, -- NodeBox7
}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
meta:set_string("infotext", "Enchantment Table")
inv:set_size("tool", 1)
inv:set_size("mese", 1)
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos)
meta:set_string("owner", placer:get_player_name() or "")
end,
on_metadata_inventory_put = function(pos, listname, _, stack)
if listname == "tool" then
local tool_stackname = stack:get_name()
local tool_groups = {
"axe, pick, shovel, bow, arrow",
"chestplate, leggings, helmet",
"sword", "boots"
}
for idx, tools in pairs(tool_groups) do
if tools:find(tool_stackname:match(":(%w+)")) then
update_tool(pos, stack)
end
end
end
if listname == "mese" then
-- local crystal_stackname = stack:get_name()
-- local crystal_groups = {
-- "crystal, diamond, shard"
-- }
-- for idx, crystals in pairs(crystal_groups) do
-- if crystals:find(crystal_stackname:match(":(%w+)")) then
update_crystal(pos, stack)
-- end
-- end
end
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
if listname == "tool" then
update_tool(pos, stack)
end
if listname == "mese" then
update_crystal(pos, stack)
end
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
-- local item = stack:get_name():match("[^:]+$")
-- if listname == "mese" then
-- return stack:get_count()
-- elseif listname == "tool" and allowed(item) then
-- return 1
-- end
-- return 0
local item = stack:get_name():match("[^:]+$")
local meta = minetest.get_meta(pos)
-- if listname=="tool" or listname=="mese" then
if listname=='tool' then
if not allowed_tools(item) then
minetest.chat_send_player( player:get_player_name(), S('This enchanting table is for picks, axes, shovels, and armor type tools only.'))
return 0
end
if meta:get_inventory():room_for_item("tool", stack) then
return 1
end
return 0
end
if listname=='mese' then
if not allowed_crystals(item) then
minetest.chat_send_player( player:get_player_name(), S('You can only enchant items with a Mese Crystal, Mese Crystal Fragment, Diamond, or Obsidian Shard.'))
minetest.chat_send_player( player:get_player_name(), S('Mese Crystal => Durable; Mese Crystal Fragment => Fast; Diamond => Strong; Obsidian Shard => Sharp'))
minetest.chat_send_player( player:get_player_name(), S('For Picks, Axes, Shovels: Durable or Fast; For Swords: Sharp'))
minetest.chat_send_player( player:get_player_name(), S('For Chestplates, Helmets, Leggings: Strong; For Boots: Strong or Fast,'))
return 0
end
if meta:get_inventory():room_for_item("mese", stack) then
return 1
end
return 0
end
-- end
return 0
end,
allow_metadata_inventory_move = function()
return 0
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("tool") then
return false
end
if not inv:is_empty("mese") then
return false
end
return true
end,
on_rightclick = function(pos, node, clicker, itemstack)
local itemstack_count = itemstack:get_count()
if itemstack:get_count() == 0 then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("tool") then
local tool_return_stack = inv:get_stack("tool", 1)
inv:set_stack("tool", 1, nil)
local wield_index = clicker:get_wield_index()
clicker:get_inventory():set_stack("main", wield_index, tool_return_stack)
update_tool(pos, node)
itemstack_count = itemstack_count + 1
return tool_return_stack
end
else
local this_def = minetest.registered_nodes[node.name]
if this_def.allow_metadata_inventory_put(pos, "tool", 1, itemstack:peek_item(), clicker) > 0 then
local s = itemstack:take_item(1)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:add_item("tool", s)
update_tool(pos,node)
end
end
if itemstack:get_count() == 0 then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if not inv:is_empty("mese") then
local crystal_return_stack = inv:get_stack("mese", 1)
inv:set_stack("mese", 1, nil)
local wield_index = clicker:get_wield_index()
clicker:get_inventory():set_stack("main", wield_index, crystal_return_stack)
update_crystal(pos, node)
return crystal_return_stack
end
else
local this_def = minetest.registered_nodes[node.name]
if this_def.allow_metadata_inventory_put(pos, "mese", 1, itemstack:peek_item(), clicker) > 0 then
local s = itemstack:take_item(1)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:add_item("mese", s)
update_crystal(pos,node)
end
end
return itemstack
end,
on_punch = function(pos, node, puncher)
if( not( pos ) or not( node ) or not( puncher )) then
return
end
local wielded = puncher:get_wielded_item()
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
--local tool = inv:get_stack("tool", 1)
local input = inv:get_stack('tool',1)
local mese = inv:get_stack("mese", 1)
local orig_wear = input:get_wear()
local tool_name = input:get_name()
-- 65535 is max damage
local enchant_state = 40-math.floor(max_enchant/1638)
if wielded:get_count() == 0 then
if not inv:is_empty("tool") then
local return_stack = inv:get_stack("tool", 1)
inv:set_stack("tool", 1, nil)
local wield_index = puncher:get_wield_index()
puncher:get_inventory():set_stack("main", wield_index, return_stack)
update_tool(pos, node)
end
end
-- only punching with the hammer is supposed to work
if wielded:get_name() ~= 'lib_tools:enchanting_wand' then
return
end
-- only tools can be repaired
if( not( input )
or input:is_empty()
or input:get_name() == "technic:water_can"
or input:get_name() == "technic:lava_can" ) then
return
end
local hud2 = nil
local hud3 = nil
if( enchant_state>0 ) then
hud2 = puncher:hud_add({
hud_elem_type = "statbar",
text = "default_cloud.png^[colorize:#ff0000:256",
number = 40,
direction = 0, -- left to right
position = {x=0.5, y=0.65},
alignment = {x = 0, y = 0},
offset = {x = -320, y = 0},
size = {x=32, y=32},
})
hud3 = puncher:hud_add({
hud_elem_type = "statbar",
text = "default_cloud.png^[colorize:#00ff00:256",
number = enchant_state,
direction = 0, -- left to right
position = {x=0.5, y=0.65},
alignment = {x = 0, y = 0},
offset = {x = -320, y = 0},
size = {x=32, y=32},
})
end
minetest.after(2, function()
if( puncher ) then
puncher:hud_remove(hud2)
puncher:hud_remove(hud3)
end
end)
-- tell the player when the job is done
if( max_enchant <= 0 ) then
local tool_desc
if minetest.registered_items[tool_name] and minetest.registered_items[tool_name].description then
tool_desc = minetest.registered_items[tool_name].description
else
tool_desc = tool_name
end
if not inv:is_empty("mese") then
if mese:get_name():find("crystal") then
if mese:get_name():find("fragment") then
current_enchant = "fast"
else
current_enchant = "durable"
end
end
if mese:get_name():find("diamond") then
current_enchant = "strong"
end
if mese:get_name():find("obsidian") then
current_enchant = "sharp"
end
end
local mod, name = input:get_name():match("(.*):(.*)")
local enchanted_tool = (mod or "")..":enchanted_"..(name or "").."_"..current_enchant
--if mese_cost <= mese:get_count() and minetest.registered_tools[enchanted_tool] then
minetest.sound_play("xdecor_enchanting", {to_player=puncher:get_player_name(), gain=0.8})
--input:replace(enchanted_tool)
input:take_item(1)
input:add_item(enchanted_tool)
input:add_wear(orig_wear)
mese:take_item(mese_cost)
inv:set_stack("mese", 1, mese)
inv:set_stack("tool", 1, nil)
remove_crystal(pos, node)
update_tool(pos, node)
current_enchant = ""
max_enchant = 65535
--end
if (wielded:set_wear( 65535 )) then
puncher:set_wielded_item( input )
end
minetest.chat_send_player( puncher:get_player_name(), S('Your @1 has been enchanted.', tool_desc))
else
pos.y = pos.y + 0.75
minetest.sound_play({name="xdecor_enchanting"}, {pos=pos, gain=0.8})
max_enchant = max_enchant - (65535/8)
minetest.add_particlespawner({
amount = 10,
time = 0.1,
minpos = pos,
maxpos = pos,
minvel = {x=2, y=3, z=2},
maxvel = {x=-2, y=1, z=-2},
minacc = {x=0, y= -10, z=0},
maxacc = {x=0, y= -10, z=0},
minexptime = 0.5,
maxexptime = 1,
minsize = 1,
maxsize = 1,
collisiondetection = true,
vertical = false,
texture = "xdecor_glyph"..math.random(1,18)..".png",
})
-- do the actual repair
--input:add_wear( -5000 ) -- equals to what technic toolshop does in 5 seconds
--inv:set_stack("input", 1, input)
-- damage the hammer slightly
wielded:add_wear( 65535/8 )
--puncher:set_wielded_item( wielded )
end
end,
})
local function cap(S) return S:gsub("^%l", string.upper) end
function enchanting3:register_tools(mod, def)
for tool in pairs(def.tools) do
for material in def.materials:gmatch("[%w_]+") do
for enchant in def.tools[tool].enchants:gmatch("[%w_]+") do
local original_tool = minetest.registered_tools[mod..":"..tool.."_"..material]
if not original_tool then return end
if original_tool.tool_capabilities then
local original_damage_groups = original_tool.tool_capabilities.damage_groups
local original_groupcaps = original_tool.tool_capabilities.groupcaps
local groupcaps = table.copy(original_groupcaps)
local fleshy = original_damage_groups.fleshy
local full_punch_interval = original_tool.tool_capabilities.full_punch_interval
local max_drop_level = original_tool.tool_capabilities.max_drop_level
local group = next(original_groupcaps)
local enchanted_texture = original_tool.inventory_image.."^[colorize:violet:65"
if enchant == "durable" then
groupcaps[group].uses = math.ceil(original_groupcaps[group].uses * enchanting3.uses)
elseif enchant == "fast" then
for i, time in pairs(original_groupcaps[group].times) do
groupcaps[group].times[i] = time - enchanting3.times
end
elseif enchant == "sharp" then
fleshy = fleshy + enchanting3.damages
end
minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, {
description = "Enchanted "..cap(material).." "..cap(tool).." ("..cap(enchant)..")",
inventory_image = original_tool.inventory_image.."^[colorize:violet:50",
wield_image = original_tool.wield_image,
groups = {not_in_creative_inventory=1},
tool_capabilities = {
groupcaps = groupcaps, damage_groups = {fleshy = fleshy},
full_punch_interval = full_punch_interval, max_drop_level = max_drop_level
}
})
end
if mod == "3d_armor" then
local original_armor_groups = original_tool.groups
local armorcaps = {}
armorcaps.not_in_creative_inventory = 1
for armor_group, value in pairs(original_armor_groups) do
if enchant == "strong" then
armorcaps[armor_group] = math.ceil(value * enchanting3.strength)
elseif enchant == "speed" then
armorcaps[armor_group] = value
armorcaps.physics_speed = enchanting3.speed
armorcaps.physics_jump = enchanting3.jump
end
end
minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, {
description = "Enchanted "..cap(material).." "..cap(tool).." ("..cap(enchant)..")",
inventory_image = original_tool.inventory_image.."^[colorize:violet:50",
texture = "3d_armor_"..tool.."_"..material,
wield_image = original_tool.wield_image,
groups = armorcaps,
wear = 0
})
end
if mod == "armor_additions" then
local original_armor_groups = original_tool.groups
local armorcaps = {}
armorcaps.not_in_creative_inventory = 1
for armor_group, value in pairs(original_armor_groups) do
if enchant == "strong" then
armorcaps[armor_group] = math.ceil(value * enchanting3.strength)
elseif enchant == "speed" then
armorcaps[armor_group] = value
armorcaps.physics_speed = enchanting3.speed
armorcaps.physics_jump = enchanting3.jump
end
end
minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, {
description = "Enchanted "..cap(material).." "..cap(tool).." ("..cap(enchant)..")",
inventory_image = original_tool.inventory_image.."^[colorize:violet:50",
texture = "armor_additions_"..tool.."_"..material,
wield_image = original_tool.wield_image,
groups = armorcaps,
wear = 0
})
end
end
end
end
end
enchanting3:register_tools("default", {
materials = "steel, bronze, mese, diamond",
tools = {
axe = {enchants = "durable, fast"},
pick = {enchants = "durable, fast"},
shovel = {enchants = "durable, fast"},
sword = {enchants = "sharp"}
}
})
-- enchanting3:register_tools("bows", {
-- materials = "steel, bronze, mese, diamond, obsidian",
-- tools = {
-- bow = {enchants = "durable, fast"}
-- }
-- })
-- enchanting3:register_tools("bows", {
-- materials = "steel, gold, mese, diamond",
-- tools = {
-- arrow = {enchants = "sharp"}
-- }
-- })
enchanting3:register_tools("3d_armor", {
materials = "steel, bronze, gold, diamond",
tools = {
boots = {enchants = "strong, speed"},
chestplate = {enchants = "strong"},
helmet = {enchants = "strong"},
leggings = {enchants = "strong"}
}
})
enchanting3:register_tools("armor_additions", {
materials = "carbon, carbonfiber, cast, stainless, wrought, obsidian, chainmail, studded",
tools = {
boots = {enchants = "strong, speed"},
chestplate = {enchants = "strong"},
helmet = {enchants = "strong"},
leggings = {enchants = "strong"}
}
})

125
flashlight.lua Normal file
View File

@ -0,0 +1,125 @@
-- Original code comes from walkin_light mod by Echo
-- http://minetest.net/forum/viewtopic.php?id=2621
local flashlight_max_charge = 30000
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
lib_tools.register_power_tool("lib_tools:flashlight", flashlight_max_charge)
minetest.register_alias("lib_tools:light_off", "air")
minetest.register_tool("lib_tools:flashlight", {
description = S("Flashlight"),
inventory_image = "technic_flashlight.png",
stack_max = 1,
wear_represents = "technic_RE_charge",
on_refill = lib_tools.refill_RE_charge,
})
minetest.register_craft({
output = "lib_tools:flashlight",
recipe = {
{"lib_tools:rubber", "default:glass", "lib_tools:rubber"},
{"lib_tools:stainless_steel_ingot", "lib_tools:battery", "lib_tools:stainless_steel_ingot"},
{"", "lib_tools:battery", ""}
}
})
local player_positions = {}
local was_wielding = {}
local function check_for_flashlight(player)
if player == nil then
return false
end
local inv = player:get_inventory()
local hotbar = inv:get_list("main")
for i = 1, 8 do
if hotbar[i]:get_name() == "lib_tools:flashlight" then
local meta = minetest.deserialize(hotbar[i]:get_metadata())
if meta and meta.charge and meta.charge >= 2 then
if not lib_tools.creative_mode then
meta.charge = meta.charge - 2;
lib_tools.set_RE_wear(hotbar[i], meta.charge, flashlight_max_charge)
hotbar[i]:set_metadata(minetest.serialize(meta))
inv:set_stack("main", i, hotbar[i])
end
return true
end
end
end
return false
end
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
local pos = player:getpos()
local rounded_pos = vector.round(pos)
rounded_pos.y = rounded_pos.y + 1
player_positions[player_name] = rounded_pos
was_wielding[player_name] = true
end)
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
local pos = player_positions[player_name]
local nodename = minetest.get_node(pos).name
if nodename == "lib_tools:light" then
minetest.remove_node(pos)
end
player_positions[player_name] = nil
end)
minetest.register_globalstep(function(dtime)
for i, player in pairs(minetest.get_connected_players()) do
local player_name = player:get_player_name()
local flashlight_weared = check_for_flashlight(player)
local pos = player:getpos()
local rounded_pos = vector.round(pos)
rounded_pos.y = rounded_pos.y + 1
local old_pos = player_positions[player_name]
local player_moved = old_pos and not vector.equals(old_pos, rounded_pos)
if not old_pos then
old_pos = rounded_pos
player_moved = true
end
-- Remove light, flashlight weared out or was removed from hotbar
if was_wielding[player_name] and not flashlight_weared then
was_wielding[player_name] = false
local node = minetest.get_node_or_nil(old_pos)
if node and node.name == "lib_tools:light" then
minetest.remove_node(old_pos)
end
elseif (player_moved or not was_wielding[player_name]) and flashlight_weared then
local node = minetest.get_node_or_nil(rounded_pos)
if node and node.name == "air" then
minetest.set_node(rounded_pos, {name="lib_tools:light"})
end
local node = minetest.get_node_or_nil(old_pos)
if node and node.name == "lib_tools:light" then
minetest.remove_node(old_pos)
end
player_positions[player_name] = rounded_pos
was_wielding[player_name] = true
end
end
end)
minetest.register_node("lib_tools:light", {
drawtype = "glasslike",
tiles = {"technic_light.png"},
paramtype = "light",
groups = {not_in_creative_inventory=1},
drop = "",
walkable = false,
buildable_to = true,
sunlight_propagates = true,
light_source = LIGHT_MAX,
pointable = false,
})

142
init.lua Normal file
View File

@ -0,0 +1,142 @@
lib_tools = {}
-- internationalization boilerplate
lib_tools.MP = minetest.get_modpath(minetest.get_current_modname())
lib_tools.gettext, lib_tools.ngettext = dofile(lib_tools.MP.."/intllib.lua")
lib_tools.S = lib_tools.gettext
lib_tools.NS = lib_tools.ngettext
--local S, NS = dofile(MP.."/intllib.lua")
dofile(minetest.get_modpath("lib_tools").."/utils.lua")
dofile(minetest.get_modpath("lib_tools").."/registration.lua")
dofile(minetest.get_modpath("lib_tools").."/anvil.lua")
dofile(minetest.get_modpath("lib_tools").."/chess.lua")
dofile(minetest.get_modpath("lib_tools").."/cooking.lua")
dofile(minetest.get_modpath("lib_tools").."/craftguide.lua")
dofile(minetest.get_modpath("lib_tools").."/enchanting3.lua")
dofile(minetest.get_modpath("lib_tools").."/enchanting.lua")
dofile(minetest.get_modpath("lib_tools").."/mailbox.lua")
dofile(minetest.get_modpath("lib_tools").."/mechanisms.lua")
dofile(minetest.get_modpath("lib_tools").."/nodes_straw.lua")
dofile(minetest.get_modpath("lib_tools").."/rope.lua")
dofile(minetest.get_modpath("lib_tools").."/config.lua")
dofile(minetest.get_modpath("lib_tools").."/rubber.lua")
dofile(minetest.get_modpath("lib_tools").."/flashlight.lua")
dofile(minetest.get_modpath("lib_tools").."/sonic_screwdriver.lua")
dofile(minetest.get_modpath("lib_tools").."/tree_tap.lua")
minetest.register_craftitem("lib_tools:bowl", {
description = "Bowl",
inventory_image = "xdecor_bowl.png",
wield_image = "xdecor_bowl.png"
})
minetest.register_craftitem("lib_tools:bowl_soup", {
description = "Bowl of soup",
inventory_image = "xdecor_bowl_soup.png",
wield_image = "xdecor_bowl_soup.png",
groups = {not_in_creative_inventory=1},
stack_max = 1,
on_use = function(itemstack, user)
itemstack:replace("lib_tools:bowl 1")
if rawget(_G, "hunger") then
minetest.item_eat(20)
else
user:set_hp(20)
end
return itemstack
end
})
minetest.register_node("lib_tools:television", {
description = "Television",
light_source = 11,
groups = {snappy=3},
on_rotate = screwdriver.rotate_simple,
tiles = {
"xdecor_television_left.png^[transformR270",
"xdecor_television_left.png^[transformR90",
"xdecor_television_left.png^[transformFX",
"xdecor_television_left.png",
"xdecor_television_back.png",
{name="xdecor_television_front_animated.png",
animation = {type="vertical_frames", length=80.0}
}
}
})
minetest.register_craft({
output = "lib_tools:bowl 3",
recipe = {
{"group:wood", "", "group:wood"},
{"", "group:wood", ""}
}
})
minetest.register_craft({
output = "lib_tools:cauldron_empty",
recipe = {
{"default:iron_lump", "", "default:iron_lump"},
{"default:iron_lump", "", "default:iron_lump"},
{"default:iron_lump", "default:iron_lump", "default:iron_lump"}
}
})
minetest.register_craft({
output = "lib_tools:enchantment_table",
recipe = {
{"", "default:book", ""},
{"default:diamond", "default:obsidian", "default:diamond"},
{"default:obsidian", "default:obsidian", "default:obsidian"}
}
})
minetest.register_craft({
output = "lib_tools:lever_off",
recipe = {
{"group:stick"},
{"group:stone"}
}
})
minetest.register_craft({
output = "lib_tools:mailbox",
recipe = {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"dye:red", "default:paper", "dye:red"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}
}
})
minetest.register_craft({
output = "lib_tools:pressure_stone_off",
type = "shapeless",
recipe = {"group:stone", "group:stone"}
})
minetest.register_craft({
output = "lib_tools:pressure_wood_off",
type = "shapeless",
recipe = {"group:wood", "group:wood"}
})
minetest.register_craft({
output = "lib_tools:tv",
recipe = {
{"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:glass", "default:steel_ingot"},
{"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"}
}
})

45
intllib.lua Normal file
View File

@ -0,0 +1,45 @@
-- Fallback functions for when `intllib` is not installed.
-- Code released under Unlicense <http://unlicense.org>.
-- Get the latest version of this file at:
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
local function format(str, ...)
local args = { ... }
local function repl(escape, open, num, close)
if escape == "" then
local replacement = tostring(args[tonumber(num)])
if open == "" then
replacement = replacement..close
end
return replacement
else
return "@"..open..num..close
end
end
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
end
local gettext, ngettext
if minetest.get_modpath("intllib") then
if intllib.make_gettext_pair then
-- New method using gettext.
gettext, ngettext = intllib.make_gettext_pair()
else
-- Old method using text files.
gettext = intllib.Getter()
end
end
-- Fill in missing functions.
gettext = gettext or function(msgid, ...)
return format(msgid, ...)
end
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
return format(n==1 and msgid or msgid_plural, ...)
end
return gettext, ngettext

163
mailbox.lua Normal file
View File

@ -0,0 +1,163 @@
local mailbox = {}
screwdriver = screwdriver or {}
local function get_img(img)
local img_name = img:match("(.*)%.png")
if img_name then return img_name..".png" end
end
local function img_col(stack)
local def = minetest.registered_items[stack]
if not def then return "" end
if def.inventory_image ~= "" then
local img = get_img(def.inventory_image)
if img then return img end
end
if def.tiles then
local tile, img = def.tiles[1]
if type(tile) == "table" then
img = get_img(tile.name)
elseif type(tile) == "string" then
img = get_img(tile)
end
if img then return img end
end
return ""
end
function mailbox:formspec(pos, owner, is_owner)
local spos = pos.x..","..pos.y..","..pos.z
local meta = minetest.get_meta(pos)
local giver, img = "", ""
if is_owner then
for i = 1, 7 do
local giving = meta:get_string("giver"..i)
if giving ~= "" then
local stack = meta:get_string("stack"..i)
local giver_name = giving:sub(1,12)
local stack_name = stack:match("[%w_:]+")
local stack_count = stack:match("%s(%d+)") or 1
giver = giver.."#FFFF00,"..giver_name..","..i..
",#FFFFFF,x "..stack_count..","
img = img..i.."="..
img_col(stack_name).."^\\[resize:16x16,"
end
end
return [[ size[9.5,9]
label[0,0;Mailbox]
label[6,0;Last donators]
box[6,0.72;3.3,3.5;#555555]
listring[current_player;main]
list[current_player;main;0.75,5.25;8,4;]
tableoptions[background=#00000000;highlight=#00000000;border=false] ]]..
"tablecolumns[color;text;image,"..img.."0;color;text]"..
"table[6,0.75;3.3,4;givers;"..giver.."]"..
"list[nodemeta:"..spos..";mailbox;0,0.75;6,4;]"..
"listring[nodemeta:"..spos..";mailbox]"..
xbg..default.get_hotbar_bg(0.75,5.25)
end
return [[ size[8,5]
list[current_player;main;0,1.25;8,4;] ]]..
"label[0,0;Send your goods to\n"..
(minetest.colorize and
minetest.colorize("#FFFF00", owner) or owner).."]"..
"list[nodemeta:"..spos..";drop;3.5,0;1,1;]"..
xbg..default.get_hotbar_bg(0,1.25)
end
function mailbox.dig(pos, player)
local meta = minetest.get_meta(pos)
local owner = meta:get_string("owner")
local player_name = player and player:get_player_name()
local inv = meta:get_inventory()
return inv:is_empty("mailbox") and player_name == owner
end
function mailbox.after_place_node(pos, placer)
local meta = minetest.get_meta(pos)
local player_name = placer:get_player_name()
meta:set_string("owner", player_name)
meta:set_string("infotext", player_name.."'s Mailbox")
local inv = meta:get_inventory()
inv:set_size("mailbox", 6*4)
inv:set_size("drop", 1)
end
function mailbox.rightclick(pos, node, clicker, itemstack, pointed_thing)
local meta = minetest.get_meta(pos)
local player = clicker:get_player_name()
local owner = meta:get_string("owner")
minetest.show_formspec(player, "xdecor:mailbox", mailbox:formspec(pos,
owner, (player == owner)))
return itemstack
end
function mailbox.put(pos, listname, _, stack, player)
if listname == "drop" then
local inv = minetest.get_meta(pos):get_inventory()
if inv:room_for_item("mailbox", stack) then
return -1
else
minetest.chat_send_player(player:get_player_name(),
"The mailbox is full")
end
end
return 0
end
function mailbox.on_put(pos, listname, _, stack, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if listname == "drop" and inv:room_for_item("mailbox", stack) then
inv:set_list("drop", {})
inv:add_item("mailbox", stack)
for i = 7, 2, -1 do
meta:set_string("giver"..i, meta:get_string("giver"..(i-1)))
meta:set_string("stack"..i, meta:get_string("stack"..(i-1)))
end
meta:set_string("giver1", player:get_player_name())
meta:set_string("stack1", stack:to_string())
end
end
function mailbox.allow_take(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
if player:get_player_name() ~= meta:get_string("owner") then
return 0
end
return stack:get_count()
end
function mailbox.allow_move(pos)
return 0
end
lib_tools.register("mailbox", {
description = "Mailbox",
tiles = {"xdecor_mailbox_top.png", "xdecor_mailbox_bottom.png",
"xdecor_mailbox_side.png", "xdecor_mailbox_side.png",
"xdecor_mailbox.png", "xdecor_mailbox.png"},
groups = {cracky=3, oddly_breakable_by_hand=1},
on_rotate = screwdriver.rotate_simple,
can_dig = mailbox.dig,
on_rightclick = mailbox.rightclick,
allow_metadata_inventory_take = mailbox.allow_take,
allow_metadata_inventory_move = mailbox.allow_move,
on_metadata_inventory_put = mailbox.on_put,
allow_metadata_inventory_put = mailbox.put,
after_place_node = mailbox.after_place_node
})

117
mechanisms.lua Normal file
View File

@ -0,0 +1,117 @@
--[[ Thanks to sofar for helping with that code.
Recommended setting in minetest.conf (requires 0.4.14 or newer) :
nodetimer_interval = 0.1
]]
local plate = {}
screwdriver = screwdriver or {}
local function door_toggle(pos_actuator, pos_door, player)
local actuator = minetest.get_node(pos_actuator)
local door = lib_doors.get(pos_door)
if actuator.name:sub(-4) == "_off" then
minetest.set_node(pos_actuator,
{name=actuator.name:gsub("_off", "_on"), param2=actuator.param2})
end
door:open(player)
minetest.after(2, function()
if minetest.get_node(pos_actuator).name:sub(-3) == "_on" then
minetest.set_node(pos_actuator,
{name=actuator.name, param2=actuator.param2})
end
door:close(player)
end)
end
function plate.construct(pos)
local timer = minetest.get_node_timer(pos)
timer:start(0.1)
end
function plate.timer(pos)
local objs = minetest.get_objects_inside_radius(pos, 0.8)
if objs == {} or not doors.get then return true end
local minp = {x=pos.x-2, y=pos.y, z=pos.z-2}
local maxp = {x=pos.x+2, y=pos.y, z=pos.z+2}
local doors = minetest.find_nodes_in_area(minp, maxp, "group:lib_doors")
for _, player in pairs(objs) do
if player:is_player() then
for i = 1, #doors do
door_toggle(pos, doors[i], player)
end
break
end
end
return true
end
function plate.register(material, desc, def)
lib_tools.register("pressure_"..material.."_off", {
description = desc.." Pressure Plate",
tiles = {"lib_tools_pressure_"..material..".png"},
drawtype = "nodebox",
node_box = lib_tools.pixelbox(16, {{1, 0, 1, 14, 1, 14}}),
groups = def.groups,
sounds = def.sounds,
sunlight_propagates = true,
on_rotate = screwdriver.rotate_simple,
on_construct = plate.construct,
on_timer = plate.timer
})
lib_tools.register("pressure_"..material.."_on", {
tiles = {"lib_tools_pressure_"..material..".png"},
drawtype = "nodebox",
node_box = lib_tools.pixelbox(16, {{1, 0, 1, 14, 0.4, 14}}),
groups = def.groups,
sounds = def.sounds,
drop = "lib_tools:pressure_"..material.."_off",
sunlight_propagates = true,
on_rotate = screwdriver.rotate_simple
})
end
plate.register("wood", "Wooden", {
sounds = default.node_sound_wood_defaults(),
groups = {choppy=3, oddly_breakable_by_hand=2, flammable=2}
})
plate.register("stone", "Stone", {
sounds = default.node_sound_stone_defaults(),
groups = {cracky=3, oddly_breakable_by_hand=2}
})
lib_tools.register("lever_off", {
description = "Lever",
tiles = {"lib_tools_lever_off.png"},
drawtype = "nodebox",
node_box = lib_tools.pixelbox(16, {{2, 1, 15, 12, 14, 1}}),
groups = {cracky=3, oddly_breakable_by_hand=2},
sounds = default.node_sound_stone_defaults(),
sunlight_propagates = true,
on_rotate = screwdriver.rotate_simple,
on_rightclick = function(pos, node, clicker)
if not doors.get then return end
local minp = {x=pos.x-2, y=pos.y-1, z=pos.z-2}
local maxp = {x=pos.x+2, y=pos.y+1, z=pos.z+2}
local doors = minetest.find_nodes_in_area(minp, maxp, "group:lib_doors")
for i = 1, #doors do
door_toggle(pos, doors[i], clicker)
end
end
})
lib_tools.register("lever_on", {
tiles = {"lib_tools_lever_on.png"},
drawtype = "nodebox",
node_box = lib_tools.pixelbox(16, {{2, 1, 15, 12, 14, 1}}),
groups = {cracky=3, oddly_breakable_by_hand=2, not_in_creative_inventory=1},
sounds = default.node_sound_stone_defaults(),
sunlight_propagates = true,
on_rotate = screwdriver.rotate_simple,
drop = "lib_tools:lever_off"
})

950
nodes_straw.lua Normal file
View File

@ -0,0 +1,950 @@
---------------------------------------------------------------------------------------
-- straw - a very basic material
---------------------------------------------------------------------------------------
-- * straw mat - for animals and very poor NPC; also basis for other straw things
-- * straw bale - well, just a good source for building and decoration
local S = lib_tools.S
-- used for: anvil, hammer, barrel, steel hatch, stove pipe, wagon wheel, handmill.
lib_tools.craftitem_steel = "default:steel_ingot";
-- used for: hammer, wood+steel hatch, fence gate, bed, table, bench, shelf,
-- washing place, wagon wheel, glass pane, flat wood, handmill,
-- operating the treshing floor.
lib_tools.craftitem_stick = "group:stick";
-- used for: treshing floor, handmill, slate roof, vertical slate
lib_tools.craftitem_stone = "default:stone";
-- the treshing floor produces wheat seeds
-- used for: treshing floor
lib_tools.craftitem_junglewood = "default:junglewood";
lib_tools.craftitem_chest_locked = "default:chest_locked";
lib_tools.craftitem_seed_wheat = "farming:seed_wheat";
lib_tools.texture_wheat_seed = "farming_wheat_seed.png";
lib_tools.texture_stick = "default_stick.png";
-- texture used for fence gate and bed posts
lib_tools.texture_furniture = "default_wood.png";
-- add to this table what you want the handmill to convert;
-- add a stack size if you want a higher yield
lib_tools.handmill_product = {};
lib_tools.handmill_product[ lib_tools.craftitem_seed_wheat ] = 'farming:flour 1';
--[[ some examples:
cottages.handmill_product[ 'default:cobble' ] = 'default:gravel';
cottages.handmill_product[ 'default:gravel' ] = 'default:sand';
cottages.handmill_product[ 'default:sand' ] = 'default:dirt 2';
cottages.handmill_product[ 'flowers:rose' ] = 'dye:red 6';
cottages.handmill_product[ 'default:cactus' ] = 'dye:green 6';
cottages.handmill_product[ 'default:coal_lump'] = 'dye:black 6';
--]]
-- process that many inputs per turn
lib_tools.handmill_max_per_turn = 20;
lib_tools.handmill_min_per_turn = 0;
-- a bed without functionality - just decoration
minetest.register_node("lib_tools:bed_foot", {
description = S("Bed (foot region)"),
drawtype = "nodebox",
tiles = {"cottages_beds_bed_top_bottom.png", lib_tools.texture_furniture, "cottages_beds_bed_side.png", "cottages_beds_bed_side.png", "cottages_beds_bed_side.png", "cottages_beds_bed_side.png"},
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
sounds = default.node_sound_wood_defaults(),
node_box = {
type = "fixed",
fixed = {
-- bed
{-0.5, 0.0, -0.5, 0.5, 0.3, 0.5},
-- stützen
{-0.5, -0.5, -0.5, -0.4, 0.5, -0.4},
{ 0.4,-0.5, -0.5, 0.5, 0.5, -0.4},
-- Querstrebe
{-0.4, 0.3, -0.5, 0.4, 0.5, -0.4}
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.3, 0.5},
}
},
is_ground_content = false,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
return lib_tools.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing );
end
})
-- the bed is split up in two parts to avoid destruction of blocks on placement
minetest.register_node("lib_tools:bed_head", {
description = S("Bed (head region)"),
drawtype = "nodebox",
tiles = {"cottages_beds_bed_top_top.png", lib_tools.texture_furniture, "cottages_beds_bed_side_top_r.png", "cottages_beds_bed_side_top_l.png", lib_tools.texture_furniture, "cottages_beds_bed_side.png"},
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
sounds = default.node_sound_wood_defaults(),
node_box = {
type = "fixed",
fixed = {
-- bed
{-0.5, 0.0, -0.5, 0.5, 0.3, 0.5},
-- stützen
{-0.5,-0.5, 0.4, -0.4, 0.5, 0.5},
{ 0.4,-0.5, 0.4, 0.5, 0.5, 0.5},
-- Querstrebe
{-0.4, 0.3, 0.4, 0.4, 0.5, 0.5}
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 0.3, 0.5},
}
},
is_ground_content = false,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
return lib_tools.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing );
end
})
-- the basic version of a bed - a sleeping mat
-- to facilitate upgrade path straw mat -> sleeping mat -> bed, this uses a nodebox
minetest.register_node("lib_tools:sleeping_mat", {
description = S("sleeping mat"),
drawtype = 'nodebox',
tiles = { 'cottages_sleepingmat.png' }, -- done by VanessaE
wield_image = 'cottages_sleepingmat.png',
inventory_image = 'cottages_sleepingmat.png',
sunlight_propagates = true,
paramtype = 'light',
paramtype2 = "facedir",
walkable = false,
groups = { snappy = 3 },
sounds = default.node_sound_leaves_defaults(),
selection_box = {
type = "wallmounted",
},
node_box = {
type = "fixed",
fixed = {
{-0.48, -0.5,-0.48, 0.48, -0.45, 0.48},
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.48, -0.5,-0.48, 0.48, -0.25, 0.48},
}
},
is_ground_content = false,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
return lib_tools.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing );
end
})
-- furniture; possible replacement: 3dforniture:chair
minetest.register_node("lib_tools:bench", {
drawtype = "nodebox",
description = S("simple wooden bench"),
tiles = {"cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png", "cottages_minimal_wood.png"},
paramtype = "light",
paramtype2 = "facedir",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
sounds = default.node_sound_wood_defaults(),
node_box = {
type = "fixed",
fixed = {
-- sitting area
{-0.5, -0.15, 0.1, 0.5, -0.05, 0.5},
-- stützen
{-0.4, -0.5, 0.2, -0.3, -0.15, 0.4},
{ 0.3, -0.5, 0.2, 0.4, -0.15, 0.4},
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, 0, 0.5, 0, 0.5},
}
},
is_ground_content = false,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
return lib_tools.sit_on_bench( pos, node, clicker, itemstack, pointed_thing );
end,
})
local cottages_can_use = function( meta, player )
if( not( player) or not( meta )) then
return false;
end
local pname = player:get_player_name();
local owner = meta:get_string('owner' );
if( not(owner) or owner=="" or owner==pname ) then
return true;
end
return false;
end
lib_tools.allow_sit = function( player )
-- no check possible
if( not( player.get_player_velocity )) then
return true;
end
local velo = player:get_player_velocity();
if( not( velo )) then
return false;
end
local max_velo = 0.0001;
if( math.abs(velo.x) < max_velo
and math.abs(velo.y) < max_velo
and math.abs(velo.z) < max_velo ) then
return true;
end
return false;
end
lib_tools.sit_on_bench = function( pos, node, clicker, itemstack, pointed_thing )
if( not( clicker ) or not( default.player_get_animation ) or not( cottages.allow_sit( clicker ))) then
return;
end
local animation = default.player_get_animation( clicker );
local pname = clicker:get_player_name();
if( animation and animation.animation=="sit") then
default.player_attached[pname] = false
clicker:setpos({x=pos.x,y=pos.y-0.5,z=pos.z})
clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
clicker:set_physics_override(1, 1, 1)
default.player_set_animation(clicker, "stand", 30)
else
-- the bench is not centered; prevent the player from sitting on air
local p2 = {x=pos.x, y=pos.y, z=pos.z};
if not( node ) or node.param2 == 0 then
p2.z = p2.z+0.3;
elseif node.param2 == 1 then
p2.x = p2.x+0.3;
elseif node.param2 == 2 then
p2.z = p2.z-0.3;
elseif node.param2 == 3 then
p2.x = p2.x-0.3;
end
clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
clicker:setpos( p2 )
default.player_set_animation(clicker, "sit", 30)
clicker:set_physics_override(0, 0, 0)
default.player_attached[pname] = true
end
end
lib_tools.sleep_in_bed = function( pos, node, clicker, itemstack, pointed_thing )
if( not( clicker ) or not( node ) or not( node.name ) or not( pos ) or not( lib_tools.allow_sit( clicker))) then
return;
end
local animation = default.player_get_animation( clicker );
local pname = clicker:get_player_name();
local place_name = 'place';
-- if only one node is present, the player can only sit;
-- sleeping requires a bed head+foot or two sleeping mats
local allow_sleep = false;
local new_animation = 'sit';
-- let players get back up
if( animation and animation.animation=="lay" ) then
default.player_attached[pname] = false
clicker:setpos({x=pos.x,y=pos.y-0.5,z=pos.z})
clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
clicker:set_physics_override(1, 1, 1)
default.player_set_animation(clicker, "stand", 30)
minetest.chat_send_player( pname, 'That was enough sleep for now. You stand up again.');
return;
end
local second_node_pos = {x=pos.x, y=pos.y, z=pos.z};
-- the node that will contain the head of the player
local p = {x=pos.x, y=pos.y, z=pos.z};
-- the player's head is pointing in this direction
local dir = node.param2;
-- it would be odd to sleep in half a bed
if( node.name=='lib_tools:bed_head' ) then
if( node.param2==0 ) then
second_node_pos.z = pos.z-1;
elseif( node.param2==1) then
second_node_pos.x = pos.x-1;
elseif( node.param2==2) then
second_node_pos.z = pos.z+1;
elseif( node.param2==3) then
second_node_pos.x = pos.x+1;
end
local node2 = minetest.get_node( second_node_pos );
if( not( node2 ) or not( node2.param2 ) or not( node.param2 )
or node2.name ~= 'lib_tools:bed_foot'
or node2.param2 ~= node.param2 ) then
allow_sleep = false;
else
allow_sleep = true;
end
place_name = 'bed';
-- if the player clicked on the foot of the bed, locate the head
elseif( node.name=='lib_tools:bed_foot' ) then
if( node.param2==2 ) then
second_node_pos.z = pos.z-1;
elseif( node.param2==3) then
second_node_pos.x = pos.x-1;
elseif( node.param2==0) then
second_node_pos.z = pos.z+1;
elseif( node.param2==1) then
second_node_pos.x = pos.x+1;
end
local node2 = minetest.get_node( second_node_pos );
if( not( node2 ) or not( node2.param2 ) or not( node.param2 )
or node2.name ~= 'lib_tools:bed_head'
or node2.param2 ~= node.param2 ) then
allow_sleep = false;
else
allow_sleep = true;
end
if( allow_sleep==true ) then
p = {x=second_node_pos.x, y=second_node_pos.y, z=second_node_pos.z};
end
place_name = 'bed';
elseif( node.name=='lib_tools:sleeping_mat' or node.name=='lib_tools:straw_mat') then
place_name = 'mat';
dir = node.param2;
allow_sleep = false;
-- search for a second mat right next to this one
local offset = {{x=0,z=-1}, {x=-1,z=0}, {x=0,z=1}, {x=1,z=0}};
for i,off in ipairs( offset ) do
node2 = minetest.get_node( {x=pos.x+off.x, y=pos.y, z=pos.z+off.z} );
if( node2.name == 'lib_tools:sleeping_mat' or node2.name=='lib_tools:straw_mat' ) then
-- if a second mat is found, sleeping is possible
allow_sleep = true;
dir = i-1;
end
end
end
-- set the right height for the bed
if( place_name=='bed' ) then
p.y = p.y+0.4;
end
if( allow_sleep==true ) then
-- set the right position (middle of the bed)
if( dir==0 ) then
p.z = p.z-0.5;
elseif( dir==1 ) then
p.x = p.x-0.5;
elseif( dir==2 ) then
p.z = p.z+0.5;
elseif( dir==3 ) then
p.x = p.x+0.5;
end
end
if( default.player_attached[pname] and animation.animation=="sit") then
-- just changing the animation...
if( allow_sleep==true ) then
default.player_set_animation(clicker, "lay", 30)
clicker:set_eye_offset({x=0,y=-14,z=2}, {x=0,y=0,z=0})
minetest.chat_send_player( pname, 'You lie down and take a nap. A right-click will wake you up.');
return;
-- no sleeping on this place
else
default.player_attached[pname] = false
clicker:setpos({x=pos.x,y=pos.y-0.5,z=pos.z})
clicker:set_eye_offset({x=0,y=0,z=0}, {x=0,y=0,z=0})
clicker:set_physics_override(1, 1, 1)
default.player_set_animation(clicker, "stand", 30)
minetest.chat_send_player( pname, 'That was enough sitting around for now. You stand up again.');
return;
end
end
clicker:set_eye_offset({x=0,y=-7,z=2}, {x=0,y=0,z=0})
clicker:setpos( p );
default.player_set_animation(clicker, new_animation, 30)
clicker:set_physics_override(0, 0, 0)
default.player_attached[pname] = true
if( allow_sleep==true) then
minetest.chat_send_player( pname, 'Aaah! What a comftable '..place_name..'. A second right-click will let you sleep.');
else
minetest.chat_send_player( pname, 'Comftable, but not good enough for a nap. Right-click again if you want to get back up.');
end
end
-- an even simpler from of bed - usually for animals
-- it is a nodebox and not wallmounted because that makes it easier to replace beds with straw mats
minetest.register_node("lib_tools:straw_mat", {
description = S("layer of straw"),
drawtype = 'nodebox',
tiles = { 'cottages_darkage_straw.png' }, -- done by VanessaE
wield_image = 'cottages_darkage_straw.png',
inventory_image = 'cottages_darkage_straw.png',
sunlight_propagates = true,
paramtype = 'light',
paramtype2 = "facedir",
walkable = false,
groups = { snappy = 3 },
sounds = default.node_sound_leaves_defaults(),
node_box = {
type = "fixed",
fixed = {
{-0.48, -0.5,-0.48, 0.48, -0.45, 0.48},
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.48, -0.5,-0.48, 0.48, -0.25, 0.48},
}
},
is_ground_content = false,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
return lib_tools.sleep_in_bed( pos, node, clicker, itemstack, pointed_thing );
end
})
-- straw bales are a must for farming environments; if you for some reason do not have the darkage mod installed, this here gets you a straw bale
minetest.register_node("lib_tools:straw_bale", {
drawtype = "nodebox",
description = S("straw bale"),
tiles = {"cottages_darkage_straw_bale.png"},
paramtype = "light",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=3},
sounds = default.node_sound_wood_defaults(),
-- the bale is slightly smaller than a full node
node_box = {
type = "fixed",
fixed = {
{-0.45, -0.5,-0.45, 0.45, 0.45, 0.45},
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.45, -0.5,-0.45, 0.45, 0.45, 0.45},
}
},
is_ground_content = false,
})
-- just straw
minetest.register_node("lib_tools:straw", {
drawtype = "normal",
description = S("straw"),
tiles = {"cottages_darkage_straw.png"},
groups = {snappy=3,choppy=3,oddly_breakable_by_hand=3,flammable=3},
sounds = default.node_sound_wood_defaults(),
-- the bale is slightly smaller than a full node
is_ground_content = false,
})
local cottages_formspec_treshing_floor =
"size[8,8]"..
"image[1.5,0;1,1;"..lib_tools.texture_stick.."]"..
"image[0,1;1,1;farming_wheat.png]"..
"list[current_name;harvest;1,1;2,1;]"..
"list[current_name;straw;5,0;2,2;]"..
"list[current_name;seeds;5,2;2,2;]"..
"label[1,0.5;"..S("Harvested wheat:").."]"..
"label[4,0.0;"..S("Straw:").."]"..
"label[4,2.0;"..S("Seeds:").."]"..
"label[0,-0.5;"..S("Threshing floor").."]"..
"label[0,2.5;"..S("Punch threshing floor with a stick").."]"..
"label[0,3.0;"..S("to get straw and seeds from wheat.").."]"..
"list[current_player;main;0,4;8,4;]";
minetest.register_node("lib_tools:threshing_floor", {
drawtype = "nodebox",
description = S("threshing floor"),
-- TODO: stone also looks pretty well for this
tiles = {"cottages_junglewood.png^farming_wheat.png","cottages_junglewood.png","cottages_junglewood.png^"..lib_tools.texture_stick},
paramtype = "light",
paramtype2 = "facedir",
groups = {cracky=2},
is_ground_content = false,
node_box = {
type = "fixed",
fixed = {
{-0.50, -0.5,-0.50, 0.50, -0.40, 0.50},
{-0.50, -0.4,-0.50,-0.45, -0.20, 0.50},
{ 0.45, -0.4,-0.50, 0.50, -0.20, 0.50},
{-0.45, -0.4,-0.50, 0.45, -0.20,-0.45},
{-0.45, -0.4, 0.45, 0.45, -0.20, 0.50},
}
},
selection_box = {
type = "fixed",
fixed = {
{-0.50, -0.5,-0.50, 0.50, -0.20, 0.50},
}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", S("Threshing floor"));
local inv = meta:get_inventory();
inv:set_size("harvest", 2);
inv:set_size("straw", 4);
inv:set_size("seeds", 4);
meta:set_string("formspec", cottages_formspec_treshing_floor );
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos);
meta:set_string("owner", placer:get_player_name() or "");
meta:set_string("infotext", S("Threshing floor (owned by %s)"):format(meta:get_string("owner") or ""));
meta:set_string("formspec",
cottages_formspec_treshing_floor..
"label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string("owner") or "").."]" );
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
local owner = meta:get_string('owner');
if( not( inv:is_empty("harvest"))
or not( inv:is_empty("straw"))
or not( inv:is_empty("seeds"))
or not( player )
or ( owner and owner ~= '' and player:get_player_name() ~= owner )) then
return false;
end
return true;
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
if( not( cottages_can_use( meta, player ))) then
return 0
end
return count;
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
-- only accept input the threshing floor can use/process
if( listname=='straw'
or listname=='seeds'
or (listname=='harvest' and stack and stack:get_name() ~= 'farming:wheat' )) then
return 0;
end
if( not( cottages_can_use( meta, player ))) then
return 0
end
return stack:get_count()
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
if( not( cottages_can_use( meta, player ))) then
return 0
end
return stack:get_count()
end,
on_punch = function(pos, node, puncher)
if( not( pos ) or not( node ) or not( puncher )) then
return;
end
-- only punching with a normal stick is supposed to work
local wielded = puncher:get_wielded_item();
if( not( wielded )
or not( wielded:get_name() )
or not( minetest.registered_items[ wielded:get_name() ])
or not( minetest.registered_items[ wielded:get_name() ].groups )
or not( minetest.registered_items[ wielded:get_name() ].groups.stick )) then
return;
end
local name = puncher:get_player_name();
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
local input = inv:get_list('harvest');
-- we have two input slots
local stack1 = inv:get_stack( 'harvest', 1);
local stack2 = inv:get_stack( 'harvest', 2);
if( ( stack1:is_empty() and stack2:is_empty())
or( not( stack1:is_empty()) and stack1:get_name() ~= 'farming:wheat')
or( not( stack2:is_empty()) and stack2:get_name() ~= 'farming:wheat')) then
-- minetest.chat_send_player( name, 'One of the input slots contains something else than wheat, or there is no wheat at all.');
-- update the formspec
meta:set_string("formspec",
cottages_formspec_treshing_floor..
"label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string("owner") or "").."]" );
return;
end
-- on average, process 25 wheat at each punch (10..40 are possible)
local anz_wheat = 10 + math.random( 0, 30 );
-- we already made sure there is only wheat inside
local found_wheat = stack1:get_count() + stack2:get_count();
-- do not process more wheat than present in the input slots
if( found_wheat < anz_wheat ) then
anz_wheat = found_wheat;
end
local overlay1 = "^farming_wheat.png";
local overlay2 = "^cottages_darkage_straw.png";
local overlay3 = "^"..lib_tools.texture_wheat_seed;
-- this can be enlarged by a multiplicator if desired
local anz_straw = anz_wheat;
local anz_seeds = anz_wheat;
if( inv:room_for_item('straw','lib_tools:straw_mat '..tostring( anz_straw ))
and inv:room_for_item('seeds',lib_tools.craftitem_seed_wheat..' '..tostring( anz_seeds ))) then
-- the player gets two kind of output
inv:add_item("straw",'lib_tools:straw_mat '..tostring( anz_straw ));
inv:add_item("seeds",lib_tools.craftitem_seed_wheat..' '..tostring( anz_seeds ));
-- consume the wheat
inv:remove_item("harvest", 'farming:wheat '..tostring( anz_wheat ));
local anz_left = found_wheat - anz_wheat;
if( anz_left > 0 ) then
-- minetest.chat_send_player( name, S('You have threshed %s wheat (%s are left).'):format(anz_wheat,anz_left));
else
-- minetest.chat_send_player( name, S('You have threshed the last %s wheat.'):format(anz_wheat));
overlay1 = "";
end
end
local hud0 = puncher:hud_add({
hud_elem_type = "image",
scale = {x = 38, y = 38},
text = "cottages_junglewood.png^[colorize:#888888:128",
position = {x = 0.5, y = 0.5},
alignment = {x = 0, y = 0}
});
local hud1 = puncher:hud_add({
hud_elem_type = "image",
scale = {x = 15, y = 15},
text = "cottages_junglewood.png"..overlay1,
position = {x = 0.4, y = 0.5},
alignment = {x = 0, y = 0}
});
local hud2 = puncher:hud_add({
hud_elem_type = "image",
scale = {x = 15, y = 15},
text = "cottages_junglewood.png"..overlay2,
position = {x = 0.6, y = 0.35},
alignment = {x = 0, y = 0}
});
local hud3 = puncher:hud_add({
hud_elem_type = "image",
scale = {x = 15, y = 15},
text = "cottages_junglewood.png"..overlay3,
position = {x = 0.6, y = 0.65},
alignment = {x = 0, y = 0}
});
local hud4 = puncher:hud_add({
hud_elem_type = "text",
text = tostring( found_wheat-anz_wheat ),
number = 0x00CC00,
alignment = {x = 0, y = 0},
scale = {x = 100, y = 100}, -- bounding rectangle of the text
position = {x = 0.4, y = 0.5},
});
if( not( anz_straw )) then
anz_straw = "0";
end
if( not( anz_seed )) then
anz_seed = "0";
end
local hud5 = puncher:hud_add({
hud_elem_type = "text",
text = '+ '..tostring( anz_straw )..' straw',
number = 0x00CC00,
alignment = {x = 0, y = 0},
scale = {x = 100, y = 100}, -- bounding rectangle of the text
position = {x = 0.6, y = 0.35},
});
local hud6 = puncher:hud_add({
hud_elem_type = "text",
text = '+ '..tostring( anz_seed )..' seeds',
number = 0x00CC00,
alignment = {x = 0, y = 0},
scale = {x = 100, y = 100}, -- bounding rectangle of the text
position = {x = 0.6, y = 0.65},
});
minetest.after(2, function()
if( puncher ) then
puncher:hud_remove(hud1);
puncher:hud_remove(hud2);
puncher:hud_remove(hud3);
puncher:hud_remove(hud4);
puncher:hud_remove(hud5);
puncher:hud_remove(hud6);
puncher:hud_remove(hud0);
end
end)
end,
})
local cottages_handmill_formspec = "size[8,8]"..
"image[0,1;1,1;"..lib_tools.texture_wheat_seed.."]"..
"list[current_name;seeds;1,1;1,1;]"..
"list[current_name;flour;5,1;2,2;]"..
"label[0,0.5;"..S("Wheat seeds:").."]"..
"label[4,0.5;"..S("Flour:").."]"..
"label[0,-0.3;"..S("Mill").."]"..
"label[0,2.5;"..S("Punch this hand-driven mill").."]"..
"label[0,3.0;"..S("to convert wheat seeds into flour.").."]"..
"list[current_player;main;0,4;8,4;]";
minetest.register_node("lib_tools:handmill", {
description = S("mill, powered by punching"),
drawtype = "mesh",
mesh = "cottages_handmill.obj",
tiles = {"cottages_stone.png"},
paramtype = "light",
paramtype2 = "facedir",
groups = {cracky=2},
is_ground_content = false,
selection_box = {
type = "fixed",
fixed = {
{-0.50, -0.5,-0.50, 0.50, 0.25, 0.50},
}
},
collision_box = {
type = "fixed",
fixed = {
{-0.50, -0.5,-0.50, 0.50, 0.25, 0.50},
}
},
on_construct = function(pos)
local meta = minetest.get_meta(pos);
meta:set_string("infotext", S("Mill, powered by punching"));
local inv = meta:get_inventory();
inv:set_size("seeds", 1);
inv:set_size("flour", 4);
meta:set_string("formspec", cottages_handmill_formspec );
end,
after_place_node = function(pos, placer)
local meta = minetest.get_meta(pos);
meta:set_string("owner", placer:get_player_name() or "");
meta:set_string("infotext", S("Mill, powered by punching (owned by %s)"):format(meta:get_string("owner") or ""));
meta:set_string("formspec",
cottages_handmill_formspec..
"label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string('owner') or "").."]" );
end,
can_dig = function(pos,player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
local owner = meta:get_string('owner');
if( not( inv:is_empty("flour"))
or not( inv:is_empty("seeds"))
or not( player )
or ( owner and owner ~= '' and player:get_player_name() ~= owner )) then
return false;
end
return true;
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
if( not( cottages_can_use( meta, player ))) then
return 0
end
return count;
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
-- only accept input the threshing floor can use/process
if( listname=='flour'
or (listname=='seeds' and stack and not( lib_tools.handmill_product[ stack:get_name()] ))) then
return 0;
end
if( not( cottages_can_use( meta, player ))) then
return 0
end
return stack:get_count()
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
if( not( cottages_can_use( meta, player ))) then
return 0
end
return stack:get_count()
end,
-- this code is very similar to the threshing floor; except that it has only one input- and output-slot
-- and does not require the usage of a stick
on_punch = function(pos, node, puncher)
if( not( pos ) or not( node ) or not( puncher )) then
return;
end
local name = puncher:get_player_name();
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
local input = inv:get_list('seeds');
local stack1 = inv:get_stack( 'seeds', 1);
if( ( stack1:is_empty())
or( not( stack1:is_empty())
and not( lib_tools.handmill_product[ stack1:get_name() ] ))) then
if not( stack1:is_empty() ) then
minetest.chat_send_player(name,"Nothing happens...")
end
-- update the formspec
meta:set_string("formspec",
cottages_handmill_formspec..
"label[2.5,-0.5;"..S("Owner: %s"):format(meta:get_string('owner') or "").."]" );
return;
end
-- turning the mill is a slow process; 1-21 flour are generated per turn
local anz = 1 + math.random( lib_tools.handmill_min_per_turn, lib_tools.handmill_max_per_turn );
-- we already made sure there is only wheat inside
local found = stack1:get_count();
-- do not process more wheat than present in the input slots
if( found < anz ) then
anz = found;
end
local product_stack = ItemStack( lib_tools.handmill_product[ stack1:get_name() ]);
local anz_result = anz;
-- items that produce more
if( product_stack:get_count()> 1 ) then
anz_result = anz * product_stack:get_count();
end
if( inv:room_for_item('flour', product_stack:get_name()..' '..tostring( anz_result ))) then
inv:add_item( 'flour', product_stack:get_name()..' '..tostring( anz_result ));
inv:remove_item( 'seeds', stack1:get_name()..' '..tostring( anz ));
local anz_left = found - anz;
if( anz_left > 0 ) then
minetest.chat_send_player( name, S('You have ground a %s (%s are left).'):format(stack1:get_definition().description,(anz_left)));
else
minetest.chat_send_player( name, S('You have ground the last %s.'):format(stack1:get_definition().description));
end
-- if the version of MT is recent enough, rotate the mill a bit
if( minetest.swap_node ) then
node.param2 = node.param2 + 1;
if( node.param2 > 3 ) then
node.param2 = 0;
end
minetest.swap_node( pos, node );
end
end
end,
})
---------------------------------------------------------------------------------------
-- crafting receipes
---------------------------------------------------------------------------------------
-- this returns corn as well
-- the replacements work only if the replaced slot gets empty...
minetest.register_craft({
output = "lib_tools:straw_mat 6",
recipe = {
{lib_tools.craftitem_stone,'',''},
{"farming:wheat", "farming:wheat", "farming:wheat", },
},
replacements = {{ lib_tools.craftitem_stone, lib_tools.craftitem_seed_wheat.." 3" }},
})
-- this is a better way to get straw mats
minetest.register_craft({
output = "lib_tools:threshing_floor",
recipe = {
{lib_tools.craftitem_junglewood, lib_tools.craftitem_chest_locked, lib_tools.craftitem_junglewood, },
{lib_tools.craftitem_junglewood, lib_tools.craftitem_stone, lib_tools.craftitem_junglewood, },
},
})
-- and a way to turn wheat seeds into flour
minetest.register_craft({
output = "lib_tools:handmill",
recipe = {
{lib_tools.craftitem_stick, lib_tools.craftitem_stone, "", },
{"", lib_tools.craftitem_steel, "", },
{"", lib_tools.craftitem_stone, "", },
},
})
minetest.register_craft({
output = "lib_tools:straw_bale",
recipe = {
{"lib_tools:straw_mat"},
{"lib_tools:straw_mat"},
{"lib_tools:straw_mat"},
},
})
minetest.register_craft({
output = "lib_tools:straw",
recipe = {
{"lib_tools:straw_bale"},
},
})
minetest.register_craft({
output = "lib_tools:straw_bale",
recipe = {
{"lib_tools:straw"},
},
})
minetest.register_craft({
output = "lib_tools:straw_mat 3",
recipe = {
{"lib_tools:straw_bale"},
},
})

84
registration.lua Normal file
View File

@ -0,0 +1,84 @@
xbg = default.gui_bg..default.gui_bg_img..default.gui_slots
local default_inventory_size = 32
local default_inventory_formspecs = {
["8"] = [[ size[8,6]
list[context;main;0,0;8,1;]
list[current_player;main;0,2;8,4;]
listring[current_player;main]
listring[context;main] ]]
..default.get_hotbar_bg(0,2),
["16"] = [[ size[8,7]
list[context;main;0,0;8,2;]
list[current_player;main;0,3;8,4;]
listring[current_player;main]
listring[context;main] ]]
..default.get_hotbar_bg(0,3),
["24"] = [[ size[8,8]
list[context;main;0,0;8,3;]
list[current_player;main;0,4;8,4;]
listring[current_player;main]
listring[context;main]" ]]
..default.get_hotbar_bg(0,4),
["32"] = [[ size[8,9]
list[context;main;0,0.3;8,4;]
list[current_player;main;0,4.85;8,1;]
list[current_player;main;0,6.08;8,3;8]
listring[current_player;main]
listring[context;main] ]]
..default.get_hotbar_bg(0,4.85)
}
local function get_formspec_by_size(size)
local formspec = default_inventory_formspecs[tostring(size)]
return formspec or default_inventory_formspecs
end
local default_can_dig = function(pos)
local inv = minetest.get_meta(pos):get_inventory()
return inv:is_empty("main")
end
function lib_tools.register(name, def)
def.drawtype = def.drawtype or (def.node_box and "nodebox")
def.paramtype = def.paramtype or "light"
def.sounds = def.sounds or default.node_sound_defaults()
if not (def.drawtype == "normal" or def.drawtype == "signlike" or
def.drawtype == "plantlike" or def.drawtype == "glasslike_framed" or
def.drawtype == "glasslike_framed_optional") then
def.paramtype2 = def.paramtype2 or "facedir"
end
if def.drawtype == "plantlike" or def.drawtype == "torchlike" or
def.drawtype == "signlike" or def.drawtype == "fencelike" then
def.sunlight_propagates = true
end
local infotext = def.infotext
local inventory = def.inventory
def.inventory = nil
if inventory then
def.on_construct = def.on_construct or function(pos)
local meta = minetest.get_meta(pos)
if infotext then meta:set_string("infotext", infotext) end
local size = inventory.size or default_inventory_size
local inv = meta:get_inventory()
inv:set_size("main", size)
meta:set_string("formspec", (inventory.formspec or get_formspec_by_size(size))..xbg)
end
def.can_dig = def.can_dig or default_can_dig
elseif infotext and not def.on_construct then
def.on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", infotext)
end
end
minetest.register_node("lib_tools:"..name, def)
end

226
rope.lua Normal file
View File

@ -0,0 +1,226 @@
--local rope = {}
-- Code by Mirko K. (modified by Temperest, Wulfsdad and kilbith) (License: GPL).
minetest.register_on_punchnode(function(pos, oldnode, digger)
if oldnode.name == "lib_tools:rope" then
lib_tools.rope_remove(pos, oldnode, digger, "lib_tools:rope")
end
end)
function lib_tools.rope_place(itemstack, placer, pointed_thing)
if pointed_thing.type == "node" then
local under = pointed_thing.under
local above = pointed_thing.above
local pos = above
local oldnode = minetest.get_node(pos)
local stackname = itemstack:get_name()
if minetest.is_protected(pos, placer:get_player_name()) then return end
while oldnode.name == "air" and not itemstack:is_empty() do
local newnode = {name = stackname, param1 = 0}
minetest.set_node(pos, newnode)
itemstack:take_item()
pos.y = pos.y - 1
oldnode = minetest.get_node(pos)
end
end
return itemstack
end
function lib_tools.rope_remove(pos, oldnode, digger, rope_name)
local num = 0
local below = {x=pos.x, y=pos.y, z=pos.z}
local digger_inv = digger:get_inventory()
while minetest.get_node(below).name == rope_name do
minetest.remove_node(below)
below.y = below.y - 1
num = num + 1
end
if num == 0 then return end
digger_inv:add_item("main", rope_name.." "..num)
return true
end
lib_tools.register("rope", {
description = "Rope",
drawtype = "nodebox",
tiles = {"castle_ropes.png"},
paramtype = "light",
walkable = false,
climbable = true,
groups = {dig_immediate=3, choppy=3,snappy=3,oddly_breakable_by_hand=3,flammable=3},
-- tiles = {"lib_tools_rope.png"},
-- inventory_image = "lib_tools_rope_inv.png",
-- wield_image = "lib_tools_rope_inv.png",
-- selection_box = lib_tools.pixelbox(8, {{3, 0, 3, 2, 8, 2}}),
node_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
selection_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
on_place = lib_tools.rope_place
})
minetest.register_node("lib_tools:rope_1m",{
description = "Rope (1 meter length)",
drawtype = "nodebox",
sunlight_propagates = true,
tiles = {"castle_ropes.png"},
groups = {choppy=3,snappy=3,oddly_breakable_by_hand=3,flammable=1},
paramtype = "light",
climbable = true,
walkable = false,
node_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
selection_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
})
minetest.register_craft({
output = "lib_tools:rope_1m",
recipe = {
{"farming:string"},
{"farming:string"},
{"farming:string"},
}
})
minetest.register_node("lib_tools:box_rope", {
description = "Rope from Ropebox",
drawtype = "nodebox",
paramtype = "light",
sunlight_propagates = true,
tiles = {"castle_ropes.png"},
groups = {not_in_creative_inventory=1},
climbable = true,
walkable = false,
diggable = false,
node_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
selection_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
after_destruct = function(pos,oldnode)
local node = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
if node.name == "lib_tools:box_rope" then
minetest.remove_node({x=pos.x,y=pos.y-1,z=pos.z})
end
end,
})
minetest.register_node("lib_tools:ropebox", {
description = "Ropebox",
drawtype = "nodebox",
sunlight_propagates = true,
tiles = {"castle_ropebox_top.png",
"castle_ropebox_top.png",
"castle_ropebox_side_1.png",
"castle_ropebox_side_1.png",
"castle_ropebox_side_2.png",
"castle_ropebox_side_2.png"},
paramtype = "light",
paramtype2 = "facedir",
connects_to = { "lib_tools:box_rope" },
groups = {choppy=3},
node_box = {
type = "fixed",
fixed = {
{-2/16, -2/16, -4/16, 2/16, 2/16, 4/16},
{-2/16, -4/16, -2/16, 2/16, 4/16, 2/16},
{-2/16, -3/16, -3/16, 2/16, 3/16, 3/16},
{-3/16, -2/16, -2/16, -2/16, 8/16, 2/16},
{2/16, -2/16, -2/16, 3/16, 8/16, 2/16},
{-1/16, -8/16, -1/16, 1/16, -4/16, 1/16}
},
},
after_destruct = function(pos,oldnode)
local node = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
if node.name == "lib_tools:box_rope" then
minetest.remove_node({x=pos.x,y=pos.y-1,z=pos.z})
end
end,
on_place = function(itemstack, placer, pointed_thing)
if pointed_thing.type ~= "node" then
return itemstack
end
local p0 = pointed_thing.under
local p1 = pointed_thing.above
local param2 = 0
local placer_pos = placer:getpos()
if placer_pos then
local dir = {
x = p1.x - placer_pos.x,
y = p1.y - placer_pos.y,
z = p1.z - placer_pos.z
}
param2 = minetest.dir_to_facedir(dir)
end
if p0.y-1 == p1.y then
param2 = param2 + 20
if param2 == 21 then
param2 = 23
elseif param2 == 23 then
param2 = 21
end
end
return minetest.item_place(itemstack, placer, pointed_thing, param2)
end,
})
minetest.register_abm({
nodenames = {"lib_tools:ropebox"},
interval = 1,
chance = 1,
action = function(pos, node)
if minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name ~= 'air' then return end
minetest.add_node({x=pos.x,y=pos.y-1,z=pos.z}, {name="lib_tools:box_rope"})
end
})
minetest.register_abm({
nodenames = {"lib_tools:box_rope"},
interval = 1,
chance = 1,
action = function(pos, node)
if minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name ~= 'air' then return end
minetest.add_node({x=pos.x,y=pos.y-1,z=pos.z}, {name="lib_tools:box_rope"})
end
})
minetest.register_craft({
output = "lib_tools:ropebox",
recipe = {
{"default:wood"},
{"lib_tools:rope_1m"},
}
})

122
ropes.lua Normal file
View File

@ -0,0 +1,122 @@
minetest.register_node("lib_tools:ropes",{
description = "Rope",
drawtype = "nodebox",
sunlight_propagates = true,
tiles = {"castle_ropes.png"},
groups = {choppy=3,snappy=3,oddly_breakable_by_hand=3,flammable=1},
paramtype = "light",
climbable = true,
walkable = false,
node_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
selection_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
})
minetest.register_craft({
output = "lib_tools:ropes",
recipe = {
{"farming:string"},
{"farming:string"},
{"farming:string"},
}
})
minetest.register_node("lib_tools:box_rope", {
description = "Rope from Ropebox",
drawtype = "nodebox",
paramtype = "light",
sunlight_propagates = true,
tiles = {"castle_ropes.png"},
groups = {not_in_creative_inventory=1},
climbable = true,
walkable = false,
diggable = false,
node_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
selection_box = {
type = "fixed",
fixed = {
{-1/16, -8/16, -1/16, 1/16, 8/16, 1/16},
},
},
after_destruct = function(pos,oldnode)
local node = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
if node.name == "lib_tools:box_rope" then
minetest.remove_node({x=pos.x,y=pos.y-1,z=pos.z})
end
end,
})
minetest.register_node("lib_tools:ropebox", {
description = "Ropebox",
drawtype = "nodebox",
sunlight_propagates = true,
tiles = {"castle_ropebox_top.png",
"castle_ropebox_top.png",
"castle_ropebox_side_1.png",
"castle_ropebox_side_1.png",
"castle_ropebox_side_2.png",
"castle_ropebox_side_2.png"},
paramtype = "light",
paramtype2 = "facedir",
groups = {choppy=3},
node_box = {
type = "fixed",
fixed = {
{-2/16, -2/16, -4/16, 2/16, 2/16, 4/16},
{-2/16, -4/16, -2/16, 2/16, 4/16, 2/16},
{-2/16, -3/16, -3/16, 2/16, 3/16, 3/16},
{-3/16, -2/16, -2/16, -2/16, 8/16, 2/16},
{2/16, -2/16, -2/16, 3/16, 8/16, 2/16},
{-1/16, -8/16, -1/16, 1/16, -4/16, 1/16},
},
},
after_destruct = function(pos,oldnode)
local node = minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z})
if node.name == "lib_tools:box_rope" then
minetest.remove_node({x=pos.x,y=pos.y-1,z=pos.z})
end
end,
})
minetest.register_abm({
nodenames = {"lib_tools:ropebox"},
interval = 1,
chance = 1,
action = function(pos, node)
if minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name ~= 'air' then return end
minetest.add_node({x=pos.x,y=pos.y-1,z=pos.z}, {name="lib_tools:box_rope"})
end
})
minetest.register_abm({
nodenames = {"lib_tools:box_rope"},
interval = 1,
chance = 1,
action = function(pos, node)
if minetest.get_node({x=pos.x,y=pos.y-1,z=pos.z}).name ~= 'air' then return end
minetest.add_node({x=pos.x,y=pos.y-1,z=pos.z}, {name="lib_tools:box_rope"})
end
})
minetest.register_craft({
output = "lib_tools:ropebox",
recipe = {
{"default:wood"},
{"lib_tools:ropes"},
}
})

102
rubber.lua Normal file
View File

@ -0,0 +1,102 @@
-- Code of rubber tree by PilzAdam
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
minetest.register_node(":moretrees:rubber_tree_sapling", {
description = S("Rubber Tree Sapling"),
drawtype = "plantlike",
tiles = {"technic_rubber_sapling.png"},
inventory_image = "technic_rubber_sapling.png",
wield_image = "technic_rubber_sapling.png",
paramtype = "light",
walkable = false,
groups = {dig_immediate=3, flammable=2, sapling=1},
sounds = default.node_sound_defaults(),
})
minetest.register_craft({
type = "fuel",
recipe = "moretrees:rubber_tree_sapling",
burntime = 10
})
minetest.register_node(":moretrees:rubber_tree_trunk", {
description = S("Rubber Tree"),
tiles = {"default_tree_top.png", "default_tree_top.png",
"technic_rubber_tree_full.png"},
groups = {tree=1, snappy=1, choppy=2, oddly_breakable_by_hand=1,
flammable=2},
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node(":moretrees:rubber_tree_trunk_empty", {
description = S("Rubber Tree"),
tiles = {"default_tree_top.png", "default_tree_top.png",
"technic_rubber_tree_empty.png"},
groups = {tree=1, snappy=1, choppy=2, oddly_breakable_by_hand=1,
flammable=2, not_in_creative_inventory=1},
sounds = default.node_sound_wood_defaults(),
})
minetest.register_node(":moretrees:rubber_tree_leaves", {
drawtype = "allfaces_optional",
description = S("Rubber Tree Leaves"),
tiles = {"technic_rubber_leaves.png"},
paramtype = "light",
groups = {snappy=3, leafdecay=3, flammable=2, leaves=1},
drop = {
max_items = 1,
items = {{
items = {"moretrees:rubber_tree_sapling"},
rarity = 20,
},
{
items = {"moretrees:rubber_tree_leaves"},
}
}
},
sounds = default.node_sound_leaves_defaults(),
})
lib_tools.rubber_tree_model={
axiom = "FFFFA",
rules_a = "[&FFBFA]////[&BFFFA]////[&FBFFA]",
rules_b = "[&FFA]////[&FFA]////[&FFA]",
trunk = "moretrees:rubber_tree_trunk",
leaves = "moretrees:rubber_tree_leaves",
angle = 35,
iterations = 3,
random_level = 1,
trunk_type = "double",
thin_branches = true
}
minetest.register_abm({
nodenames = {"moretrees:rubber_tree_sapling"},
label = "Worldgen: grow rubber tree sapling",
interval = 60,
chance = 20,
action = function(pos, node)
minetest.remove_node(pos)
minetest.spawn_tree(pos, lib_tools.rubber_tree_model)
end
})
if lib_tools.config:get_bool("enable_rubber_tree_generation") then
minetest.register_on_generated(function(minp, maxp, blockseed)
if math.random(1, 100) > 5 then
return
end
local tmp = {
x = (maxp.x - minp.x) / 2 + minp.x,
y = (maxp.y - minp.y) / 2 + minp.y,
z = (maxp.z - minp.z) / 2 + minp.z}
local pos = minetest.find_node_near(tmp, maxp.x - minp.x,
{"default:dirt_with_grass"})
if pos ~= nil then
minetest.spawn_tree({x=pos.x, y=pos.y+1, z=pos.z}, lib_tools.rubber_tree_model)
end
end)
end

100
sonic_screwdriver.lua Normal file
View File

@ -0,0 +1,100 @@
local sonic_screwdriver_max_charge = 15000
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
lib_tools.register_power_tool("lib_tools:sonic_screwdriver", sonic_screwdriver_max_charge)
-- screwdriver handler code reused from minetest/minetest_game screwdriver @a9ac480
local ROTATE_FACE = 1
local ROTATE_AXIS = 2
local function nextrange(x, max)
x = x + 1
if x > max then
x = 0
end
return x
end
-- Handles rotation
local function screwdriver_handler(itemstack, user, pointed_thing, mode)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
if minetest.is_protected(pos, user:get_player_name()) then
minetest.record_protection_violation(pos, user:get_player_name())
return
end
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if not ndef or not ndef.paramtype2 == "facedir" or
(ndef.drawtype == "nodebox" and
not ndef.node_box.type == "fixed") or
node.param2 == nil then
return
end
-- contrary to the default screwdriver, do not check for can_dig, to allow rotating machines with CLU's in them
-- this is consistent with the previous sonic screwdriver
local meta1 = minetest.deserialize(itemstack:get_metadata())
if not meta1 or not meta1.charge or meta1.charge < 100 then
return
end
minetest.sound_play("technic_sonic_screwdriver", {pos = pos, gain = 0.3, max_hear_distance = 10})
-- Set param2
local rotationPart = node.param2 % 32 -- get first 4 bits
local preservePart = node.param2 - rotationPart
local axisdir = math.floor(rotationPart / 4)
local rotation = rotationPart - axisdir * 4
if mode == ROTATE_FACE then
rotationPart = axisdir * 4 + nextrange(rotation, 3)
elseif mode == ROTATE_AXIS then
rotationPart = nextrange(axisdir, 5) * 4
end
node.param2 = preservePart + rotationPart
minetest.swap_node(pos, node)
if not lib_tools.creative_mode then
meta1.charge = meta1.charge - 100
itemstack:set_metadata(minetest.serialize(meta1))
lib_tools.set_RE_wear(itemstack, meta1.charge, sonic_screwdriver_max_charge)
end
return itemstack
end
minetest.register_tool("lib_tools:sonic_screwdriver", {
description = S("Sonic Screwdriver (left-click rotates face, right-click rotates axis)"),
inventory_image = "technic_sonic_screwdriver.png",
wear_represents = "technic_RE_charge",
on_refill = lib_tools.refill_RE_charge,
on_use = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing, ROTATE_FACE)
return itemstack
end,
on_place = function(itemstack, user, pointed_thing)
screwdriver_handler(itemstack, user, pointed_thing, ROTATE_AXIS)
return itemstack
end,
})
minetest.register_craft({
output = "lib_tools:sonic_screwdriver",
recipe = {
{"", "default:diamond", ""},
{"", "screwdriver:screwdriver", ""},
{"", "", ""}
}
})

78
tree_tap.lua Normal file
View File

@ -0,0 +1,78 @@
local MP = minetest.get_modpath(minetest.get_current_modname())
local S, NS = dofile(MP.."/intllib.lua")
local mesecons_materials = minetest.get_modpath("mesecons_materials")
minetest.register_tool("lib_tools:treetap", {
description = S("Tree Tap"),
inventory_image = "technic_tree_tap.png",
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type ~= "node" then
return
end
local pos = pointed_thing.under
if minetest.is_protected(pos, user:get_player_name()) then
minetest.record_protection_violation(pos, user:get_player_name())
return
end
local node = minetest.get_node(pos)
local node_name = node.name
if node_name ~= "moretrees:rubber_tree_trunk" then
return
end
node.name = "moretrees:rubber_tree_trunk_empty"
minetest.swap_node(pos, node)
minetest.handle_node_drops(pointed_thing.above, {"lib_tools:raw_latex"}, user)
if not lib_tools.creative_mode then
local item_wear = tonumber(itemstack:get_wear())
item_wear = item_wear + 819
if item_wear > 65535 then
itemstack:clear()
return itemstack
end
itemstack:set_wear(item_wear)
end
return itemstack
end,
})
minetest.register_craft({
output = "lib_tools:treetap",
recipe = {
{"pipeworks:tube_1", "group:wood", "default:stick"},
{"", "default:stick", "default:stick"}
},
})
minetest.register_craftitem("lib_tools:raw_latex", {
description = S("Raw Latex"),
inventory_image = "technic_raw_latex.png",
})
if mesecons_materials then
minetest.register_craft({
type = "cooking",
recipe = "lib_tools:raw_latex",
output = "mesecons_materials:glue",
})
end
minetest.register_craftitem("lib_tools:rubber", {
description = S("Rubber Fiber"),
inventory_image = "technic_rubber.png",
})
minetest.register_abm({
label = "Tools: tree tap",
nodenames = {"moretrees:rubber_tree_trunk_empty"},
interval = 60,
chance = 15,
action = function(pos, node)
if minetest.find_node_near(pos, (moretrees and moretrees.leafdecay_radius) or 5, {"moretrees:rubber_tree_leaves"}) then
node.name = "moretrees:rubber_tree_trunk"
minetest.swap_node(pos, node)
end
end
})

17
utils.lua Normal file
View File

@ -0,0 +1,17 @@
lib_tools.pixelbox = function(size, boxes)
local fixed = {}
for _, box in pairs(boxes) do
-- `unpack` has been changed to `table.unpack` in newest Lua versions.
local x, y, z, w, h, l = unpack(box)
fixed[#fixed+1] = {
(x / size) - 0.5,
(y / size) - 0.5,
(z / size) - 0.5,
((x + w) / size) - 0.5,
((y + h) / size) - 0.5,
((z + l) / size) - 0.5
}
end
return { type = "fixed", fixed = fixed }
end