2024-08-10 09:37:33 +02:00

493 lines
14 KiB
Lua

-- Lazarr! 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
-- If set to true, will print a list of translatable strings
-- for the registered nodes to the console so it can
-- be copied into this source file.
local GENERATE_TRANSLATABLE_STRING_LIST = false
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.
-- CAN be rotated.
-- 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 unusual and differs from most other Minetest games.
-- The segments have been made slightly different so that a laser will alway
-- be completely blocked off from any direction.
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.
-- CAN'T be rotated to simplify the code.
-- Rotation code MAY be added, as long the node remains compatible with lasers.
-- Registers two nodes:
-- * stairs:slab_<subname> for the normal slab and
-- * stairs:slab_laser_<subname> for the slab with laser from above
function stairs.register_slab(subname, recipeitem, groups, images, description,
sounds, worldaligntex)
local src_def = minetest.registered_nodes[recipeitem]
-- Use first tile only, for slab mesh
local slab_images = table.copy(images)
if type(slab_images[1]) == "string" then
-- Add backface culling because otherwise z-fighting occurs when
-- inside the node
slab_images[1] = { name = slab_images[1], backface_culling = true }
end
if not slab_images[2] then
slab_images[2] = slab_images[1]
end
if not slab_images[3] then
slab_images[3] = slab_images[2]
end
slab_images[4] = "blank.png"
slab_images[5] = nil
slab_images[6] = nil
local laser_slab_images = table.copy(slab_images)
laser_slab_images[4] = lzr_laser.LASER_TILE
local new_groups = table.copy(groups)
new_groups.slab = 1
new_groups.laser_block = 1
lzr_laser.register_element(":stairs:slab_" .. subname, {
description = description,
drawtype = "mesh",
mesh_off = "lzr_stairs_slab_laser.obj",
mesh_on = "lzr_stairs_slab_laser.obj",
tiles_off = slab_images,
tiles_on = laser_slab_images,
use_texture_alpha = "blend",
paramtype = "light",
is_ground_content = false,
groups = new_groups,
sounds = sounds,
collision_box = {
type = "fixed",
-- The slab nodebox is slightly higher than half of a node
-- so that an incoming laser from any direction (except the top)
-- will be visually blocked.
fixed = {-0.5, -0.5, -0.5, 0.5, 1/16, 0.5},
},
selection_box = {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, 1/16, 0.5},
},
light_source_on = lzr_globals.LASER_GLOW,
}, { group = "laser_element_slab_"..subname } )
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)
if GENERATE_TRANSLATABLE_STRING_LIST then
for _,x in ipairs({"","Inner ","Outer "}) do
print(("S(%q)"):format(x..desc_stair))
end
print(("S(%q)"):format(desc_slab))
end
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_and_slab(
"wood_mossy",
"lzr_core:wood_mossy",
{breakable=1},
{"lzr_core_wood_mossy.png"},
"Mossy Wooden Stair",
"Mossy Wooden Slab",
lzr_sounds.node_sound_wood_defaults(),
true
)
my_register_stair_and_slab(
"palm_wood",
"lzr_core:palm_wood",
{breakable=1},
{"lzr_core_palm_wood.png"},
"Palm Wood Stair",
"Palm Wood Slab",
lzr_sounds.node_sound_wood_defaults(),
true
)
my_register_stair_and_slab(
"coconut_wood",
"lzr_core:coconut_wood",
{breakable=1},
{"lzr_core_coconut_wood.png"},
"Coconut Wood Stair",
"Coconut Wood Slab",
lzr_sounds.node_sound_wood_defaults(),
true
)
my_register_stair_and_slab(
"stone",
"lzr_core:stone",
{breakable=1},
{"default_stone.png"},
"Stone Stair",
"Stone Slab",
lzr_sounds.node_sound_stone_defaults(),
true
)
my_register_stair_and_slab(
"ocean_stone",
"lzr_decor:ocean_stone",
{breakable=1},
{"xocean_stone.png"},
"Ocean Stone Stair",
"Ocean Stone Slab",
lzr_sounds.node_sound_stone_defaults(),
true
)
my_register_stair_and_slab(
"ocean_cobble",
"lzr_decor:ocean_cobble",
{breakable=1},
{"xocean_cobble.png"},
"Ocean Cobblestone Stair",
"Ocean Cobblestone Slab",
lzr_sounds.node_sound_stone_defaults(),
true
)
my_register_stair_and_slab(
"thatch",
"lzr_decor:thatch",
{breakable=1},
{"dryplants_thatch.png"},
"Thatch Stair",
"Thatch Slab",
lzr_sounds.node_sound_leaves_defaults(),
true
)
my_register_stair_and_slab(
"thatch_wet",
"lzr_decor:thatch_wet",
{breakable=1},
{"dryplants_thatch_wet.png"},
"Wet Thatch Stair",
"Wet Thatch Slab",
lzr_sounds.node_sound_leaves_defaults(),
true
)
-- Dummy calls to S() to allow translation scripts to detect the strings.
-- MUST be updated before release when new nodes have arrived.
-- To update this, set GENERATE_TRANSLATABLE_STRING_LIST to true
-- and paste the console output here:
--[[
S("Wooden Stair")
S("Inner Wooden Stair")
S("Outer Wooden Stair")
S("Wooden Slab")
S("Mossy Wooden Stair")
S("Inner Mossy Wooden Stair")
S("Outer Mossy Wooden Stair")
S("Mossy Wooden Slab")
S("Palm Wood Stair")
S("Inner Palm Wood Stair")
S("Outer Palm Wood Stair")
S("Palm Wood Slab")
S("Coconut Wood Stair")
S("Inner Coconut Wood Stair")
S("Outer Coconut Wood Stair")
S("Coconut Wood Slab")
S("Stone Stair")
S("Inner Stone Stair")
S("Outer Stone Stair")
S("Stone Slab")
S("Ocean Stone Stair")
S("Inner Ocean Stone Stair")
S("Outer Ocean Stone Stair")
S("Ocean Stone Slab")
S("Ocean Cobblestone Stair")
S("Inner Ocean Cobblestone Stair")
S("Outer Ocean Cobblestone Stair")
S("Ocean Cobblestone Slab")
S("Thatch Stair")
S("Inner Thatch Stair")
S("Outer Thatch Stair")
S("Thatch Slab")
S("Wet Thatch Stair")
S("Inner Wet Thatch Stair")
S("Outer Wet Thatch Stair")
S("Wet Thatch Slab")
]]
-- Aliases for the pre-laser color era
minetest.register_alias("stairs:slab_wood_laser", "stairs:slab_wood_on_1")
minetest.register_alias("stairs:slab_wood_mossy_laser", "stairs:slab_wood_mossy_on_1")
minetest.register_alias("stairs:slab_palm_wood_laser", "stairs:slab_palm_wood_on_1")
minetest.register_alias("stairs:slab_coconut_wood_laser", "stairs:slab_coconut_wood_on_1")
minetest.register_alias("stairs:slab_stone_laser", "stairs:slab_stone_on_1")
minetest.register_alias("stairs:slab_ocean_stone_laser", "stairs:slab_ocean_stone_on_1")
minetest.register_alias("stairs:slab_ocean_cobble_laser", "stairs:slab_ocean_cobble_on_1")
minetest.register_alias("stairs:slab_thatch_laser", "stairs:slab_thatch_on_1")
minetest.register_alias("stairs:slab_thatch_wet_laser", "stairs:slab_thatch_wet_on_1")