lazarr/mods/stairs/init.lua

410 lines
11 KiB
Lua

-- stairs/init.lua
-- Minetest 0.4 mod: stairs
-- See README.txt for licensing and other information.
-- Global namespace for functions
stairs = {}
-- Load support for MT game translation.
local S = minetest.get_translator("stairs")
-- Same as S, but will be ignored by translation file update scripts
local T = S
local function rotate_and_place(itemstack, placer, pointed_thing)
local p0 = pointed_thing.under
local p1 = pointed_thing.above
local param2 = 0
if placer then
local placer_pos = placer:get_pos()
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
end
return minetest.item_place(itemstack, placer, pointed_thing, param2)
end
-- Register stair
-- Node will be called stairs:stair_<subname>
function stairs.register_stair(subname, recipeitem, groups, images, description,
sounds, worldaligntex)
local src_def = minetest.registered_nodes[recipeitem]
-- Set backface culling and world-aligned textures
local stair_images = {}
for i, image in ipairs(images) do
if type(image) == "string" then
stair_images[i] = {
name = image,
backface_culling = true,
}
if worldaligntex then
stair_images[i].align_style = "world"
end
else
stair_images[i] = table.copy(image)
if stair_images[i].backface_culling == nil then
stair_images[i].backface_culling = true
end
if worldaligntex and stair_images[i].align_style == nil then
stair_images[i].align_style = "world"
end
end
end
local new_groups = table.copy(groups)
new_groups.stair = 1
new_groups.rotatable = 3
minetest.register_node(":stairs:stair_" .. subname, {
description = description,
drawtype = "nodebox",
tiles = stair_images,
use_texture_alpha = src_def and src_def.use_texture_alpha,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
groups = new_groups,
sounds = sounds,
node_box = {
-- This stairs nodebox is a bit unusual.
-- This is done in a way that it completely blocks off the laser.
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1/16, 0.5},
{-0.5, 1/16, -1/16, 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,
})
end
-- Register slab
-- Node will be called stairs:slab_<subname>
function stairs.register_slab(subname, recipeitem, groups, images, description,
sounds, worldaligntex)
local src_def = minetest.registered_nodes[recipeitem]
-- Set world-aligned textures
local slab_images = {}
for i, image in ipairs(images) do
if type(image) == "string" then
slab_images[i] = {
name = image,
}
if worldaligntex then
slab_images[i].align_style = "world"
end
else
slab_images[i] = table.copy(image)
if worldaligntex and image.align_style == nil then
slab_images[i].align_style = "world"
end
end
end
local new_groups = table.copy(groups)
new_groups.slab = 1
new_groups.rotatable = 3
minetest.register_node(":stairs:slab_" .. subname, {
description = description,
drawtype = "nodebox",
tiles = slab_images,
use_texture_alpha = src_def and src_def.use_texture_alpha,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
groups = new_groups,
sounds = sounds,
node_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 1/16, 0.5},
},
on_place = function(itemstack, placer, pointed_thing)
local under = minetest.get_node(pointed_thing.under)
local wield_item = itemstack:get_name()
local player_name = placer and placer:get_player_name() or ""
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
-- 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 minetest.is_creative_enabled(player_name) then
itemstack:take_item()
end
return itemstack
else
return rotate_and_place(itemstack, placer, pointed_thing)
end
end,
})
end
-- Register inner stair
-- Node will be called stairs:stair_inner_<subname>
function stairs.register_stair_inner(subname, recipeitem, groups, images,
description, sounds, worldaligntex, full_description)
local src_def = minetest.registered_nodes[recipeitem]
-- Set backface culling and world-aligned textures
local stair_images = {}
for i, image in ipairs(images) do
if type(image) == "string" then
stair_images[i] = {
name = image,
backface_culling = true,
}
if worldaligntex then
stair_images[i].align_style = "world"
end
else
stair_images[i] = table.copy(image)
if stair_images[i].backface_culling == nil then
stair_images[i].backface_culling = true
end
if worldaligntex and stair_images[i].align_style == nil then
stair_images[i].align_style = "world"
end
end
end
local new_groups = table.copy(groups)
new_groups.stair = 1
if full_description then
description = full_description
else
description = "Inner " .. description
end
minetest.register_node(":stairs:stair_inner_" .. subname, {
description = description,
drawtype = "nodebox",
tiles = stair_images,
use_texture_alpha = src_def and src_def.use_texture_alpha,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
groups = new_groups,
sounds = sounds,
node_box = {
-- Unusual stairs nodebox (see stairs comment)
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1/16, 0.5},
{-0.5, 1/16, -1/16, 0.5, 0.5, 0.5},
{-0.5, 1/16, -0.5, 1/16, 0.5, -1/16},
},
},
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,
})
end
-- Register outer stair
-- Node will be called stairs:stair_outer_<subname>
function stairs.register_stair_outer(subname, recipeitem, groups, images,
description, sounds, worldaligntex, full_description)
local src_def = minetest.registered_nodes[recipeitem]
-- Set backface culling and world-aligned textures
local stair_images = {}
for i, image in ipairs(images) do
if type(image) == "string" then
stair_images[i] = {
name = image,
backface_culling = true,
}
if worldaligntex then
stair_images[i].align_style = "world"
end
else
stair_images[i] = table.copy(image)
if stair_images[i].backface_culling == nil then
stair_images[i].backface_culling = true
end
if worldaligntex and stair_images[i].align_style == nil then
stair_images[i].align_style = "world"
end
end
end
local new_groups = table.copy(groups)
new_groups.stair = 1
if full_description then
description = full_description
else
description = "Outer " .. description
end
minetest.register_node(":stairs:stair_outer_" .. subname, {
description = description,
drawtype = "nodebox",
tiles = stair_images,
use_texture_alpha = src_def and src_def.use_texture_alpha,
paramtype = "light",
paramtype2 = "facedir",
is_ground_content = false,
groups = new_groups,
sounds = sounds,
node_box = {
-- Unusual stairs nodebox (see stairs comment)
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, 1/16, 0.5},
{-0.5, 1/16, -1/16, 1/16, 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,
})
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, worldaligntex,
desc_stair_inner, desc_stair_outer)
stairs.register_stair(subname, recipeitem, groups, images, desc_stair,
sounds, worldaligntex)
stairs.register_stair_inner(subname, recipeitem, groups, images,
desc_stair, sounds, worldaligntex, desc_stair_inner)
stairs.register_stair_outer(subname, recipeitem, groups, images,
desc_stair, sounds, worldaligntex, desc_stair_outer)
stairs.register_slab(subname, recipeitem, groups, images, desc_slab,
sounds, worldaligntex)
end
-- Local function so we can apply translations
local function my_register_stair(subname, recipeitem, groups, images,
desc_stair, sounds, worldaligntex)
stairs.register_stair(subname, recipeitem, groups, images, S(desc_stair),
sounds, worldaligntex)
stairs.register_stair_inner(subname, recipeitem, groups, images, "",
sounds, worldaligntex, T("Inner " .. desc_stair))
stairs.register_stair_outer(subname, recipeitem, groups, images, "",
sounds, worldaligntex, T("Outer " .. desc_stair))
end
local function my_register_stair_and_slab(subname, recipeitem, groups, images,
desc_stair, desc_slab, sounds, worldaligntex)
my_register_stair(subname, recipeitem, groups, images,
desc_stair, sounds, worldaligntex)
stairs.register_slab(subname, recipeitem, groups, images, S(desc_slab),
sounds, worldaligntex)
end
-- Register default stairs and slabs
my_register_stair_and_slab(
"wood",
"lzr_core:wood",
{breakable=1},
{"default_wood.png"},
"Wooden Stair",
"Wooden Slab",
lzr_sounds.node_sound_wood_defaults(),
true
)
my_register_stair(
"stone",
"lzr_core:stone",
{breakable=1},
{"default_stone.png"},
"Stone Stair",
lzr_sounds.node_sound_stone_defaults(),
true
)
my_register_stair(
"ocean_stone",
"lzr_decor:ocean_stone",
{breakable=1},
{"xocean_stone.png"},
"Ocean Stone Stair",
lzr_sounds.node_sound_stone_defaults(),
true
)
my_register_stair(
"ocean_cobble",
"lzr_decor:ocean_cobble",
{breakable=1},
{"xocean_cobble.png"},
"Ocean Cobblestone Stair",
lzr_sounds.node_sound_stone_defaults(),
true
)
-- Dummy calls to S() to allow translation scripts to detect the strings.
-- To update this add this code to my_register_stair_and_slab:
-- for _,x in ipairs({"","Inner ","Outer "}) do print(("S(%q)"):format(x..desc_stair)) end
-- print(("S(%q)"):format(desc_slab))
--[[
S("Wooden Stair")
S("Inner Wooden Stair")
S("Outer Wooden Stair")
S("Wooden Slab")
S("Stone Stair")
S("Inner Stone Stair")
S("Outer Stone Stair")
S("Ocean Stone Stair")
S("Inner Ocean Stone Stair")
S("Outer Ocean Stone Stair")
S("Ocean Cobblestone Stair")
S("Inner Ocean Cobblestone Stair")
S("Outer Ocean Cobblestone Stair")
]]