From e712a06299f59a0ae53d90704cabb096382db19a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Ronvel?= Date: Mon, 24 Aug 2020 18:03:21 +0200 Subject: [PATCH] Improved chisel, with API, support for reverse cycle and copy-paste of 'chisel' style --- chisel.lua | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++ init.lua | 148 ++++++++++++++------------------------------- 2 files changed, 217 insertions(+), 103 deletions(-) create mode 100644 chisel.lua diff --git a/chisel.lua b/chisel.lua new file mode 100644 index 0000000..681f60e --- /dev/null +++ b/chisel.lua @@ -0,0 +1,172 @@ +chisel = {} +local S = minetest.get_translator(minetest.get_current_modname()) + +chisel.chiselable = {} +chisel.group_style_index = {} +chisel.group_style_nodes = {} +chisel.player_copied_style = {} + + + +chisel.register_chiselable = function(node_name, group_name, style) + chisel.chiselable[ node_name ] = {} + chisel.chiselable[ node_name ].group_name = group_name + chisel.chiselable[ node_name ].style = style + + if not chisel.group_style_nodes[ group_name ] then + chisel.group_style_nodes[ group_name ] = {} + end + + chisel.group_style_nodes[ group_name ][ style ] = node_name +end + + + +chisel.register_chiselable_stair_and_slab = function(node_subname, group_subname, style) + chisel.register_chiselable("stairs:stair_" .. node_subname, "stairs:stair_" .. group_subname, style) + chisel.register_chiselable("stairs:stair_inner_" .. node_subname, "stairs:stair_inner_" .. group_subname, style) + chisel.register_chiselable("stairs:stair_outer_" .. node_subname, "stairs:stair_outer_" .. group_subname, style) + chisel.register_chiselable("stairs:slab_" .. node_subname, "stairs:slab_" .. group_subname, style) +end + + + +local function chisel_interact(player, pointed_thing, is_right_click) + if pointed_thing.type ~= "node" then return end + + local pos = pointed_thing.under + local is_sneak = player and player:get_player_control().sneak or false + local player_name = player and player:get_player_name() + + -- A true player is required + if not player_name then return end + + -- Check for node protection + if minetest.is_protected(pos, player_name) then + minetest.chat_send_player(player_name, "You're not authorized to alter nodes in this area") + minetest.record_protection_violation(pos, player_name) + return + end + + -- Retrieve group info and styles + local node = minetest.get_node(pos) + local node_name = node.name + + if not chisel.chiselable[ node_name ] then + minetest.chat_send_player(player_name, "Not chiselable") + return + end + + local group_name = chisel.chiselable[ node_name ].group_name + local style = chisel.chiselable[ node_name ].style + local group = chisel.group_style_nodes[ group_name ] + local new_style , new_node_name + + + -- Now branch on the four user-input cases + if is_right_click then + if is_sneak then + -- Copy style + chisel.player_copied_style[ player_name ] = style + minetest.chat_send_player(player_name, "Chisel style " .. style .. " copied") + return + else + -- Paste style + new_style = chisel.player_copied_style[ player_name ] + if not new_style then + minetest.chat_send_player(player_name, "No chisel style copied yet, use sneak + right-click to copy a style") + return + end + + -- Already the correct style, exit now! + if new_style == style then return end + + new_node_name = group[ new_style ] + if not new_node_name then + minetest.chat_send_player(player_name, "Chisel style " .. new_style .. " is not supported by this chisel group " .. group_name) + return + end + end + else + if is_sneak then + -- Backward cycle mode + for k,v in pairs(group) do + if v == node_name then break end + new_style = k + new_node_name = v + end + + if new_node_name == nil then + -- Not found? Go for the last element + for k,v in pairs(group) do + new_style = k + new_node_name = v + end + end + else + -- Forward cycle mode + new_style , new_node_name = next(group,style) + if new_node_name == nil then + new_style , new_node_name = next(group) + end + end + end + + + -- Check if rotation could be preserved + local nodedef = minetest.registered_nodes[node_name] + local new_nodedef = minetest.registered_nodes[new_node_name] + local rotation , new_rotation + + if nodedef and new_nodedef then + if ( nodedef.paramtype2 == "facedir" or nodedef.paramtype2 == "colorfacedir" ) and ( new_nodedef.paramtype2 == "facedir" or new_nodedef.paramtype2 == "colorfacedir" ) then + rotation = node.param2 % 32 --rotation are on the last 5 digits + end + end + + -- Set the new node + minetest.set_node(pos, {name= new_node_name}) + local new_node = minetest.get_node(pos) + + -- Copy rotation if needed! + if rotation ~= nil then + new_rotation = new_node.param2 % 32 + + if new_rotation ~= rotation then + new_node.param2 = new_node.param2 - new_rotation + rotation + minetest.swap_node(pos, new_node) + end + end + + minetest.sound_play("jonez_carve", {pos = pos, gain = 0.7, max_hear_distance = 5}) +end + + + +--The chisel to carve the marble +minetest.register_craftitem("jonez:chisel", { + description = S("Chisel for Marble"), + inventory_image = "jonez_chisel.png", + wield_image = "jonez_chisel.png^[transformR180", + on_use = function(itemstack, player, pointed_thing) + chisel_interact(player, pointed_thing, false) + return itemstack + end, + on_place = function(itemstack, player, pointed_thing) + chisel_interact(player, pointed_thing, true) + return itemstack + end, +}) + + + +minetest.register_craft({ + type = "shaped", + output = "jonez:chisel", + recipe = { + {"", "", "default:diamond"}, + {"", "default:steel_ingot", ""}, + {"default:stick", "", ""}, + } +}) + diff --git a/init.lua b/init.lua index 89a206e..876f10b 100644 --- a/init.lua +++ b/init.lua @@ -1,30 +1,22 @@ --Variables +local mod_path = minetest.get_modpath(minetest.get_current_modname()) +local chisel = dofile(mod_path .. "/chisel.lua") local S = minetest.get_translator(minetest.get_current_modname()) local function firstToUpper(str) - return (str:gsub("^%l", string.upper)) -end - -local function on_punch_marble(pos, player, replace_item) - local wielded_item = player:get_wielded_item() - local wielded_item_name = wielded_item:get_name() - if wielded_item_name == "jonez:chisel" then - minetest.set_node(pos, {name= replace_item}) - minetest.sound_play("jonez_carve", {pos = pos, gain = 0.7, max_hear_distance = 5}) - end + return (str:gsub("^%l", string.upper)) end +chisel.register_chiselable("jonez:marble", "jonez:marble", "raw" ) minetest.register_node("jonez:marble", { description = S("Ancient Marble"), tiles = {"jonez_marble.png"}, is_ground_content = true, groups = {cracky=3}, sounds = default.node_sound_stone_defaults(), - on_punch = function(pos, node, player, pointed_thing) - on_punch_marble(pos, player, "jonez:marble_polished") - end, }) +chisel.register_chiselable("jonez:marble_polished", "jonez:marble", "polished" ) minetest.register_node("jonez:marble_polished", { description = S("Ancient Polished Marble"), tiles = {"jonez_marble_polished.png"}, @@ -33,6 +25,7 @@ minetest.register_node("jonez:marble_polished", { sounds = default.node_sound_stone_defaults(), }) +chisel.register_chiselable_stair_and_slab("marble", "marble", "raw" ) stairs.register_stair_and_slab( "marble", "jonez:marble", @@ -42,6 +35,8 @@ stairs.register_stair_and_slab( S("Ancient Marble Slab"), default.node_sound_stone_defaults() ) + +chisel.register_chiselable_stair_and_slab("marble_brick", "marble_brick", "raw" ) stairs.register_stair_and_slab( "marble_brick", "jonez:marble_brick", @@ -52,17 +47,16 @@ stairs.register_stair_and_slab( default.node_sound_stone_defaults() ) +chisel.register_chiselable("jonez:marble_brick", "jonez:marble_brick", "raw" ) minetest.register_node("jonez:marble_brick", { description = S("Ancient Marble Brick"), tiles = {"jonez_marble_brick.png"}, is_ground_content = false, groups = {cracky=3}, sounds = default.node_sound_stone_defaults(), - on_punch = function(pos, node, player, pointed_thing) - on_punch_marble(pos, player, "jonez:marble_brick_polished") - end, }) +chisel.register_chiselable("jonez:marble_brick_polished", "jonez:marble_brick", "polished" ) minetest.register_node("jonez:marble_brick_polished", { description = S("Ancient Marble Polished Brick"), tiles = {"jonez_marble_brick_polished.png"}, @@ -71,6 +65,7 @@ minetest.register_node("jonez:marble_brick_polished", { sounds = default.node_sound_stone_defaults(), }) +chisel.register_chiselable_stair_and_slab("marble_polished", "marble", "polished" ) stairs.register_stair_and_slab( "marble_polished", "jonez:marble_polished", @@ -80,6 +75,8 @@ stairs.register_stair_and_slab( S("Ancient Polished Marble Slab"), default.node_sound_stone_defaults() ) + +chisel.register_chiselable_stair_and_slab("marble_brick_polished", "marble_brick", "polished" ) stairs.register_stair_and_slab( "marble_brick_polished", "jonez:marble_brick_polished", @@ -135,143 +132,88 @@ local styles = { "corinthian" } ---The chisel to carve the marble -minetest.register_craftitem("jonez:chisel", { - description = S("Chisel for Marble"), - inventory_image = "jonez_chisel.png", - wield_image = "jonez_chisel.png^[transformR180" -}) -minetest.register_craft({ - type = "shaped", - output = "jonez:chisel", - recipe = { - {"", "", "default:diamond"}, - {"", "default:steel_ingot", ""}, - {"default:stick", "", ""}, - } -}) -- The Crafting of the Greek Set minetest.register_craft({ - output = 'jonez:greek_shaft 3', - type = "shaped", - recipe = { - {'', 'jonez:marble_polished', ''}, - {'', 'jonez:marble_polished', ''}, - {'', 'jonez:marble_polished', ''}, - }, + output = 'jonez:greek_shaft 3', + type = "shaped", + recipe = { + {'', 'jonez:marble_polished', ''}, + {'', 'jonez:marble_polished', ''}, + {'', 'jonez:marble_polished', ''}, + }, }) minetest.register_craft({ - output = 'jonez:greek_architrave 3', - type = "shaped", - recipe = { - {'', '', ''}, - {'', '', ''}, - {'stairs:slab_marble_polished', 'stairs:slab_marble_polished', 'stairs:slab_marble_polished'}, - }, + output = 'jonez:greek_architrave 3', + type = "shaped", + recipe = { + {'', '', ''}, + {'', '', ''}, + {'stairs:slab_marble_polished', 'stairs:slab_marble_polished', 'stairs:slab_marble_polished'}, + }, }) minetest.register_craft({ - output = 'jonez:greek_base 2', - type = "shaped", - recipe = { - {'', '', ''}, - {'', 'jonez:marble_polished', ''}, - {'', 'stairs:slab_marble_polished', ''}, - }, + output = 'jonez:greek_base 2', + type = "shaped", + recipe = { + {'', '', ''}, + {'', 'jonez:marble_polished', ''}, + {'', 'stairs:slab_marble_polished', ''}, + }, }) minetest.register_craft({ - output = 'jonez:greek_capital 2', - type = "shaped", - recipe = { - {'', '', ''}, - {'', 'stairs:slab_marble_polished', ''}, - {'', 'jonez:marble_polished', ''}, - }, + output = 'jonez:greek_capital 2', + type = "shaped", + recipe = { + {'', '', ''}, + {'', 'stairs:slab_marble_polished', ''}, + {'', 'jonez:marble_polished', ''}, + }, }) -local function save_meta(pos, i, element) - local meta = minetest.get_meta(pos) - meta:set_int("jonez:style", i) - meta:set_string("jonez:element", element) -end -local function on_punch(pos, player) - local wielded_item = player:get_wielded_item() - local wielded_item_name = wielded_item:get_name() - if wielded_item_name == "jonez:chisel" then - local meta = minetest.get_meta(pos) - local style = meta:get_int("jonez:style") - local element = meta:get_string("jonez:element") - style = style + 1 - if style > # styles then - style = 1 - end - minetest.set_node(pos, {name= "jonez:"..styles[style].."_"..element}) - minetest.sound_play("jonez_carve", {pos = pos, gain = 0.7, max_hear_distance = 5}) - end -end for i = 1, #styles do + chisel.register_chiselable("jonez:"..styles[i].."_architrave", "jonez:architrave", styles[i] ) minetest.register_node("jonez:"..styles[i].."_architrave", { description = S("Ancient").." "..S(firstToUpper(styles[i])).." "..S("Architrave"), tiles = {"jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_architrave.png"}, is_ground_content = false, groups = {cracky=3}, sounds = default.node_sound_stone_defaults(), - on_construct = function(pos) - save_meta(pos, i, "architrave") - end, - on_punch = function(pos, node, player, pointed_thing) - on_punch(pos, player) - end, }) + chisel.register_chiselable("jonez:"..styles[i].."_capital", "jonez:capital", styles[i] ) minetest.register_node("jonez:"..styles[i].."_capital", { description = S("Ancient").." "..S(firstToUpper(styles[i])).." "..S("Capital"), tiles = {"jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_capital.png"}, is_ground_content = false, groups = {cracky=3}, sounds = default.node_sound_stone_defaults(), - on_construct = function(pos) - save_meta(pos, i, "capital") - end, - on_punch = function(pos, node, player, pointed_thing) - on_punch(pos, player) - end, }) + chisel.register_chiselable("jonez:"..styles[i].."_shaft", "jonez:shaft", styles[i] ) minetest.register_node("jonez:"..styles[i].."_shaft", { description = S("Ancient").." "..S(firstToUpper(styles[i])).." "..S("Shaft"), tiles = {"jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_shaft.png"}, is_ground_content = false, groups = {cracky=3}, sounds = default.node_sound_stone_defaults(), - on_construct = function(pos) - save_meta(pos, i, "shaft") - end, - on_punch = function(pos, node, player, pointed_thing) - on_punch(pos, player) - end, }) + chisel.register_chiselable("jonez:"..styles[i].."_base", "jonez:base", styles[i] ) minetest.register_node("jonez:"..styles[i].."_base", { description = S("Ancient").." "..S(firstToUpper(styles[i])).." "..S("Base"), tiles = {"jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_top_bottom.png", "jonez_"..styles[i].."_base.png"}, is_ground_content = false, groups = {cracky=3}, sounds = default.node_sound_stone_defaults(), - on_construct = function(pos) - save_meta(pos, i, "base") - end, - on_punch = function(pos, node, player, pointed_thing) - on_punch(pos, player) - end, }) end