player_api/mods/doors/init.lua
Auke Kok 322967d2d1 Better trapdoor side appearance.
We're using a normal wooden side texture to draw the sides
of trapdoors. But the side textures have only 2 edges that
have a nice texture for the 2px wide trapdoor. We can
either repaint the textures, or just rotate the texture
properly for the two sides that need it.

Because the side texture for wooden doors was just a default:wood
texture, it clashes with the colors in the trapdoor, and so
we add a wooden trapdoor-matching tile side texture as well.

This also improves the steel trapdoor side, but without a
texture change there since that was already a specially
drawn texture for that node.

We also increase the thickness of the trapdoor to 2px. Right
now the model is 0.4 large, but this causes the side textures
to look odd as there's a mismatch in pixel size. By scaling the
trapdoor side up to exactly 2px, the sides look natural.

Thanks to @kilbith for the suggestion.
2016-01-20 22:17:25 +00:00

550 lines
15 KiB
Lua

doors = {}
-- Registers a door
function doors.register_door(name, def)
def.groups.not_in_creative_inventory = 1
local box = {{-0.5, -0.5, -0.5, 0.5, 0.5, -0.5+1.5/16}}
if not def.node_box_bottom then
def.node_box_bottom = box
end
if not def.node_box_top then
def.node_box_top = box
end
if not def.selection_box_bottom then
def.selection_box_bottom= box
end
if not def.selection_box_top then
def.selection_box_top = box
end
if not def.sound_close_door then
def.sound_close_door = "doors_door_close"
end
if not def.sound_open_door then
def.sound_open_door = "doors_door_open"
end
minetest.register_craftitem(name, {
description = def.description,
inventory_image = def.inventory_image,
on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing.type == "node" then
return itemstack
end
local ptu = pointed_thing.under
local nu = minetest.get_node(ptu)
if minetest.registered_nodes[nu.name].on_rightclick then
return minetest.registered_nodes[nu.name].on_rightclick(ptu, nu, placer, itemstack)
end
local pt = pointed_thing.above
local pt2 = {x=pt.x, y=pt.y, z=pt.z}
pt2.y = pt2.y+1
if
not minetest.registered_nodes[minetest.get_node(pt).name].buildable_to or
not minetest.registered_nodes[minetest.get_node(pt2).name].buildable_to or
not placer or
not placer:is_player()
then
return itemstack
end
if minetest.is_protected(pt, placer:get_player_name()) or
minetest.is_protected(pt2, placer:get_player_name()) then
minetest.record_protection_violation(pt, placer:get_player_name())
return itemstack
end
local p2 = minetest.dir_to_facedir(placer:get_look_dir())
local pt3 = {x=pt.x, y=pt.y, z=pt.z}
if p2 == 0 then
pt3.x = pt3.x-1
elseif p2 == 1 then
pt3.z = pt3.z+1
elseif p2 == 2 then
pt3.x = pt3.x+1
elseif p2 == 3 then
pt3.z = pt3.z-1
end
if minetest.get_item_group(minetest.get_node(pt3).name, "door") == 0 then
minetest.set_node(pt, {name=name.."_b_1", param2=p2})
minetest.set_node(pt2, {name=name.."_t_1", param2=p2})
else
minetest.set_node(pt, {name=name.."_b_2", param2=p2})
minetest.set_node(pt2, {name=name.."_t_2", param2=p2})
minetest.get_meta(pt):set_int("right", 1)
minetest.get_meta(pt2):set_int("right", 1)
end
if def.only_placer_can_open then
local pn = placer:get_player_name()
local meta = minetest.get_meta(pt)
meta:set_string("doors_owner", pn)
meta:set_string("infotext", "Owned by "..pn)
meta = minetest.get_meta(pt2)
meta:set_string("doors_owner", pn)
meta:set_string("infotext", "Owned by "..pn)
end
if not minetest.setting_getbool("creative_mode") then
itemstack:take_item()
end
return itemstack
end,
})
local tt = def.tiles_top
local tb = def.tiles_bottom
local function after_dig_node(pos, name, digger)
local node = minetest.get_node(pos)
if node.name == name then
minetest.node_dig(pos, node, digger)
end
end
local function check_and_blast(pos, name)
local node = minetest.get_node(pos)
if node.name == name then
minetest.remove_node(pos)
end
end
local function make_on_blast(base_name, dir, door_type, other_door_type)
if def.only_placer_can_open then
return function() end
else
return function(pos, intensity)
check_and_blast(pos, base_name .. door_type)
pos.y = pos.y + dir
check_and_blast(pos, base_name .. other_door_type)
end
end
end
local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
pos.y = pos.y+dir
if minetest.get_node(pos).name ~= check_name then
return
end
local p2 = minetest.get_node(pos).param2
p2 = params[p2+1]
minetest.swap_node(pos, {name=replace_dir, param2=p2})
pos.y = pos.y-dir
minetest.swap_node(pos, {name=replace, param2=p2})
local snd_1 = def.sound_close_door
local snd_2 = def.sound_open_door
if params[1] == 3 then
snd_1 = def.sound_open_door
snd_2 = def.sound_close_door
end
if minetest.get_meta(pos):get_int("right") ~= 0 then
minetest.sound_play(snd_1, {pos = pos, gain = 0.3, max_hear_distance = 10})
else
minetest.sound_play(snd_2, {pos = pos, gain = 0.3, max_hear_distance = 10})
end
end
local function check_player_priv(pos, player)
if not def.only_placer_can_open then
return true
end
local meta = minetest.get_meta(pos)
local pn = player:get_player_name()
return meta:get_string("doors_owner") == pn
end
local function on_rotate(pos, node, dir, user, check_name, mode, new_param2)
if not check_player_priv(pos, user) then
return false
end
if mode ~= screwdriver.ROTATE_FACE then
return false
end
pos.y = pos.y + dir
if not minetest.get_node(pos).name == check_name then
return false
end
if minetest.is_protected(pos, user:get_player_name()) then
minetest.record_protection_violation(pos, user:get_player_name())
return false
end
local node2 = minetest.get_node(pos)
node2.param2 = (node2.param2 + 1) % 4
minetest.swap_node(pos, node2)
pos.y = pos.y - dir
node.param2 = (node.param2 + 1) % 4
minetest.swap_node(pos, node)
return true
end
minetest.register_node(name.."_b_1", {
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1], tb[1].."^[transformfx"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
drop = name,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = def.node_box_bottom
},
selection_box = {
type = "fixed",
fixed = def.selection_box_bottom
},
groups = def.groups,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
pos.y = pos.y+1
after_dig_node(pos, name.."_t_1", digger)
end,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
on_rightclick(pos, 1, name.."_t_1", name.."_b_2", name.."_t_2", {1,2,3,0})
end
end,
on_rotate = function(pos, node, user, mode, new_param2)
return on_rotate(pos, node, 1, user, name.."_t_1", mode)
end,
can_dig = check_player_priv,
sounds = def.sounds,
sunlight_propagates = def.sunlight,
on_blast = make_on_blast(name, 1, "_b_1", "_t_1")
})
minetest.register_node(name.."_t_1", {
tiles = {tt[2], tt[2], tt[2], tt[2], tt[1], tt[1].."^[transformfx"},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
drop = "",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = def.node_box_top
},
selection_box = {
type = "fixed",
fixed = def.selection_box_top
},
groups = def.groups,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
pos.y = pos.y-1
after_dig_node(pos, name.."_b_1", digger)
end,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
on_rightclick(pos, -1, name.."_b_1", name.."_t_2", name.."_b_2", {1,2,3,0})
end
end,
on_rotate = function(pos, node, user, mode, new_param2)
return on_rotate(pos, node, -1, user, name.."_b_1", mode)
end,
can_dig = check_player_priv,
sounds = def.sounds,
sunlight_propagates = def.sunlight,
on_blast = make_on_blast(name, -1, "_t_1", "_b_1")
})
minetest.register_node(name.."_b_2", {
tiles = {tb[2], tb[2], tb[2], tb[2], tb[1].."^[transformfx", tb[1]},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
drop = name,
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = def.node_box_bottom
},
selection_box = {
type = "fixed",
fixed = def.selection_box_bottom
},
groups = def.groups,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
pos.y = pos.y+1
after_dig_node(pos, name.."_t_2", digger)
end,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
on_rightclick(pos, 1, name.."_t_2", name.."_b_1", name.."_t_1", {3,0,1,2})
end
end,
on_rotate = function(pos, node, user, mode, new_param2)
return on_rotate(pos, node, 1, user, name.."_t_2", mode)
end,
can_dig = check_player_priv,
sounds = def.sounds,
sunlight_propagates = def.sunlight,
on_blast = make_on_blast(name, 1, "_b_2", "_t_2")
})
minetest.register_node(name.."_t_2", {
tiles = {tt[2], tt[2], tt[2], tt[2], tt[1].."^[transformfx", tt[1]},
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
drop = "",
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = def.node_box_top
},
selection_box = {
type = "fixed",
fixed = def.selection_box_top
},
groups = def.groups,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
pos.y = pos.y-1
after_dig_node(pos, name.."_b_2", digger)
end,
on_rightclick = function(pos, node, clicker)
if check_player_priv(pos, clicker) then
on_rightclick(pos, -1, name.."_b_2", name.."_t_1", name.."_b_1", {3,0,1,2})
end
end,
on_rotate = function(pos, node, user, mode, new_param2)
return on_rotate(pos, node, -1, user, name.."_b_2", mode)
end,
can_dig = check_player_priv,
sounds = def.sounds,
sunlight_propagates = def.sunlight,
on_blast = make_on_blast(name, -1, "_t_2", "_b_2")
})
end
doors.register_door("doors:door_wood", {
description = "Wooden Door",
inventory_image = "doors_wood.png",
groups = {snappy=1,choppy=2,oddly_breakable_by_hand=2,flammable=2,door=1},
tiles_bottom = {"doors_wood_b.png", "doors_brown.png"},
tiles_top = {"doors_wood_a.png", "doors_brown.png"},
sounds = default.node_sound_wood_defaults(),
sunlight = false,
})
minetest.register_craft({
output = "doors:door_wood",
recipe = {
{"group:wood", "group:wood"},
{"group:wood", "group:wood"},
{"group:wood", "group:wood"}
}
})
doors.register_door("doors:door_steel", {
description = "Steel Door",
inventory_image = "doors_steel.png",
groups = {snappy=1,bendy=2,cracky=1,melty=2,level=2,door=1},
tiles_bottom = {"doors_steel_b.png", "doors_grey.png"},
tiles_top = {"doors_steel_a.png", "doors_grey.png"},
only_placer_can_open = true,
sounds = default.node_sound_wood_defaults(),
sunlight = false,
})
minetest.register_craft({
output = "doors:door_steel",
recipe = {
{"default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot"}
}
})
doors.register_door("doors:door_glass", {
description = "Glass Door",
inventory_image = "doors_glass.png",
groups = {snappy=1,cracky=1,oddly_breakable_by_hand=3,door=1},
tiles_bottom = {"doors_glass_b.png", "doors_glass_side.png"},
tiles_top = {"doors_glass_a.png", "doors_glass_side.png"},
sounds = default.node_sound_glass_defaults(),
sunlight = true,
})
minetest.register_craft({
output = "doors:door_glass",
recipe = {
{"default:glass", "default:glass"},
{"default:glass", "default:glass"},
{"default:glass", "default:glass"}
}
})
doors.register_door("doors:door_obsidian_glass", {
description = "Obsidian Glass Door",
inventory_image = "doors_obsidian_glass.png",
groups = {snappy=1,cracky=1,oddly_breakable_by_hand=3,door=1},
tiles_bottom = {"doors_obsidian_glass_b.png", "doors_obsidian_glass_side.png"},
tiles_top = {"doors_obsidian_glass_a.png", "doors_obsidian_glass_side.png"},
sounds = default.node_sound_glass_defaults(),
sunlight = true,
})
minetest.register_craft({
output = "doors:door_obsidian_glass",
recipe = {
{"default:obsidian_glass", "default:obsidian_glass"},
{"default:obsidian_glass", "default:obsidian_glass"},
{"default:obsidian_glass", "default:obsidian_glass"}
}
})
----trapdoor----
function doors.register_trapdoor(name, def)
local name_closed = name
local name_opened = name.."_open"
local function check_player_priv(pos, player)
if not def.only_placer_can_open then
return true
end
local meta = minetest.get_meta(pos)
local pn = player:get_player_name()
return meta:get_string("doors_owner") == pn
end
def.on_rightclick = function (pos, node, clicker, itemstack, pointed_thing)
if not check_player_priv(pos, clicker) then
return
end
local newname = node.name == name_closed and name_opened or name_closed
local sound = false
if node.name == name_closed then sound = def.sound_open end
if node.name == name_opened then sound = def.sound_close end
if sound then
minetest.sound_play(sound, {pos = pos, gain = 0.3, max_hear_distance = 10})
end
minetest.swap_node(pos, {name = newname, param1 = node.param1, param2 = node.param2})
end
-- Common trapdoor configuration
def.drawtype = "nodebox"
def.paramtype = "light"
def.paramtype2 = "facedir"
def.is_ground_content = false
def.can_dig = check_player_priv
if def.only_placer_can_open then
def.after_place_node = function(pos, placer, itemstack, pointed_thing)
local pn = placer:get_player_name()
local meta = minetest.get_meta(pos)
meta:set_string("doors_owner", pn)
meta:set_string("infotext", "Owned by "..pn)
return minetest.setting_getbool("creative_mode")
end
end
local def_opened = table.copy(def)
local def_closed = table.copy(def)
def_closed.node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5}
}
def_closed.selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -6/16, 0.5}
}
def_closed.tiles = { def.tile_front, def.tile_front, def.tile_side, def.tile_side,
def.tile_side, def.tile_side }
def_opened.node_box = {
type = "fixed",
fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5}
}
def_opened.selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, 6/16, 0.5, 0.5, 0.5}
}
def_opened.tiles = { def.tile_side, def.tile_side,
def.tile_side .. '^[transform3',
def.tile_side .. '^[transform1',
def.tile_front, def.tile_front }
def_opened.drop = name_closed
def_opened.groups.not_in_creative_inventory = 1
minetest.register_node(name_opened, def_opened)
minetest.register_node(name_closed, def_closed)
end
doors.register_trapdoor("doors:trapdoor", {
description = "Trapdoor",
inventory_image = "doors_trapdoor.png",
wield_image = "doors_trapdoor.png",
tile_front = "doors_trapdoor.png",
tile_side = "doors_trapdoor_side.png",
groups = {snappy=1, choppy=2, oddly_breakable_by_hand=2, flammable=2, door=1},
sounds = default.node_sound_wood_defaults(),
sound_open = "doors_door_open",
sound_close = "doors_door_close"
})
doors.register_trapdoor("doors:trapdoor_steel", {
description = "Steel Trapdoor",
inventory_image = "doors_trapdoor_steel.png",
wield_image = "doors_trapdoor_steel.png",
tile_front = "doors_trapdoor_steel.png",
tile_side = "doors_trapdoor_steel_side.png",
only_placer_can_open = true,
groups = {snappy=1, bendy=2, cracky=1, melty=2, level=2, door=1},
sounds = default.node_sound_wood_defaults(),
sound_open = "doors_door_open",
sound_close = "doors_door_close"
})
minetest.register_craft({
output = 'doors:trapdoor 2',
recipe = {
{'group:wood', 'group:wood', 'group:wood'},
{'group:wood', 'group:wood', 'group:wood'},
{'', '', ''},
}
})
minetest.register_craft({
output = 'doors:trapdoor_steel',
recipe = {
{'default:steel_ingot', 'default:steel_ingot'},
{'default:steel_ingot', 'default:steel_ingot'},
}
})