mirror of
https://github.com/minetest/minetest_game.git
synced 2024-12-23 15:20:19 +01:00
7b46d3b6af
If backface culling is not specified for a tile in 'images' it is set to true. Slabs already have backface culling due to being defined as nodeboxes (which are then converted to meshnodes).
635 lines
15 KiB
Lua
635 lines
15 KiB
Lua
-- Minetest 0.4 mod: stairs
|
|
-- See README.txt for licensing and other information.
|
|
|
|
|
|
-- Global namespace for functions
|
|
|
|
stairs = {}
|
|
|
|
|
|
-- Register aliases for new pine node names
|
|
|
|
minetest.register_alias("stairs:stair_pinewood", "stairs:stair_pine_wood")
|
|
minetest.register_alias("stairs:slab_pinewood", "stairs:slab_pine_wood")
|
|
|
|
|
|
-- Get setting for replace ABM
|
|
|
|
local replace = minetest.settings:get_bool("enable_stairs_replace_abm")
|
|
|
|
local function rotate_and_place(itemstack, placer, pointed_thing)
|
|
local p0 = pointed_thing.under
|
|
local p1 = pointed_thing.above
|
|
local param2 = 0
|
|
|
|
local placer_pos = placer:getpos()
|
|
if placer_pos then
|
|
param2 = minetest.dir_to_facedir(vector.subtract(p1, placer_pos))
|
|
end
|
|
|
|
local finepos = minetest.pointed_thing_to_face_pos(placer, pointed_thing)
|
|
local fpos = finepos.y % 1
|
|
|
|
if p0.y - 1 == p1.y or (fpos > 0 and fpos < 0.5)
|
|
or (fpos < -0.5 and fpos > -0.999999999) 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
|
|
|
|
-- Register stairs.
|
|
-- Node will be called stairs:stair_<subname>
|
|
|
|
function stairs.register_stair(subname, recipeitem, groups, images, description, sounds)
|
|
local stair_images = {}
|
|
for i, image in ipairs(images) do
|
|
if type(image) == "string" then
|
|
stair_images[i] = {
|
|
name = image,
|
|
backface_culling = true,
|
|
}
|
|
elseif image.backface_culling == nil then -- override using any other value
|
|
stair_images[i] = table.copy(image)
|
|
stair_images[i].backface_culling = true
|
|
end
|
|
end
|
|
groups.stair = 1
|
|
minetest.register_node(":stairs:stair_" .. subname, {
|
|
description = description,
|
|
drawtype = "mesh",
|
|
mesh = "stairs_stair.obj",
|
|
tiles = stair_images,
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
is_ground_content = false,
|
|
groups = groups,
|
|
sounds = sounds,
|
|
selection_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
|
{-0.5, 0, 0, 0.5, 0.5, 0.5},
|
|
},
|
|
},
|
|
collision_box = {
|
|
type = "fixed",
|
|
fixed = {
|
|
{-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
|
{-0.5, 0, 0, 0.5, 0.5, 0.5},
|
|
},
|
|
},
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
if pointed_thing.type ~= "node" then
|
|
return itemstack
|
|
end
|
|
|
|
return rotate_and_place(itemstack, placer, pointed_thing)
|
|
end,
|
|
})
|
|
|
|
-- for replace ABM
|
|
if replace then
|
|
minetest.register_node(":stairs:stair_" .. subname .. "upside_down", {
|
|
replace_name = "stairs:stair_" .. subname,
|
|
groups = {slabs_replace = 1},
|
|
})
|
|
end
|
|
|
|
if recipeitem then
|
|
-- Recipe matches appearence in inventory
|
|
minetest.register_craft({
|
|
output = 'stairs:stair_' .. subname .. ' 8',
|
|
recipe = {
|
|
{"", "", recipeitem},
|
|
{"", recipeitem, recipeitem},
|
|
{recipeitem, recipeitem, recipeitem},
|
|
},
|
|
})
|
|
|
|
-- Use stairs to craft full blocks again (1:1)
|
|
minetest.register_craft({
|
|
output = recipeitem .. ' 3',
|
|
recipe = {
|
|
{'stairs:stair_' .. subname, 'stairs:stair_' .. subname},
|
|
{'stairs:stair_' .. subname, 'stairs:stair_' .. subname},
|
|
},
|
|
})
|
|
|
|
-- Fuel
|
|
local baseburntime = minetest.get_craft_result({
|
|
method = "fuel",
|
|
width = 1,
|
|
items = {recipeitem}
|
|
}).time
|
|
if baseburntime > 0 then
|
|
minetest.register_craft({
|
|
type = "fuel",
|
|
recipe = 'stairs:stair_' .. subname,
|
|
burntime = math.floor(baseburntime * 0.75),
|
|
})
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Slab facedir to placement 6d matching table
|
|
local slab_trans_dir = {[0] = 8, 0, 2, 1, 3, 4}
|
|
|
|
-- Register slabs.
|
|
-- Node will be called stairs:slab_<subname>
|
|
|
|
function stairs.register_slab(subname, recipeitem, groups, images, description, sounds)
|
|
groups.slab = 1
|
|
minetest.register_node(":stairs:slab_" .. subname, {
|
|
description = description,
|
|
drawtype = "nodebox",
|
|
tiles = images,
|
|
paramtype = "light",
|
|
paramtype2 = "facedir",
|
|
is_ground_content = false,
|
|
groups = groups,
|
|
sounds = sounds,
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = {-0.5, -0.5, -0.5, 0.5, 0, 0.5},
|
|
},
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
local under = minetest.get_node(pointed_thing.under)
|
|
local wield_item = itemstack:get_name()
|
|
local creative_enabled = (creative and creative.is_enabled_for
|
|
and creative.is_enabled_for(placer:get_player_name()))
|
|
|
|
if under and under.name:find("stairs:slab_") then
|
|
-- place slab using under node orientation
|
|
local dir = minetest.dir_to_facedir(vector.subtract(
|
|
pointed_thing.above, pointed_thing.under), true)
|
|
|
|
local p2 = under.param2
|
|
|
|
-- combine two slabs if possible
|
|
if slab_trans_dir[math.floor(p2 / 4)] == dir
|
|
and wield_item == under.name then
|
|
|
|
if not recipeitem then
|
|
return itemstack
|
|
end
|
|
local player_name = placer:get_player_name()
|
|
if minetest.is_protected(pointed_thing.under, player_name) and not
|
|
minetest.check_player_privs(placer, "protection_bypass") then
|
|
minetest.record_protection_violation(pointed_thing.under,
|
|
player_name)
|
|
return
|
|
end
|
|
minetest.set_node(pointed_thing.under, {name = recipeitem, param2 = p2})
|
|
if not creative_enabled then
|
|
itemstack:take_item()
|
|
end
|
|
return itemstack
|
|
end
|
|
|
|
-- Placing a slab on an upside down slab should make it right-side up.
|
|
if p2 >= 20 and dir == 8 then
|
|
p2 = p2 - 20
|
|
-- same for the opposite case: slab below normal slab
|
|
elseif p2 <= 3 and dir == 4 then
|
|
p2 = p2 + 20
|
|
end
|
|
|
|
-- else attempt to place node with proper param2
|
|
minetest.item_place_node(ItemStack(wield_item), placer, pointed_thing, p2)
|
|
if not creative_enabled then
|
|
itemstack:take_item()
|
|
end
|
|
return itemstack
|
|
else
|
|
return rotate_and_place(itemstack, placer, pointed_thing)
|
|
end
|
|
end,
|
|
})
|
|
|
|
-- for replace ABM
|
|
if replace then
|
|
minetest.register_node(":stairs:slab_" .. subname .. "upside_down", {
|
|
replace_name = "stairs:slab_".. subname,
|
|
groups = {slabs_replace = 1},
|
|
})
|
|
end
|
|
|
|
if recipeitem then
|
|
minetest.register_craft({
|
|
output = 'stairs:slab_' .. subname .. ' 6',
|
|
recipe = {
|
|
{recipeitem, recipeitem, recipeitem},
|
|
},
|
|
})
|
|
|
|
-- Use 2 slabs to craft a full block again (1:1)
|
|
minetest.register_craft({
|
|
output = recipeitem,
|
|
recipe = {
|
|
{'stairs:slab_' .. subname},
|
|
{'stairs:slab_' .. subname},
|
|
},
|
|
})
|
|
|
|
-- Fuel
|
|
local baseburntime = minetest.get_craft_result({
|
|
method = "fuel",
|
|
width = 1,
|
|
items = {recipeitem}
|
|
}).time
|
|
if baseburntime > 0 then
|
|
minetest.register_craft({
|
|
type = "fuel",
|
|
recipe = 'stairs:slab_' .. subname,
|
|
burntime = math.floor(baseburntime * 0.5),
|
|
})
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
-- Optionally replace old "upside_down" nodes with new param2 versions.
|
|
-- Disabled by default.
|
|
|
|
if replace then
|
|
minetest.register_abm({
|
|
label = "Slab replace",
|
|
nodenames = {"group:slabs_replace"},
|
|
interval = 16,
|
|
chance = 1,
|
|
action = function(pos, node)
|
|
node.name = minetest.registered_nodes[node.name].replace_name
|
|
node.param2 = node.param2 + 20
|
|
if node.param2 == 21 then
|
|
node.param2 = 23
|
|
elseif node.param2 == 23 then
|
|
node.param2 = 21
|
|
end
|
|
minetest.set_node(pos, node)
|
|
end,
|
|
})
|
|
end
|
|
|
|
|
|
-- Stair/slab registration function.
|
|
-- Nodes will be called stairs:{stair,slab}_<subname>
|
|
|
|
function stairs.register_stair_and_slab(subname, recipeitem,
|
|
groups, images, desc_stair, desc_slab, sounds)
|
|
stairs.register_stair(subname, recipeitem, groups, images, desc_stair, sounds)
|
|
stairs.register_slab(subname, recipeitem, groups, images, desc_slab, sounds)
|
|
end
|
|
|
|
|
|
-- Register default stairs and slabs
|
|
|
|
stairs.register_stair_and_slab(
|
|
"wood",
|
|
"default:wood",
|
|
{choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
|
|
{"default_wood.png"},
|
|
"Wooden Stair",
|
|
"Wooden Slab",
|
|
default.node_sound_wood_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"junglewood",
|
|
"default:junglewood",
|
|
{choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
|
|
{"default_junglewood.png"},
|
|
"Jungle Wood Stair",
|
|
"Jungle Wood Slab",
|
|
default.node_sound_wood_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"pine_wood",
|
|
"default:pine_wood",
|
|
{choppy = 3, oddly_breakable_by_hand = 2, flammable = 3},
|
|
{"default_pine_wood.png"},
|
|
"Pine Wood Stair",
|
|
"Pine Wood Slab",
|
|
default.node_sound_wood_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"acacia_wood",
|
|
"default:acacia_wood",
|
|
{choppy = 2, oddly_breakable_by_hand = 2, flammable = 2},
|
|
{"default_acacia_wood.png"},
|
|
"Acacia Wood Stair",
|
|
"Acacia Wood Slab",
|
|
default.node_sound_wood_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"aspen_wood",
|
|
"default:aspen_wood",
|
|
{choppy = 3, oddly_breakable_by_hand = 2, flammable = 3},
|
|
{"default_aspen_wood.png"},
|
|
"Aspen Wood Stair",
|
|
"Aspen Wood Slab",
|
|
default.node_sound_wood_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"stone",
|
|
"default:stone",
|
|
{cracky = 3},
|
|
{"default_stone.png"},
|
|
"Stone Stair",
|
|
"Stone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"cobble",
|
|
"default:cobble",
|
|
{cracky = 3},
|
|
{"default_cobble.png"},
|
|
"Cobblestone Stair",
|
|
"Cobblestone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"mossycobble",
|
|
"default:mossycobble",
|
|
{cracky = 3},
|
|
{"default_mossycobble.png"},
|
|
"Mossy Cobblestone Stair",
|
|
"Mossy Cobblestone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"stonebrick",
|
|
"default:stonebrick",
|
|
{cracky = 2},
|
|
{"default_stone_brick.png"},
|
|
"Stone Brick Stair",
|
|
"Stone Brick Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"stone_block",
|
|
"default:stone_block",
|
|
{cracky = 2},
|
|
{"default_stone_block.png"},
|
|
"Stone Block Stair",
|
|
"Stone Block Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"desert_stone",
|
|
"default:desert_stone",
|
|
{cracky = 3},
|
|
{"default_desert_stone.png"},
|
|
"Desert Stone Stair",
|
|
"Desert Stone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"desert_cobble",
|
|
"default:desert_cobble",
|
|
{cracky = 3},
|
|
{"default_desert_cobble.png"},
|
|
"Desert Cobblestone Stair",
|
|
"Desert Cobblestone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"desert_stonebrick",
|
|
"default:desert_stonebrick",
|
|
{cracky = 2},
|
|
{"default_desert_stone_brick.png"},
|
|
"Desert Stone Brick Stair",
|
|
"Desert Stone Brick Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"desert_stone_block",
|
|
"default:desert_stone_block",
|
|
{cracky = 2},
|
|
{"default_desert_stone_block.png"},
|
|
"Desert Stone Block Stair",
|
|
"Desert Stone Block Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"sandstone",
|
|
"default:sandstone",
|
|
{crumbly = 1, cracky = 3},
|
|
{"default_sandstone.png"},
|
|
"Sandstone Stair",
|
|
"Sandstone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"sandstonebrick",
|
|
"default:sandstonebrick",
|
|
{cracky = 2},
|
|
{"default_sandstone_brick.png"},
|
|
"Sandstone Brick Stair",
|
|
"Sandstone Brick Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"sandstone_block",
|
|
"default:sandstone_block",
|
|
{cracky = 2},
|
|
{"default_sandstone_block.png"},
|
|
"Sandstone Block Stair",
|
|
"Sandstone Block Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"desert_sandstone",
|
|
"default:desert_sandstone",
|
|
{crumbly = 1, cracky = 3},
|
|
{"default_desert_sandstone.png"},
|
|
"Desert Sandstone Stair",
|
|
"Desert Sandstone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"desert_sandstone_brick",
|
|
"default:desert_sandstone_brick",
|
|
{cracky = 2},
|
|
{"default_desert_sandstone_brick.png"},
|
|
"Desert Sandstone Brick Stair",
|
|
"Desert Sandstone Brick Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"desert_sandstone_block",
|
|
"default:desert_sandstone_block",
|
|
{cracky = 2},
|
|
{"default_desert_sandstone_block.png"},
|
|
"Desert Sandstone Block Stair",
|
|
"Desert Sandstone Block Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"silver_sandstone",
|
|
"default:silver_sandstone",
|
|
{crumbly = 1, cracky = 3},
|
|
{"default_silver_sandstone.png"},
|
|
"Silver Sandstone Stair",
|
|
"Silver Sandstone Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"silver_sandstone_brick",
|
|
"default:silver_sandstone_brick",
|
|
{cracky = 2},
|
|
{"default_silver_sandstone_brick.png"},
|
|
"Silver Sandstone Brick Stair",
|
|
"Silver Sandstone Brick Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"silver_sandstone_block",
|
|
"default:silver_sandstone_block",
|
|
{cracky = 2},
|
|
{"default_silver_sandstone_block.png"},
|
|
"Silver Sandstone Block Stair",
|
|
"Silver Sandstone Block Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"obsidian",
|
|
"default:obsidian",
|
|
{cracky = 1, level = 2},
|
|
{"default_obsidian.png"},
|
|
"Obsidian Stair",
|
|
"Obsidian Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"obsidianbrick",
|
|
"default:obsidianbrick",
|
|
{cracky = 1, level = 2},
|
|
{"default_obsidian_brick.png"},
|
|
"Obsidian Brick Stair",
|
|
"Obsidian Brick Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"obsidian_block",
|
|
"default:obsidian_block",
|
|
{cracky = 1, level = 2},
|
|
{"default_obsidian_block.png"},
|
|
"Obsidian Block Stair",
|
|
"Obsidian Block Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"brick",
|
|
"default:brick",
|
|
{cracky = 3},
|
|
{"default_brick.png"},
|
|
"Brick Stair",
|
|
"Brick Slab",
|
|
default.node_sound_stone_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"straw",
|
|
"farming:straw",
|
|
{snappy = 3, flammable = 4},
|
|
{"farming_straw.png"},
|
|
"Straw Stair",
|
|
"Straw Slab",
|
|
default.node_sound_leaves_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"steelblock",
|
|
"default:steelblock",
|
|
{cracky = 1, level = 2},
|
|
{"default_steel_block.png"},
|
|
"Steel Block Stair",
|
|
"Steel Block Slab",
|
|
default.node_sound_metal_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"copperblock",
|
|
"default:copperblock",
|
|
{cracky = 1, level = 2},
|
|
{"default_copper_block.png"},
|
|
"Copper Block Stair",
|
|
"Copper Block Slab",
|
|
default.node_sound_metal_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"bronzeblock",
|
|
"default:bronzeblock",
|
|
{cracky = 1, level = 2},
|
|
{"default_bronze_block.png"},
|
|
"Bronze Block Stair",
|
|
"Bronze Block Slab",
|
|
default.node_sound_metal_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"goldblock",
|
|
"default:goldblock",
|
|
{cracky = 1},
|
|
{"default_gold_block.png"},
|
|
"Gold Block Stair",
|
|
"Gold Block Slab",
|
|
default.node_sound_metal_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"ice",
|
|
"default:ice",
|
|
{cracky = 3, puts_out_fire = 1, cools_lava = 1},
|
|
{"default_ice.png"},
|
|
"Ice Stair",
|
|
"Ice Slab",
|
|
default.node_sound_glass_defaults()
|
|
)
|
|
|
|
stairs.register_stair_and_slab(
|
|
"snowblock",
|
|
"default:snowblock",
|
|
{crumbly = 3, puts_out_fire = 1, cools_lava = 1, snowy = 1},
|
|
{"default_snow.png"},
|
|
"Snow Block Stair",
|
|
"Snow Block Slab",
|
|
default.node_sound_dirt_defaults({
|
|
footstep = {name = "default_snow_footstep", gain = 0.15},
|
|
dug = {name = "default_snow_footstep", gain = 0.2},
|
|
dig = {name = "default_snow_footstep", gain = 0.2}
|
|
})
|
|
)
|