Add files via upload
This commit is contained in:
parent
70fbb8ddb9
commit
4669b94b46
378
anvil.lua
Normal file
378
anvil.lua
Normal 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
625
chess.lua
Normal 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
44
config.lua
Normal 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
200
cooking.lua
Normal 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
156
craftguide.lua
Normal 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
9
depends.txt
Normal file
@ -0,0 +1,9 @@
|
||||
default
|
||||
wool
|
||||
3d_armor?
|
||||
pipeworks?
|
||||
bucket?
|
||||
screwdriver?
|
||||
mesecons?
|
||||
mesecons_mvps?
|
||||
intllib?
|
283
enchanting.lua
Normal file
283
enchanting.lua
Normal 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
743
enchanting3.lua
Normal 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
125
flashlight.lua
Normal 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
142
init.lua
Normal 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
45
intllib.lua
Normal 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
163
mailbox.lua
Normal 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
117
mechanisms.lua
Normal 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
950
nodes_straw.lua
Normal 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
84
registration.lua
Normal 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
226
rope.lua
Normal 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
122
ropes.lua
Normal 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
102
rubber.lua
Normal 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
100
sonic_screwdriver.lua
Normal 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
78
tree_tap.lua
Normal 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
17
utils.lua
Normal 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user