297 lines
7.8 KiB
Lua
297 lines
7.8 KiB
Lua
customnode = {}
|
|
customnode._templates = {}
|
|
|
|
----------------------------------------------------
|
|
-- API Call to create the nodes reading textures folder
|
|
----------------------------------------------------
|
|
function customnode.add_nodes_from_textures(conf)
|
|
|
|
--[[
|
|
the texture names needs to follow the next convention:
|
|
modname_[prefix_][generator_][name_][tiletype].xyz
|
|
[] is optional
|
|
|
|
conf can contains the next attributes:
|
|
conf.descr_prefix - Additional prefix to the node description
|
|
conf.check_prefix - Enhance the prefix check to modname_addprefix_ instead of default modname_
|
|
conf.add_stairs_slabs - generate stairs and slabs from stairs mod in addition to the node
|
|
|
|
]]
|
|
|
|
if not conf.add_stairs_slabs then
|
|
conf.add_stairs_slabs = "brick,cobblestone,ice,sandstone,stone"
|
|
end
|
|
|
|
local customnode_list = customnode.get_nodelist_by_textures(conf.check_prefix)
|
|
for name, generator in pairs(customnode_list) do
|
|
local nodedef = generator:get_nodedef(conf)
|
|
if nodedef then
|
|
minetest.register_node(nodedef.name, nodedef)
|
|
if minetest.global_exists("stairs") and conf.add_stairs_slabs ~= false then
|
|
if conf.add_stairs_slabs == true or (type(conf.add_stairs_slabs) == "string" and string.find(conf.add_stairs_slabs, generator.variant)) then
|
|
stairs.register_stair_and_slab(
|
|
generator.modname.."_"..generator:get_name(),
|
|
nodedef.name,
|
|
table.copy(nodedef.groups),
|
|
table.copy(nodedef.tiles),
|
|
nodedef.description.." Stair",
|
|
nodedef.description.." Stone Slab",
|
|
table.copy(nodedef.sounds)
|
|
)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
----------------------------------------------------
|
|
-- API Call - register new nodes generator
|
|
----------------------------------------------------
|
|
function customnode.register_generator(name, def)
|
|
customnode._templates[name] = def
|
|
if name ~= "default" then
|
|
setmetatable(def, customnode._templates.default)
|
|
end
|
|
def.__index = customnode._templates.default
|
|
end
|
|
|
|
|
|
----------------------------------------------------
|
|
-- read textures folder and get node names
|
|
----------------------------------------------------
|
|
function customnode.get_nodelist_by_textures(prefix, generator_mapping)
|
|
if not generator_mapping then
|
|
generator_mapping = {
|
|
brick = "default",
|
|
cobblestone = "default",
|
|
dirt = "default",
|
|
grass = "default",
|
|
ice = "default",
|
|
iron = "default",
|
|
sandstone = "default",
|
|
stone = "default",
|
|
item = "skip",
|
|
}
|
|
end
|
|
|
|
local tile_mapping = {
|
|
top = "top",
|
|
bottom = "bottom",
|
|
down = "bottom",
|
|
right = "right",
|
|
left = "left",
|
|
back = "back",
|
|
inner = "back",
|
|
front = "front",
|
|
side = "all",
|
|
normal = "all",
|
|
}
|
|
|
|
local modname = minetest.get_current_modname()
|
|
local modpath = minetest.get_modpath(modname)
|
|
local files = minetest.get_dir_list(modpath.."/textures")
|
|
|
|
local customnode_list = {}
|
|
|
|
-- syntax is modename_[prefix_]_name_[type_][tiletype].xyz
|
|
local def_name_idx_start = 2
|
|
if prefix then
|
|
def_name_idx_start = 3
|
|
end
|
|
|
|
for _, v in ipairs(files) do
|
|
local index = 0
|
|
local skip = false
|
|
|
|
local basename
|
|
local variant
|
|
local generator
|
|
local tiletype
|
|
|
|
for part in v:gmatch("([^_]+)") do -- split filename by "_"
|
|
index = index + 1
|
|
|
|
-- remove file ending in last part
|
|
part = part:gsub('%....$','')
|
|
|
|
-- check modname namespace
|
|
if index == 1 then
|
|
if part ~= modname then
|
|
skip = true
|
|
break
|
|
end
|
|
|
|
-- check additional namespace
|
|
elseif index == 2 and prefix then
|
|
if part ~= prefix then
|
|
skip = true
|
|
break
|
|
end
|
|
|
|
-- process tile mapping
|
|
elseif tile_mapping[part] then
|
|
tiletype = tile_mapping[part]
|
|
|
|
else
|
|
if not generator and generator_mapping[part] then
|
|
variant = part
|
|
generator = customnode._templates[generator_mapping[part]]
|
|
end
|
|
if not basename then
|
|
basename = part
|
|
else
|
|
basename = basename.."_"..part
|
|
end
|
|
end
|
|
end
|
|
|
|
if not skip then
|
|
-- default tiletype
|
|
if not tiletype then
|
|
tiletype = "all"
|
|
end
|
|
|
|
-- default generator
|
|
if not generator then
|
|
variant = "default"
|
|
generator = customnode._templates["default"]
|
|
end
|
|
|
|
-- Add information to the customnode
|
|
if not customnode_list[basename] then
|
|
customnode_list[basename] = generator:new({
|
|
modname = modname,
|
|
prefix = prefix,
|
|
basename = basename,
|
|
variant = variant,
|
|
})
|
|
end
|
|
customnode_list[basename].tiles[tiletype] = v
|
|
end
|
|
end
|
|
return customnode_list
|
|
end
|
|
|
|
----------------------------------------------------
|
|
-- Default base generator
|
|
----------------------------------------------------
|
|
customnode.register_generator("default", {
|
|
-- create new generator (constructor
|
|
new = function(self, def)
|
|
local obj = setmetatable(def, self)
|
|
obj.__index = self
|
|
obj.tiles = {}
|
|
return obj
|
|
end,
|
|
|
|
-- Main method - get a node definition for customnode
|
|
get_nodedef = function(self, conf)
|
|
self.conf = conf
|
|
local nodedef = self:get_template()
|
|
nodedef.name = self.modname..":"..self:get_name()
|
|
nodedef.description = self:get_description()
|
|
nodedef.tiles = self:get_tiles()
|
|
nodedef.sounds = self:get_sounds()
|
|
nodedef.paramtype2 = self:get_paramtype2()
|
|
nodedef.groups = self:get_groups()
|
|
return nodedef
|
|
end,
|
|
|
|
-- get the base template for the node
|
|
get_template = function(self)
|
|
return {
|
|
is_ground_content = false,
|
|
}
|
|
end,
|
|
|
|
-- Get node name
|
|
get_name = function(self)
|
|
if not self.basename then
|
|
return self.modname
|
|
else
|
|
return self.basename
|
|
end
|
|
end,
|
|
|
|
-- Get node description
|
|
get_description = function(self)
|
|
local descr = self.conf.descr_prefix or self.modname
|
|
if self.basename then
|
|
descr = descr.." "..self.basename:gsub("_"," ")
|
|
end
|
|
return descr
|
|
end,
|
|
|
|
-- Get the tiles table for node definition
|
|
get_tiles = function(self)
|
|
local fallback_file = self.tiles.all
|
|
or self.tiles.left or self.tiles.right
|
|
or self.tiles.back or self.tiles.front
|
|
or self.tiles.bottom or self.tiles.top
|
|
|
|
local nodetiles = {}
|
|
nodetiles[1] = self.tiles.top or fallback_file
|
|
nodetiles[2] = self.tiles.bottom or fallback_file
|
|
nodetiles[3] = self.tiles.right or fallback_file
|
|
nodetiles[4] = self.tiles.left or fallback_file
|
|
nodetiles[5] = self.tiles.back or fallback_file
|
|
nodetiles[6] = self.tiles.front or fallback_file
|
|
return nodetiles
|
|
end,
|
|
|
|
-- get sounds for the node
|
|
get_sounds = function(self)
|
|
local sound_mapping = {
|
|
dirt = default.node_sound_dirt_defaults(),
|
|
grass = minetest.registered_nodes["default:dirt_with_grass"].sounds,
|
|
ice = default.node_sound_glass_defaults(),
|
|
default = default.node_sound_stone_defaults(),
|
|
}
|
|
local sound = sound_mapping[self.variant]
|
|
if not sound then
|
|
sound = sound_mapping.default
|
|
end
|
|
return table.copy(sound)
|
|
end,
|
|
get_paramtype2 = function(self)
|
|
if self.tiles.front then
|
|
return "facedir"
|
|
end
|
|
end,
|
|
get_groups = function(self)
|
|
local groups_mapping = {
|
|
brick = {cracky = 2, stone = 1, oddly_breakable_by_hand = 2},
|
|
cobblestone = {cracky = 3, stone = 2, oddly_breakable_by_hand = 2},
|
|
dirt = {crumbly = 3, oddly_breakable_by_hand = 2},
|
|
grass = {crumbly = 3, oddly_breakable_by_hand = 2},
|
|
ice = {cracky = 3, oddly_breakable_by_hand = 2},
|
|
iron = {cracky = 1, oddly_breakable_by_hand = 2},
|
|
sandstone = {crumbly = 1, cracky = 3, oddly_breakable_by_hand = 2},
|
|
stone = {cracky = 3, stone = 1, oddly_breakable_by_hand = 2},
|
|
default = {crumbly = 1, cracky = 3, oddly_breakable_by_hand = 2},
|
|
}
|
|
local groups = groups_mapping[self.variant]
|
|
if not groups then
|
|
groups = groups_mapping.default
|
|
end
|
|
groups = table.copy(groups)
|
|
if self.variant == default then
|
|
groups.customnode = 1
|
|
else
|
|
groups["customnode_"..self.variant] = 1
|
|
end
|
|
return groups
|
|
-- groups = {choppy = 3, oddly_breakable_by_hand = 2},
|
|
end,
|
|
})
|
|
|
|
|
|
----------------------------------------------------
|
|
-- Generator that does nothing
|
|
----------------------------------------------------
|
|
customnode.register_generator("skip", {
|
|
get_nodedef = function(self, conf)
|
|
return nil
|
|
end,
|
|
})
|