diff --git a/.luacheckrc b/.luacheckrc index 718790b..c89cac7 100755 --- a/.luacheckrc +++ b/.luacheckrc @@ -7,6 +7,9 @@ read_globals = { "default", "stairs", "doors", "xpanes", "xdecor", "xbg", - table = { fields = { "copy" } }, + table = {fields = {"copy"}}, + string = {fields = {"split"}}, "unpack", + "stairsplus", + "mesecon" } diff --git a/depends.txt b/depends.txt index 034f1f7..97096f9 100755 --- a/depends.txt +++ b/depends.txt @@ -8,4 +8,5 @@ stairs xpanes fire? oresplus? -moreblocks? \ No newline at end of file +moreblocks? +mesecons_doors? diff --git a/handlers/animations.lua b/handlers/animations.lua index 6cfb098..6c240b4 100755 --- a/handlers/animations.lua +++ b/handlers/animations.lua @@ -19,24 +19,29 @@ function xdecor.sit(pos, node, clicker, pointed_thing) if default.player_attached[player_name] then pos.y = pos.y - 0.5 clicker:setpos(pos) - clicker:set_eye_offset({x=0, y=0, z=0}, {x=0, y=0, z=0}) - clicker:set_physics_override(1, 1, 1) + clicker:set_eye_offset(vector.new(), vector.new()) + clicker:set_physics_override({speed = 1, jump = 1, gravity = 1}) default.player_attached[player_name] = false default.player_set_animation(clicker, "stand", 30) elseif not default.player_attached[player_name] and node.param2 <= 3 and - not ctrl.sneak and vector.equals(vel, {x=0,y=0,z=0}) then + not ctrl.sneak and vector.equals(vel, vector.new()) then - clicker:set_eye_offset({x=0, y=-7, z=2}, {x=0, y=0, z=0}) - clicker:set_physics_override(0, 0, 0) + clicker:set_eye_offset({x = 0, y = -7, z = 2}, vector.new()) + clicker:set_physics_override({speed = 0, jump = 0, gravity = 1}) clicker:setpos(pos) default.player_attached[player_name] = true default.player_set_animation(clicker, "sit", 30) - if node.param2 == 0 then clicker:set_look_yaw(3.15) - elseif node.param2 == 1 then clicker:set_look_yaw(7.9) - elseif node.param2 == 2 then clicker:set_look_yaw(6.28) - elseif node.param2 == 3 then clicker:set_look_yaw(4.75) end + if node.param2 == 0 then + clicker:set_look_yaw(3.15) + elseif node.param2 == 1 then + clicker:set_look_yaw(7.9) + elseif node.param2 == 2 then + clicker:set_look_yaw(6.28) + elseif node.param2 == 3 then + clicker:set_look_yaw(4.75) + end end end @@ -47,6 +52,7 @@ function xdecor.sit_dig(pos, digger) return false end end + return true end diff --git a/handlers/helpers.lua b/handlers/helpers.lua index 6098c5a..c789b70 100755 --- a/handlers/helpers.lua +++ b/handlers/helpers.lua @@ -2,21 +2,31 @@ function xdecor.maxn(T) local n = 0 for k in pairs(T) do - if k > n then n = k end + if k > n then + n = k + end end + return n end -- Returns the length of an hash table. function xdecor.tablelen(T) local n = 0 - for _ in pairs(T) do n = n + 1 end + + for _ in pairs(T) do + n = n + 1 + end + return n end -- Deep copy of a table. Borrowed from mesecons mod (https://github.com/Jeija/minetest-mod-mesecons). function xdecor.tablecopy(T) - if type(T) ~= "table" then return T end -- No need to copy. + if type(T) ~= "table" then + return T -- No need to copy. + end + local new = {} for k, v in pairs(T) do @@ -26,6 +36,7 @@ function xdecor.tablecopy(T) new[k] = v end end + return new end diff --git a/handlers/nodeboxes.lua b/handlers/nodeboxes.lua index 63da57e..4a3d8ca 100755 --- a/handlers/nodeboxes.lua +++ b/handlers/nodeboxes.lua @@ -1,7 +1,13 @@ xdecor.box = { slab_y = function(height, shift) - return {-0.5, -0.5 + (shift or 0), -0.5, 0.5, -0.5 + height + - (shift or 0), 0.5} + return { + -0.5, + -0.5 + (shift or 0), + -0.5, + 0.5, + -0.5 + height + (shift or 0), + 0.5 + } end, slab_z = function(depth) return {-0.5, -0.5, -0.5 + depth, 0.5, 0.5, 0.5} @@ -15,16 +21,18 @@ xdecor.box = { } xdecor.nodebox = { - regular = {type="regular"}, - null = {type="fixed", fixed={0,0,0,0,0,0}} + regular = {type = "regular"}, + null = { + type = "fixed", fixed = {0,0,0,0,0,0} + } } xdecor.pixelbox = function(size, boxes) local fixed = {} - for _, box in pairs(boxes) do + for _, box in ipairs(boxes) do -- `unpack` has been changed to `table.unpack` in newest Lua versions. local x, y, z, w, h, l = unpack(box) - fixed[#fixed+1] = { + fixed[#fixed + 1] = { (x / size) - 0.5, (y / size) - 0.5, (z / size) - 0.5, @@ -33,26 +41,27 @@ xdecor.pixelbox = function(size, boxes) ((z + l) / size) - 0.5 } end - return {type="fixed", fixed=fixed} + + return {type = "fixed", fixed = fixed} end local mt = {} + mt.__index = function(table, key) local ref = xdecor.box[key] local ref_type = type(ref) if ref_type == "function" then return function(...) - return {type="fixed", fixed=ref(...)} + return {type = "fixed", fixed = ref(...)} end elseif ref_type == "table" then - return {type="fixed", fixed=ref} + return {type = "fixed", fixed = ref} elseif ref_type == "nil" then - error(key.."could not be found among nodebox presets and functions") + error(key .. "could not be found among nodebox presets and functions") end - error("unexpected datatype "..tostring(type(ref)).." while looking for "..key) + error("unexpected datatype " .. tostring(type(ref)) .. " while looking for " .. key) end setmetatable(xdecor.nodebox, mt) - diff --git a/handlers/registration.lua b/handlers/registration.lua index cbeabdb..b16dc4b 100755 --- a/handlers/registration.lua +++ b/handlers/registration.lua @@ -1,4 +1,4 @@ -xbg = default.gui_bg..default.gui_bg_img..default.gui_slots +xbg = default.gui_bg .. default.gui_bg_img .. default.gui_slots local default_inventory_size = 32 local default_inventory_formspecs = { @@ -6,30 +6,30 @@ local default_inventory_formspecs = { list[context;main;0,0;8,1;] list[current_player;main;0,2;8,4;] listring[current_player;main] - listring[context;main] ]] - ..default.get_hotbar_bg(0,2), + listring[context;main] ]] .. + default.get_hotbar_bg(0,2), ["16"] = [[ size[8,7] list[context;main;0,0;8,2;] list[current_player;main;0,3;8,4;] listring[current_player;main] - listring[context;main] ]] - ..default.get_hotbar_bg(0,3), + listring[context;main] ]] .. + default.get_hotbar_bg(0,3), ["24"] = [[ size[8,8] list[context;main;0,0;8,3;] list[current_player;main;0,4;8,4;] listring[current_player;main] - listring[context;main]" ]] - ..default.get_hotbar_bg(0,4), + listring[context;main]" ]] .. + default.get_hotbar_bg(0,4), ["32"] = [[ size[8,9] list[context;main;0,0.3;8,4;] list[current_player;main;0,4.85;8,1;] list[current_player;main;0,6.08;8,3;8] listring[current_player;main] - listring[context;main] ]] - ..default.get_hotbar_bg(0,4.85) + listring[context;main] ]] .. + default.get_hotbar_bg(0,4.85) } local function get_formspec_by_size(size) @@ -42,13 +42,13 @@ local default_can_dig = function(pos) return inv:is_empty("main") end -function xdecor.register(name, def) - local function xdecor_stairs_alternative(nodename, def) +local function xdecor_stairs_alternative(nodename, def) local mod, name = nodename:match("(.*):(.*)") + for groupname, value in pairs(def.groups) do if groupname ~= "cracky" and groupname ~= "choppy" and groupname ~= "flammable" and groupname ~= "crumbly" and - groupname ~= "snappy" then + groupname ~= "snappy" then def.groups.groupname = nil end end @@ -65,17 +65,18 @@ function xdecor.register(name, def) sounds = def.sounds, } ) - elseif minetest.get_modpath("stairs") then + elseif minetest.get_modpath("stairs") then stairs.register_stair_and_slab(name,nodename, def.groups, def.tiles, ("%s Stair"):format(def.description), ("%s Slab"):format(def.description), def.sounds - ) - end + ) + end end +function xdecor.register(name, def) def.drawtype = def.drawtype or (def.mesh and "mesh") or (def.node_box and "nodebox") def.sounds = def.sounds or default.node_sound_defaults() @@ -108,11 +109,14 @@ function xdecor.register(name, def) local size = inventory.size or default_inventory_size local inv = meta:get_inventory() + inv:set_size("main", size) - meta:set_string("formspec", (inventory.formspec or - get_formspec_by_size(size))..xbg) + meta:set_string("formspec", + (inventory.formspec or get_formspec_by_size(size)) .. xbg) end + def.can_dig = def.can_dig or default_can_dig + elseif infotext and not def.on_construct then def.on_construct = function(pos) local meta = minetest.get_meta(pos) @@ -120,12 +124,12 @@ function xdecor.register(name, def) end end - minetest.register_node("xdecor:"..name, def) + minetest.register_node("xdecor:" .. name, def) local workbench = minetest.settings:get_bool("enable_xdecor_workbench") if workbench == false and - (minetest.get_modpath("moreblocks") or minetest.get_modpath("stairs")) then + (minetest.get_modpath("moreblocks") or minetest.get_modpath("stairs")) then if xdecor.stairs_valid_def(def) then xdecor_stairs_alternative("xdecor:"..name, def) end diff --git a/init.lua b/init.lua index 6509446..1399a1c 100755 --- a/init.lua +++ b/init.lua @@ -1,29 +1,15 @@ --local t = os.clock() -local mver_major, mver_minor, mver_patch = 0, 4, 16 -- Minetest 0.4.16 minimum. - -local client_version = minetest.get_version().string -local major, minor, patch = client_version:match("(%d+).(%d+).(%d+)") - -if (major and minor and patch) and - ((tonumber(major) < mver_major) or - (mver_major == tonumber(major) and tonumber(minor) < mver_minor) or - (mver_minor == tonumber(minor) and tonumber(patch) < mver_patch)) then - minetest.log("error", "[xdecor] Your Minetest client is too old to run this mod. Disabling.") - return -end - xdecor = {} local modpath = minetest.get_modpath("xdecor") -dofile(modpath.."/handlers/animations.lua") -dofile(modpath.."/handlers/helpers.lua") -dofile(modpath.."/handlers/nodeboxes.lua") -dofile(modpath.."/handlers/registration.lua") +dofile(modpath .. "/handlers/animations.lua") +dofile(modpath .. "/handlers/helpers.lua") +dofile(modpath .. "/handlers/nodeboxes.lua") +dofile(modpath .. "/handlers/registration.lua") -dofile(modpath.."/src/alias.lua") -dofile(modpath.."/src/nodes.lua") -dofile(modpath.."/src/recipes.lua") +dofile(modpath .. "/src/nodes.lua") +dofile(modpath .. "/src/recipes.lua") local subpart = { "chess", @@ -34,13 +20,13 @@ local subpart = { "mailbox", "mechanisms", "rope", - "workbench" + "workbench", } -for _, name in pairs(subpart) do - local enable = minetest.settings:get_bool("enable_xdecor_"..name) +for _, name in ipairs(subpart) do + local enable = minetest.settings:get_bool("enable_xdecor_" .. name) if enable or enable == nil then - dofile(modpath.."/src/"..name..".lua") + dofile(modpath .. "/src/" .. name .. ".lua") end end diff --git a/src/chess.lua b/src/chess.lua index f037eee..a1364da 100755 --- a/src/chess.lua +++ b/src/chess.lua @@ -2,9 +2,15 @@ local realchess = {} screwdriver = screwdriver or {} local function index_to_xy(idx) + if not idx then + return nil + end + idx = idx - 1 + local x = idx % 8 local y = (idx - x) / 8 + return x, y end @@ -19,14 +25,6 @@ end local chat_prefix = minetest.colorize("#FFFF00", "[Chess] ") local letters = {'A','B','C','D','E','F','G','H'} -local rowDirs = {-1, -1, -1, 0, 0, 1, 1, 1} -local colDirs = {-1, 0, 1, -1, 1, -1, 0, 1} - -local bishopThreats = {true, false, true, false, false, true, false, true} -local rookThreats = {false, true, false, true, true, false, true, false} -local queenThreats = {true, true, true, true, true, true, true, true} -local kingThreats = {true, true, true, true, true, true, true, true} - local function board_to_table(inv) local t = {} for i = 1, 64 do @@ -36,6 +34,431 @@ local function board_to_table(inv) return t end +local piece_values = { + pawn = 10, + knight = 30, + bishop = 30, + rook = 50, + queen = 90, + king = 900 +} + +local function get_possible_moves(board, from_idx) + local piece, color = board[from_idx]:match(":(%w+)_(%w+)") + if not piece then return end + local moves = {} + local from_x, from_y = index_to_xy(from_idx) + + for i = 1, 64 do + local stack_name = board[i] + if stack_name:find((color == "black" and "white" or "black")) or + stack_name == "" then + moves[i] = 0 + end + end + + for to_idx in pairs(moves) do + local pieceTo = board[to_idx] + local to_x, to_y = index_to_xy(to_idx) + + -- PAWN + if piece == "pawn" then + if color == "white" then + local pawnWhiteMove = board[xy_to_index(from_x, from_y - 1)] + -- white pawns can go up only + if from_y - 1 == to_y then + if from_x == to_x then + if pieceTo ~= "" then + moves[to_idx] = nil + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("black") then + moves[to_idx] = nil + end + else + moves[to_idx] = nil + end + elseif from_y - 2 == to_y then + if pieceTo ~= "" or from_y < 6 or pawnWhiteMove ~= "" then + moves[to_idx] = nil + end + else + moves[to_idx] = nil + end + + --[[ + if x not changed + ensure that destination cell is empty + elseif x changed one unit left or right + ensure the pawn is killing opponent piece + else + move is not legal - abort + ]] + + if from_x == to_x then + if pieceTo ~= "" then + moves[to_idx] = nil + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("black") then + moves[to_idx] = nil + end + else + moves[to_idx] = nil + end + + elseif color == "black" then + local pawnBlackMove = board[xy_to_index(from_x, from_y + 1)] + -- black pawns can go down only + if from_y + 1 == to_y then + if from_x == to_x then + if pieceTo ~= "" then + moves[to_idx] = nil + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("white") then + moves[to_idx] = nil + end + else + moves[to_idx] = nil + end + elseif from_y + 2 == to_y then + if pieceTo ~= "" or from_y > 1 or pawnBlackMove ~= "" then + moves[to_idx] = nil + end + else + moves[to_idx] = nil + end + + --[[ + if x not changed + ensure that destination cell is empty + elseif x changed one unit left or right + ensure the pawn is killing opponent piece + else + move is not legal - abort + ]] + + if from_x == to_x then + if pieceTo ~= "" then + moves[to_idx] = nil + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("white") then + moves[to_idx] = nil + end + else + moves[to_idx] = nil + end + else + moves[to_idx] = nil + end + + -- ROOK + elseif piece == "rook" then + if from_x == to_x then + -- Moving vertically + if from_y < to_y then + -- Moving down + -- Ensure that no piece disturbs the way + for i = from_y + 1, to_y - 1 do + if board[xy_to_index(from_x, i)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Mocing up + -- Ensure that no piece disturbs the way + for i = to_y + 1, from_y - 1 do + if board[xy_to_index(from_x, i)] ~= "" then + moves[to_idx] = nil + end + end + end + elseif from_y == to_y then + -- Mocing horizontally + if from_x < to_x then + -- mocing right + -- ensure that no piece disturbs the way + for i = from_x + 1, to_x - 1 do + if board[xy_to_index(i, from_y)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Mocing left + -- Ensure that no piece disturbs the way + for i = to_x + 1, from_x - 1 do + if board[xy_to_index(i, from_y)] ~= "" then + moves[to_idx] = nil + end + end + end + else + -- Attempt to move arbitrarily -> abort + moves[to_idx] = nil + end + + -- KNIGHT + elseif piece == "knight" then + -- Get relative pos + local dx = from_x - to_x + local dy = from_y - to_y + + -- Get absolute values + if dx < 0 then + dx = -dx + end + + if dy < 0 then + dy = -dy + end + + -- Sort x and y + if dx > dy then + dx, dy = dy, dx + end + + -- Ensure that dx == 1 and dy == 2 + if dx ~= 1 or dy ~= 2 then + moves[to_idx] = nil + end + -- Just ensure that destination cell does not contain friend piece + -- ^ It was done already thus everything ok + + -- BISHOP + elseif piece == "bishop" then + -- Get relative pos + local dx = from_x - to_x + local dy = from_y - to_y + + -- Get absolute values + if dx < 0 then + dx = -dx + end + + if dy < 0 then + dy = -dy + end + + -- Ensure dx and dy are equal + if dx ~= dy then + moves[to_idx] = nil + end + + if from_x < to_x then + if from_y < to_y then + -- Moving right-down + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x + i, from_y + i)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Moving right-up + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x + i, from_y - i)] ~= "" then + moves[to_idx] = nil + end + end + end + else + if from_y < to_y then + -- Moving left-down + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x - i, from_y + i)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Moving left-up + -- ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x - i, from_y - i)] ~= "" then + moves[to_idx] = nil + end + end + end + end + + -- QUEEN + elseif piece == "queen" then + local dx = from_x - to_x + local dy = from_y - to_y + + -- Get absolute values + if dx < 0 then + dx = -dx + end + + if dy < 0 then + dy = -dy + end + + -- Ensure valid relative move + if dx ~= 0 and dy ~= 0 and dx ~= dy then + moves[to_idx] = nil + end + + if from_x == to_x then + -- Moving vertically + if from_y < to_y then + -- Moving down + -- Ensure that no piece disturbs the way + for i = from_y + 1, to_y - 1 do + if board[xy_to_index(from_x, i)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Mocing up + -- Ensure that no piece disturbs the way + for i = to_y + 1, from_y - 1 do + if board[xy_to_index(from_x, i)] ~= "" then + moves[to_idx] = nil + end + end + end + elseif from_x < to_x then + if from_y == to_y then + -- Goes right + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x + i, from_y)] ~= "" then + moves[to_idx] = nil + end + end + elseif from_y < to_y then + -- Goes right-down + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x + i, from_y + i)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Goes right-up + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x + i, from_y - i)] ~= "" then + moves[to_idx] = nil + end + end + end + else + if from_y == to_y then + -- Mocing horizontally + if from_x < to_x then + -- mocing right + -- ensure that no piece disturbs the way + for i = from_x + 1, to_x - 1 do + if board[xy_to_index(i, from_y)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Mocing left + -- Ensure that no piece disturbs the way + for i = to_x + 1, from_x - 1 do + if board[xy_to_index(i, from_y)] ~= "" then + moves[to_idx] = nil + end + end + end + elseif from_y < to_y then + -- Goes left-down + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x - i, from_y + i)] ~= "" then + moves[to_idx] = nil + end + end + else + -- Goes left-up + -- Ensure that no piece disturbs the way + for i = 1, dx - 1 do + if board[xy_to_index(from_x - i, from_y - i)] ~= "" then + moves[to_idx] = nil + end + end + end + end + + -- KING + elseif piece == "king" then + local dx = from_x - to_x + local dy = from_y - to_y + + if dx < 0 then + dx = -dx + end + + if dy < 0 then + dy = -dy + end + + if dx > 1 or dy > 1 then + moves[to_idx] = nil + end + end + end + + if not next(moves) then return end + + for i in pairs(moves) do + local stack_name = board[tonumber(i)] + if stack_name ~= "" then + for p, value in pairs(piece_values) do + if stack_name:find(p) then + moves[i] = value + end + end + end + end + + return moves +end + +local function best_move(moves) + local value, choices = 0, {} + + for from, _ in pairs(moves) do + for to, val in pairs(_) do + if val > value then + value = val + choices = {{ + from = from, + to = to + }} + elseif val == value then + choices[#choices + 1] = { + from = from, + to = to + } + end + end + end + + local random = math.random(1, #choices) + local choice_from, choice_to = choices[random].from, choices[random].to + + return tonumber(choice_from), choice_to +end + +local rowDirs = {-1, -1, -1, 0, 0, 1, 1, 1} +local colDirs = {-1, 0, 1, -1, 1, -1, 0, 1} + +local rowDirsKnight = { 2, 1, 2, 1, -2, -1, -2, -1} +local colDirsKnight = {-1, -2, 1, 2, 1, 2, -1, -2} + +local bishopThreats = {true, false, true, false, false, true, false, true} +local rookThreats = {false, true, false, true, true, false, true, false} +local queenThreats = {true, true, true, true, true, true, true, true} +local kingThreats = {true, true, true, true, true, true, true, true} + local function attacked(color, idx, board) local threatDetected = false local kill = color == "white" @@ -78,6 +501,21 @@ local function attacked(color, idx, board) end end end + + local colK, rowK = index_to_xy(idx) + colK, rowK = colK + 1, rowK + 1 + rowK = rowK + rowDirsKnight[dir] + colK = colK + colDirsKnight[dir] + + if rowK >= 1 and rowK <= 8 and colK >= 1 and colK <= 8 then + local square = get_square(rowK, colK) + local square_name = board[square] + local piece, pieceColor = square_name:match(":(%w+)_(%w+)") + + if piece and pieceColor ~= color and piece == "knight" then + threatDetected = true + end + end end end @@ -147,6 +585,14 @@ for i = 1, #pieces do end pieces_str = pieces_str .. "69=mailbox_blank16.png" +local fs_init = [[ + size[4,1.2;] + no_prepend[] + label[0,0;Select a mode:] + button[0,0.5;2,1;single;Singleplayer] + button[2,0.5;2,1;multi;Multiplayer] +]] + local fs = [[ size[14.7,10;] no_prepend[] @@ -159,7 +605,34 @@ local fs = [[ ]] .. "tablecolumns[image," .. pieces_str .. ";text;color;text;color;text;image," .. pieces_str .. "]" -local function get_moves_list(meta, pieceFrom, pieceTo, pieceTo_s, from_x, to_x, from_y, to_y) +local function update_formspec(meta) + local black_king_attacked = meta:get_string("blackAttacked") == "true" + local white_king_attacked = meta:get_string("whiteAttacked") == "true" + + local playerWhite = meta:get_string("playerWhite") + local playerBlack = meta:get_string("playerBlack") + + local moves = meta:get_string("moves") + local eaten_img = meta:get_string("eaten_img") + local lastMove = meta:get_string("lastMove") + local turnBlack = minetest.colorize("#000001", (lastMove == "white" and playerBlack ~= "") and + playerBlack .. "..." or playerBlack) + local turnWhite = minetest.colorize("#000001", (lastMove == "black" and playerWhite ~= "") and + playerWhite .. "..." or playerWhite) + local check_s = minetest.colorize("#FF0000", "\\[check\\]") + + local formspec = fs .. + "label[1.9,0.3;" .. turnBlack .. (black_king_attacked and " " .. check_s or "") .. "]" .. + "label[1.9,9.15;" .. turnWhite .. (white_king_attacked and " " .. check_s or "") .. "]" .. + "table[8.9,1.05;5.07,3.75;moves;" .. moves:sub(1,-2) .. ";1]" .. + eaten_img + + meta:set_string("formspec", formspec) +end + +local function get_moves_list(meta, pieceFrom, pieceTo, pieceTo_s, from_idx, to_idx) + local from_x, from_y = index_to_xy(from_idx) + local to_x, to_y = index_to_xy(to_idx) local moves = meta:get_string("moves") local pieceFrom_s = pieceFrom:match(":(%w+_%w+)") local pieceFrom_si_id = pieces_str:match("(%d+)=" .. pieceFrom_s) @@ -202,7 +675,7 @@ local function get_eaten_list(meta, pieceTo, pieceTo_s) end eaten_img = eaten_img .. - "image[" .. ((X + (is_white and 11.7 or 8.8)) - (X * 0.45)) .. "," .. + "image[" .. ((X + (is_white and 11.67 or 8.8)) - (X * 0.45)) .. "," .. ((Y + 5.56) - (Y * 0.2)) .. ";1,1;" .. eaten_t[i] .. ".png]" end @@ -213,7 +686,7 @@ function realchess.init(pos) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - meta:set_string("formspec", fs) + meta:set_string("formspec", fs_init) meta:set_string("infotext", "Chess Board") meta:set_string("playerBlack", "") meta:set_string("playerWhite", "") @@ -229,6 +702,7 @@ function realchess.init(pos) meta:set_string("moves", "") meta:set_string("eaten", "") + meta:set_string("mode", "") inv:set_list("board", pieces) inv:set_size("board", 64) @@ -483,7 +957,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Moving right-down -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then return 0 end end @@ -491,7 +966,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Moving right-up -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then return 0 end end @@ -501,7 +977,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Moving left-down -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then return 0 end end @@ -509,7 +986,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Moving left-up -- ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then return 0 end end @@ -535,7 +1013,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes down -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x, from_y + i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x, from_y + i)):get_name() ~= "" then return 0 end end @@ -543,7 +1022,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes up -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x, from_y - i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x, from_y - i)):get_name() ~= "" then return 0 end end @@ -553,7 +1033,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes right -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x + i, from_y)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x + i, from_y)):get_name() ~= "" then return 0 end end @@ -561,7 +1042,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes right-down -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then return 0 end end @@ -569,7 +1051,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes right-up -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x + i, from_y - i)):get_name() ~= "" then return 0 end end @@ -579,7 +1062,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes left -- Ensure that no piece disturbs the way and destination cell does for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x - i, from_y)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x - i, from_y)):get_name() ~= "" then return 0 end end @@ -587,7 +1071,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes left-down -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then return 0 end end @@ -595,7 +1080,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player -- Goes left-up -- Ensure that no piece disturbs the way for i = 1, dx - 1 do - if inv:get_stack(from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then + if inv:get_stack( + from_list, xy_to_index(from_x - i, from_y - i)):get_name() ~= "" then return 0 end end @@ -620,6 +1106,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player return 0 end end + inv:set_stack(from_list, 57, "") inv:set_stack(from_list, 59, "realchess:rook_white_1") check = false @@ -634,6 +1121,7 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player return 0 end end + inv:set_stack(from_list, 62, "realchess:rook_white_2") inv:set_stack(from_list, 64, "") check = false @@ -705,11 +1193,15 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player board[from_index] = "" local black_king_idx, white_king_idx = locate_kings(board) + if not black_king_idx or not white_king_idx then + return 0 + end local blackAttacked = attacked("black", black_king_idx, board) local whiteAttacked = attacked("white", white_king_idx, board) if blackAttacked then - if thisMove == "black" and meta:get_string("blackAttacked") == "true" then + if thisMove == "black" then + --[(*)[ and meta:get_string("blackAttacked") == "true" ]] then return 0 else meta:set_string("blackAttacked", "true") @@ -719,7 +1211,8 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player end if whiteAttacked then - if thisMove == "white" and meta:get_string("whiteAttacked") == "true" then + if thisMove == "white" then + --[(*)[ and meta:get_string("whiteAttacked") == "true" ]] then return 0 else meta:set_string("whiteAttacked", "true") @@ -728,47 +1221,139 @@ function realchess.move(pos, from_list, from_index, to_list, to_index, _, player meta:set_string("whiteAttacked", "") end - lastMove = thisMove + --(*) Allow a piece to move and put its king in check. Maybe not in the chess rules though? + lastMove = thisMove meta:set_string("lastMove", lastMove) meta:set_int("lastMoveTime", minetest.get_gametime()) - meta:set_string("playerWhite", playerWhite) - meta:set_string("playerBlack", playerBlack) + + if meta:get_string("playerWhite") == "" then + meta:set_string("playerWhite", playerWhite) + elseif meta:get_string("playerBlack") == "" then + meta:set_string("playerBlack", playerBlack) + end local pieceTo_s = pieceTo ~= "" and pieceTo:match(":(%w+_%w+)") or "" - get_moves_list(meta, pieceFrom, pieceTo, pieceTo_s, from_x, to_x, from_y, to_y) + get_moves_list(meta, pieceFrom, pieceTo, pieceTo_s, from_index, to_index) get_eaten_list(meta, pieceTo, pieceTo_s) return 1 end +local function ai_move(inv, meta) + local board_t = board_to_table(inv) + local lastMove = meta:get_string("lastMove") + + if lastMove == "white" then + update_formspec(meta) + local moves = {} + + for i = 1, 64 do + local possibleMoves = get_possible_moves(board_t, i) + local stack_name = inv:get_stack("board", i):get_name() + + if stack_name:find("black") then + moves[tostring(i)] = possibleMoves + end + end + + local choice_from, choice_to = best_move(moves) + + local pieceFrom = inv:get_stack("board", choice_from):get_name() + local pieceTo = inv:get_stack("board", choice_to):get_name() + local pieceTo_s = pieceTo ~= "" and pieceTo:match(":(%w+_%w+)") or "" + + local board = board_to_table(inv) + local black_king_idx = locate_kings(board) + local blackAttacked = attacked("black", black_king_idx, board) + local kingSafe = true + local bestMoveSaveFrom, bestMoveSaveTo + + if blackAttacked then + kingSafe = false + meta:set_string("blackAttacked", "true") + local save_moves = {} + + for from_idx, _ in pairs(moves) do + for to_idx, value in pairs(_) do + from_idx = tonumber(from_idx) + local from_idx_bak, to_idx_bak = board[from_idx], board[to_idx] + board[to_idx] = board[from_idx] + board[from_idx] = "" + black_king_idx = locate_kings(board) + + if black_king_idx then + blackAttacked = attacked("black", black_king_idx, board) + if not blackAttacked then + save_moves[from_idx] = save_moves[from_idx] or {} + save_moves[from_idx][to_idx] = value + end + end + + board[from_idx], board[to_idx] = from_idx_bak, to_idx_bak + end + end + + if next(save_moves) then + bestMoveSaveFrom, bestMoveSaveTo = best_move(save_moves) + end + end + + minetest.after(1.0, function() + local lastMoveTime = meta:get_int("lastMoveTime") + if lastMoveTime > 0 then + if not kingSafe then + if bestMoveSaveTo then + inv:set_stack("board", bestMoveSaveTo, board[bestMoveSaveFrom]) + inv:set_stack("board", bestMoveSaveFrom, "") + meta:set_string("blackAttacked", "") + else + return + end + else + if pieceFrom:find("pawn") and choice_to >= 57 and choice_to <= 64 then + inv:set_stack("board", choice_to, "realchess:queen_black") + else + inv:set_stack("board", choice_to, pieceFrom) + end + + inv:set_stack("board", choice_from, "") + end + + board = board_to_table(inv) + local _, white_king_idx = locate_kings(board) + local whiteAttacked = attacked("white", white_king_idx, board) + + if whiteAttacked then + meta:set_string("whiteAttacked", "true") + end + + if meta:get_string("playerBlack") == "" then + meta:set_string("playerBlack", "Dumb AI") + end + + meta:set_string("lastMove", "black") + meta:set_int("lastMoveTime", minetest.get_gametime()) + + get_moves_list(meta, pieceFrom, pieceTo, pieceTo_s, choice_from, choice_to) + get_eaten_list(meta, pieceTo, pieceTo_s) + + update_formspec(meta) + end + end) + else + update_formspec(meta) + end +end + function realchess.on_move(pos, from_list, from_index) local meta = minetest.get_meta(pos) local inv = meta:get_inventory() - inv:set_stack(from_list, from_index, '') + inv:set_stack(from_list, from_index, "") - local black_king_attacked = meta:get_string("blackAttacked") == "true" - local white_king_attacked = meta:get_string("whiteAttacked") == "true" - - local playerWhite = meta:get_string("playerWhite") - local playerBlack = meta:get_string("playerBlack") - - local moves = meta:get_string("moves") - local eaten_img = meta:get_string("eaten_img") - local lastMove = meta:get_string("lastMove") - local turnBlack = minetest.colorize("#000001", (lastMove == "white" and playerBlack ~= "") and - playerBlack .. "..." or playerBlack) - local turnWhite = minetest.colorize("#000001", (lastMove == "black" and playerWhite ~= "") and - playerWhite .. "..." or playerWhite) - local check_s = minetest.colorize("#FF0000", "\\[check\\]") - - local formspec = fs .. - "label[1.9,0.3;" .. turnBlack .. (black_king_attacked and " " .. check_s or "") .. "]" .. - "label[1.9,9.15;" .. turnWhite .. (white_king_attacked and " " .. check_s or "") .. "]" .. - "table[8.9,1.05;5.07,3.75;moves;" .. moves:sub(1,-2) .. ";1]" .. - eaten_img - - meta:set_string("formspec", formspec) + if meta:get_string("mode") == "single" then + ai_move(inv, meta) + end return false end @@ -794,12 +1379,18 @@ function realchess.fields(pos, _, fields, sender) local lastMoveTime = meta:get_int("lastMoveTime") if fields.quit then return end + if fields.single or fields.multi then + meta:set_string("mode", (fields.single and "single" or "multi")) + update_formspec(meta) + return + end + -- Timeout is 5 min. by default for resetting the game (non-players only) if fields.new then if (playerWhite == playerName or playerBlack == playerName) then realchess.init(pos) - elseif lastMoveTime ~= 0 then + elseif lastMoveTime > 0 then if minetest.get_gametime() >= timeout_limit and (playerWhite ~= playerName or playerBlack ~= playerName) then realchess.init(pos) diff --git a/src/cooking.lua b/src/cooking.lua index 8cc2d38..ec5d11e 100755 --- a/src/cooking.lua +++ b/src/cooking.lua @@ -17,7 +17,9 @@ cauldron.cbox = { function cauldron.stop_sound(pos) local spos = minetest.hash_node_position(pos) - if sounds[spos] then minetest.sound_stop(sounds[spos]) end + if sounds[spos] then + minetest.sound_stop(sounds[spos]) + end end function cauldron.idle_construct(pos) @@ -29,7 +31,10 @@ end function cauldron.boiling_construct(pos) local spos = minetest.hash_node_position(pos) sounds[spos] = minetest.sound_play("xdecor_boiling_water", { - pos=pos, max_hear_distance=5, gain=0.8, loop=true + pos = pos, + max_hear_distance = 5, + gain = 0.8, + loop = true }) local meta = minetest.get_meta(pos) @@ -57,23 +62,25 @@ function cauldron.filling(pos, node, clicker, itemstack) else itemstack:replace("bucket:bucket_water") end - minetest.set_node(pos, {name="xdecor:cauldron_empty", param2=node.param2}) + minetest.set_node(pos, {name = "xdecor:cauldron_empty", param2 = node.param2}) + elseif wield_item:sub(-6) == "_water" and node.name:sub(-6) == "_empty" then - minetest.set_node(pos, {name="xdecor:cauldron_idle", param2=node.param2}) + minetest.set_node(pos, {name = "xdecor:cauldron_idle", param2 = node.param2}) itemstack:replace("bucket:bucket_empty") end + return itemstack end end function cauldron.idle_timer(pos) - local below_node = {x=pos.x, y=pos.y-1, z=pos.z} + local below_node = {x = pos.x, y = pos.y - 1, z = pos.z} if not minetest.get_node(below_node).name:find("fire") then return true end local node = minetest.get_node(pos) - minetest.set_node(pos, {name="xdecor:cauldron_boiling", param2=node.param2}) + minetest.set_node(pos, {name = "xdecor:cauldron_boiling", param2 = node.param2}) return true end @@ -82,13 +89,17 @@ local function eatable(itemstring) local item = itemstring:match("[%w_:]+") local on_use_def = minetest.registered_items[item].on_use if not on_use_def then return end + return string.format("%q", string.dump(on_use_def)):find("item_eat") end function cauldron.boiling_timer(pos) local node = minetest.get_node(pos) local objs = minetest.get_objects_inside_radius(pos, 0.5) - if not next(objs) then return true end + + if not next(objs) then + return true + end local ingredients = {} for _, obj in pairs(objs) do @@ -96,31 +107,38 @@ function cauldron.boiling_timer(pos) local itemstring = obj:get_luaentity().itemstring local food = itemstring:match(":([%w_]+)") - for _, ingredient in pairs(ingredients_list) do + for _, ingredient in ipairs(ingredients_list) do if food and (eatable(itemstring) or food:find(ingredient)) then - ingredients[#ingredients+1] = food break + ingredients[#ingredients + 1] = food + break end end end end if #ingredients >= 2 then - for _, obj in pairs(objs) do obj:remove() end - minetest.set_node(pos, {name="xdecor:cauldron_soup", param2=node.param2}) + for _, obj in pairs(objs) do + obj:remove() + end + + minetest.set_node(pos, {name = "xdecor:cauldron_soup", param2 = node.param2}) end - local node_under = {x=pos.x, y=pos.y-1, z=pos.z} + local node_under = {x = pos.x, y = pos.y - 1, z = pos.z} + if not minetest.get_node(node_under).name:find("fire") then - minetest.set_node(pos, {name="xdecor:cauldron_idle", param2=node.param2}) + minetest.set_node(pos, {name = "xdecor:cauldron_idle", param2 = node.param2}) end + return true end function cauldron.take_soup(pos, node, clicker, itemstack) local inv = clicker:get_inventory() local wield_item = clicker:get_wielded_item() + local item_name = wield_item:get_name() - if wield_item:get_name() == "xdecor:bowl" then + if item_name == "xdecor:bowl" or item_name == "farming:bowl" then if wield_item:get_count() > 1 then if inv:room_for_item("main", "xdecor:bowl_soup 1") then itemstack:take_item() @@ -134,8 +152,9 @@ function cauldron.take_soup(pos, node, clicker, itemstack) itemstack:replace("xdecor:bowl_soup 1") end - minetest.set_node(pos, {name="xdecor:cauldron_empty", param2=node.param2}) + minetest.set_node(pos, {name = "xdecor:cauldron_empty", param2 = node.param2}) end + return itemstack end @@ -145,11 +164,11 @@ xdecor.register("cauldron_empty", { on_rotate = screwdriver.rotate_simple, tiles = {"xdecor_cauldron_top_empty.png", "xdecor_cauldron_sides.png"}, infotext = "Cauldron (empty)", + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.filling, on_construct = function(pos) cauldron.stop_sound(pos) end, - on_rightclick = cauldron.filling, - collision_box = xdecor.pixelbox(16, cauldron.cbox) }) xdecor.register("cauldron_idle", { @@ -161,7 +180,7 @@ xdecor.register("cauldron_idle", { collision_box = xdecor.pixelbox(16, cauldron.cbox), on_rightclick = cauldron.filling, on_construct = cauldron.idle_construct, - on_timer = cauldron.idle_timer + on_timer = cauldron.idle_timer, }) xdecor.register("cauldron_boiling", { @@ -170,32 +189,40 @@ xdecor.register("cauldron_boiling", { drop = "xdecor:cauldron_empty", infotext = "Cauldron (active) - Drop foods inside to make a soup", damage_per_second = 2, - tiles = {{name="xdecor_cauldron_top_anim_boiling_water.png", - animation={type="vertical_frames", length=3.0}}, - "xdecor_cauldron_sides.png"}, + tiles = { + { + name = "xdecor_cauldron_top_anim_boiling_water.png", + animation = {type = "vertical_frames", length = 3.0} + }, + "xdecor_cauldron_sides.png" + }, collision_box = xdecor.pixelbox(16, cauldron.cbox), on_rightclick = cauldron.filling, on_construct = cauldron.boiling_construct, + on_timer = cauldron.boiling_timer, on_destruct = function(pos) cauldron.stop_sound(pos) end, - on_timer = cauldron.boiling_timer }) xdecor.register("cauldron_soup", { - groups = {cracky=2, oddly_breakable_by_hand=1, not_in_creative_inventory=1}, + groups = {cracky = 2, oddly_breakable_by_hand = 1, not_in_creative_inventory = 1}, on_rotate = screwdriver.rotate_simple, drop = "xdecor:cauldron_empty", infotext = "Cauldron (active) - Use a bowl to eat the soup", damage_per_second = 2, - tiles = {{name="xdecor_cauldron_top_anim_soup.png", - animation={type="vertical_frames", length=3.0}}, - "xdecor_cauldron_sides.png"}, + tiles = { + { + name = "xdecor_cauldron_top_anim_soup.png", + animation = {type = "vertical_frames", length = 3.0} + }, + "xdecor_cauldron_sides.png" + }, collision_box = xdecor.pixelbox(16, cauldron.cbox), on_rightclick = cauldron.take_soup, on_destruct = function(pos) cauldron.stop_sound(pos) - end + end, }) -- Craft items diff --git a/src/enchanting.lua b/src/enchanting.lua index e332384..b731f61 100755 --- a/src/enchanting.lua +++ b/src/enchanting.lua @@ -1,5 +1,6 @@ screwdriver = screwdriver or {} local ceil, abs, random = math.ceil, math.abs, math.random +local reg_tools = minetest.registered_tools -- Cost in Mese crystal(s) for enchanting. local mese_cost = 1 @@ -11,13 +12,17 @@ local enchanting = { damages = 1, -- Sharpness } -local function cap(S) return S:gsub("^%l", string.upper) end +local function cap(S) return + S:gsub("^%l", string.upper) +end + local function to_percent(orig_value, final_value) return abs(ceil(((final_value - orig_value) / orig_value) * 100)) end function enchanting:get_tooltip(enchant, orig_caps, fleshy) - local bonus = {durable=0, efficiency=0, damages=0} + local bonus = {durable = 0, efficiency = 0, damages = 0} + if orig_caps then bonus.durable = to_percent(orig_caps.uses, orig_caps.uses * enchanting.uses) local sum_caps_times = 0 @@ -28,23 +33,25 @@ function enchanting:get_tooltip(enchant, orig_caps, fleshy) bonus.efficiency = to_percent(average_caps_time, average_caps_time - enchanting.times) end + if fleshy then bonus.damages = to_percent(fleshy, fleshy + enchanting.damages) end local specs = { -- not finished, to complete - durable = {"#00baff", " (+"..bonus.durable.."%)"}, - fast = {"#74ff49", " (+"..bonus.efficiency.."%)"}, - sharp = {"#ffff00", " (+"..bonus.damages.."%)"}, + durable = {"#00baff", " (+" .. bonus.durable .. "%)"}, + fast = {"#74ff49", " (+" .. bonus.efficiency .. "%)"}, + sharp = {"#ffff00", " (+" .. bonus.damages .. "%)"}, } + return minetest.colorize and minetest.colorize(specs[enchant][1], - "\n"..cap(enchant)..specs[enchant][2]) or - "\n"..cap(enchant)..specs[enchant][2] + "\n" .. cap(enchant) .. specs[enchant][2]) or + "\n" .. cap(enchant) .. specs[enchant][2] end local enchant_buttons = { - [[ image_button[3.9,0.85;4,0.92;bg_btn.png;fast;Efficiency] - image_button[3.9,1.77;4,1.12;bg_btn.png;durable;Durability] ]], + "image_button[3.9,0.85;4,0.92;bg_btn.png;fast;Efficiency]" .. + "image_button[3.9,1.77;4,1.12;bg_btn.png;durable;Durability]", "image_button[3.9,2.9;4,0.92;bg_btn.png;sharp;Sharpness]", } @@ -63,10 +70,10 @@ function enchanting.formspec(pos, num) image[2,2.9;1,1;mese_layout.png] tooltip[sharp;Your weapon inflicts more damages] tooltip[durable;Your tool last longer] - tooltip[fast;Your tool digs faster] ]] - ..default.gui_slots..default.get_hotbar_bg(0.5,4.5) + tooltip[fast;Your tool digs faster] ]] .. + default.gui_slots .. default.get_hotbar_bg(0.5,4.5) - formspec = formspec..(enchant_buttons[num] or "") + formspec = formspec .. (enchant_buttons[num] or "") meta:set_string("formspec", formspec) end @@ -78,7 +85,7 @@ function enchanting.on_put(pos, listname, _, stack) "sword", } - for idx, tools in pairs(tool_groups) do + for idx, tools in ipairs(tool_groups) do if tools:find(stackname:match(":(%w+)")) then enchanting.formspec(pos, idx) end @@ -93,11 +100,14 @@ function enchanting.fields(pos, _, fields, sender) local mese = inv:get_stack("mese", 1) local orig_wear = tool:get_wear() local mod, name = tool:get_name():match("(.*):(.*)") - local enchanted_tool = (mod or "")..":enchanted_"..(name or "").."_"..next(fields) + local enchanted_tool = (mod or "") .. ":enchanted_" .. (name or "") .. "_" .. next(fields) - if mese:get_count() >= mese_cost and minetest.registered_tools[enchanted_tool] then + if mese:get_count() >= mese_cost and reg_tools[enchanted_tool] then minetest.sound_play("xdecor_enchanting", { - to_player=sender:get_player_name(), gain=0.8}) + to_player = sender:get_player_name(), + gain = 0.8 + }) + tool:replace(enchanted_tool) tool:add_wear(orig_wear) mese:take_item(mese_cost) @@ -112,11 +122,13 @@ function enchanting.dig(pos) end local function allowed(tool) - if not tool then return false end - for item in pairs(minetest.registered_tools) do - if item:find("enchanted_"..tool) then return true end + if not tool then return end + + for item in pairs(reg_tools) do + if item:find("enchanted_" .. tool) then + return true + end end - return false end function enchanting.put(_, listname, _, stack) @@ -126,23 +138,26 @@ function enchanting.put(_, listname, _, stack) elseif listname == "tool" and allowed(stackname:match("[^:]+$")) then return 1 end + return 0 end function enchanting.on_take(pos, listname) - if listname == "tool" then enchanting.formspec(pos, nil) end + if listname == "tool" then + enchanting.formspec(pos) + end end function enchanting.construct(pos) local meta = minetest.get_meta(pos) meta:set_string("infotext", "Enchantment Table") - enchanting.formspec(pos, nil) + enchanting.formspec(pos) local inv = meta:get_inventory() inv:set_size("tool", 1) inv:set_size("mese", 1) - minetest.add_entity({x=pos.x, y=pos.y+0.85, z=pos.z}, "xdecor:book_open") + minetest.add_entity({x = pos.x, y = pos.y + 0.85, z = pos.z}, "xdecor:book_open") local timer = minetest.get_node_timer(pos) timer:start(0.5) end @@ -160,39 +175,45 @@ end function enchanting.timer(pos) local num = #minetest.get_objects_inside_radius(pos, 0.9) if num == 0 then - minetest.add_entity({x=pos.x, y=pos.y+0.85, z=pos.z}, "xdecor:book_open") + minetest.add_entity({x = pos.x, y = pos.y + 0.85, z = pos.z}, "xdecor:book_open") end - local minp = {x=pos.x-2, y=pos.y, z=pos.z-2} - local maxp = {x=pos.x+2, y=pos.y+1, z=pos.z+2} + local minp = {x = pos.x - 2, y = pos.y, z = pos.z - 2} + local maxp = {x = pos.x + 2, y = pos.y + 1, z = pos.z + 2} + local bookshelves = minetest.find_nodes_in_area(minp, maxp, "default:bookshelf") - if #bookshelves == 0 then return true end + if #bookshelves == 0 then + return true + end local bookshelf_pos = bookshelves[random(1, #bookshelves)] local x = pos.x - bookshelf_pos.x local y = bookshelf_pos.y - pos.y local z = pos.z - bookshelf_pos.z - if tostring(x..z):find(2) then + if tostring(x .. z):find(2) then minetest.add_particle({ pos = bookshelf_pos, - velocity = {x=x, y=2-y, z=z}, - acceleration = {x=0, y=-2.2, z=0}, + velocity = {x = x, y = 2 - y, z = z}, + acceleration = {x = 0, y = -2.2, z = 0}, expirationtime = 1, size = 1.5, glow = 5, - texture = "xdecor_glyph"..random(1,18)..".png" + texture = "xdecor_glyph" .. random(1,18) .. ".png" }) end + return true end xdecor.register("enchantment_table", { description = "Enchantment Table", - tiles = {"xdecor_enchantment_top.png", "xdecor_enchantment_bottom.png", - "xdecor_enchantment_side.png", "xdecor_enchantment_side.png", - "xdecor_enchantment_side.png", "xdecor_enchantment_side.png"}, - groups = {cracky=1, level=1}, + tiles = { + "xdecor_enchantment_top.png", "xdecor_enchantment_bottom.png", + "xdecor_enchantment_side.png", "xdecor_enchantment_side.png", + "xdecor_enchantment_side.png", "xdecor_enchantment_side.png" + }, + groups = {cracky = 1, level = 1}, light_source = 6, sounds = default.node_sound_stone_defaults(), on_rotate = screwdriver.rotate_simple, @@ -204,7 +225,9 @@ xdecor.register("enchantment_table", { on_metadata_inventory_put = enchanting.on_put, on_metadata_inventory_take = enchanting.on_take, allow_metadata_inventory_put = enchanting.put, - allow_metadata_inventory_move = function() return 0 end + allow_metadata_inventory_move = function() + return 0 + end, }) minetest.register_entity("xdecor:book_open", { @@ -215,7 +238,7 @@ minetest.register_entity("xdecor:book_open", { textures = {"xdecor_book_open.png"}, on_activate = function(self) local pos = self.object:getpos() - local pos_under = {x=pos.x, y=pos.y-1, z=pos.z} + local pos_under = {x = pos.x, y = pos.y - 1, z = pos.z} if minetest.get_node(pos_under).name ~= "xdecor:enchantment_table" then self.object:remove() @@ -227,7 +250,7 @@ function enchanting:register_tools(mod, def) for tool in pairs(def.tools) do for material in def.materials:gmatch("[%w_]+") do for enchant in def.tools[tool].enchants:gmatch("[%w_]+") do - local original_tool = minetest.registered_tools[mod..":"..tool.."_"..material] + local original_tool = reg_tools[mod .. ":" .. tool .. "_" .. material] if not original_tool then break end local original_toolcaps = original_tool.tool_capabilities @@ -251,12 +274,12 @@ function enchanting:register_tools(mod, def) fleshy = fleshy + enchanting.damages end - minetest.register_tool(":"..mod..":enchanted_"..tool.."_"..material.."_"..enchant, { - description = "Enchanted "..cap(material).." "..cap(tool).. + minetest.register_tool(":" .. mod .. ":enchanted_" .. tool .. "_" .. material .. "_" .. enchant, { + description = "Enchanted " .. cap(material) .. " " .. cap(tool) .. self:get_tooltip(enchant, original_groupcaps[group], fleshy), - inventory_image = original_tool.inventory_image.."^[colorize:violet:50", + inventory_image = original_tool.inventory_image .. "^[colorize:violet:50", wield_image = original_tool.wield_image, - groups = {not_in_creative_inventory=1}, + groups = {not_in_creative_inventory = 1}, tool_capabilities = { groupcaps = groupcaps, damage_groups = {fleshy = fleshy}, full_punch_interval = full_punch_interval, diff --git a/src/hive.lua b/src/hive.lua index a162d42..ae3c3b2 100755 --- a/src/hive.lua +++ b/src/hive.lua @@ -12,8 +12,8 @@ function hive.construct(pos) list[context;honey;5,0;1,1;] list[current_player;main;0,1.35;8,4;] listring[current_player;main] - listring[context;honey] ]] - ..xbg..default.get_hotbar_bg(0,1.35) + listring[context;honey] ]] .. + xbg .. default.get_hotbar_bg(0,1.35) meta:set_string("formspec", formspec) meta:set_string("infotext", "Artificial Hive") @@ -25,7 +25,9 @@ end function hive.timer(pos) local time = (minetest.get_timeofday() or 0) * 24000 - if time < 5500 or time > 18500 then return true end + if time < 5500 or time > 18500 then + return true + end local inv = minetest.get_meta(pos):get_inventory() local honeystack = inv:get_stack("honey", 1) @@ -40,8 +42,10 @@ function hive.timer(pos) inv:add_item("honey", "mobs:honey") elseif honey == honey_max then local timer = minetest.get_node_timer(pos) - timer:stop() return true + timer:stop() + return true end + return true end @@ -53,11 +57,12 @@ xdecor.register("hive", { groups = {choppy=3, oddly_breakable_by_hand=2, flammable=1}, on_construct = hive.construct, on_timer = hive.timer, + can_dig = function(pos) local inv = minetest.get_meta(pos):get_inventory() return inv:is_empty("honey") end, - on_punch = function(pos, node, puncher) + on_punch = function(pos, player, puncher) if math.random(1, 4) == 1 then minetest.add_entity(pos, "mobs_animal:bee_angry") end @@ -66,7 +71,11 @@ xdecor.register("hive", { minetest.add_entity(pos, "mobs_animal:bee_angry") end end, - allow_metadata_inventory_put = function() return 0 end, + + allow_metadata_inventory_put = function() + return 0 + end, + on_metadata_inventory_take = function(pos, _, _, stack) if stack:get_count() == honey_max then local timer = minetest.get_node_timer(pos) @@ -81,8 +90,13 @@ minetest.register_craftitem("xdecor:honey", { description = "Honey", inventory_image = "xdecor_honey.png", wield_image = "xdecor_honey.png", - groups = {food_honey = 1, food_sugar = 1, flammable = 2, not_in_creative_inventory=1}, - on_use = minetest.item_eat(2) + on_use = minetest.item_eat(2), + groups = { + food_honey = 1, + food_sugar = 1, + flammable = 2, + not_in_creative_inventory = 1, + }, }) -- Recipes diff --git a/src/itemframe.lua b/src/itemframe.lua index e8890ca..83cce3f 100755 --- a/src/itemframe.lua +++ b/src/itemframe.lua @@ -6,15 +6,18 @@ local function remove_item(pos, node) if not objs then return end for _, obj in pairs(objs) do - if obj and obj:get_luaentity() and - obj:get_luaentity().name == "xdecor:f_item" then + local ent = obj:get_luaentity() + if obj and ent and ent.name == "xdecor:f_item" then obj:remove() break end end end local facedir = { - [0] = {x=0, y=0, z=1}, {x=1, y=0, z=0}, {x=0, y=0, z=-1}, {x=-1, y=0, z=0} + [0] = {x = 0, y = 0, z = 1}, + {x = 1, y = 0, z = 0}, + {x = 0, y = 0, z = -1}, + {x = -1, y = 0, z = 0} } local function update_item(pos, node) @@ -29,8 +32,8 @@ local function update_item(pos, node) tmp.texture = ItemStack(itemstring):get_name() local entity = minetest.add_entity(pos, "xdecor:f_item") - local yaw = math.pi*2 - node.param2 * math.pi/2 - entity:setyaw(yaw) + local yaw = (math.pi * 2) - node.param2 * (math.pi / 2) + entity:set_yaw(yaw) local timer = minetest.get_node_timer(pos) timer:start(15.0) @@ -53,7 +56,7 @@ function itemframe.after_place(pos, placer, itemstack) local meta = minetest.get_meta(pos) local name = placer:get_player_name() meta:set_string("owner", name) - meta:set_string("infotext", "Item Frame (owned by "..name..")") + meta:set_string("infotext", "Item Frame (owned by " .. name .. ")") end function itemframe.timer(pos) @@ -64,6 +67,7 @@ function itemframe.timer(pos) if num == 0 and meta:get_string("item") ~= "" then update_item(pos, node) end + return true end @@ -91,8 +95,9 @@ function itemframe.punch(pos, node, puncher) local owner = meta:get_string("owner") local admin = minetest.check_player_privs(player_name, "protection_bypass") - if not admin and player_name ~= owner then return end - drop_item(pos, node) + if admin and player_name == owner then + drop_item(pos, node) + end end function itemframe.dig(pos, player) @@ -107,14 +112,16 @@ end xdecor.register("itemframe", { description = "Item Frame", - groups = {choppy=3, oddly_breakable_by_hand=2, flammable=3}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 3}, sounds = default.node_sound_wood_defaults(), on_rotate = screwdriver.disallow, sunlight_propagates = true, inventory_image = "xdecor_itemframe.png", node_box = xdecor.nodebox.slab_z(0.9375), - tiles = {"xdecor_wood.png", "xdecor_wood.png", "xdecor_wood.png", - "xdecor_wood.png", "xdecor_wood.png", "xdecor_itemframe.png"}, + tiles = { + "xdecor_wood.png", "xdecor_wood.png", "xdecor_wood.png", + "xdecor_wood.png", "xdecor_wood.png", "xdecor_itemframe.png" + }, after_place_node = itemframe.after_place, on_timer = itemframe.timer, on_rightclick = itemframe.rightclick, @@ -125,12 +132,12 @@ xdecor.register("itemframe", { minetest.register_entity("xdecor:f_item", { visual = "wielditem", - visual_size = {x=0.33, y=0.33}, + visual_size = {x = 0.33, y = 0.33}, collisionbox = {0}, physical = false, textures = {"air"}, on_activate = function(self, staticdata) - local pos = self.object:getpos() + local pos = self.object:get_pos() if minetest.get_node(pos).name ~= "xdecor:itemframe" then self.object:remove() end @@ -148,13 +155,16 @@ minetest.register_entity("xdecor:f_item", { end end if self.texture then - self.object:set_properties({textures={self.texture}}) + self.object:set_properties({ + textures = {self.texture} + }) end end, get_staticdata = function(self) if self.nodename and self.texture then - return self.nodename..";"..self.texture + return self.nodename .. ";" .. self.texture end + return "" end }) \ No newline at end of file diff --git a/src/mailbox.lua b/src/mailbox.lua index 5c2dcd2..a3f5424 100755 --- a/src/mailbox.lua +++ b/src/mailbox.lua @@ -2,17 +2,25 @@ local mailbox = {} screwdriver = screwdriver or {} local function get_img(img) + if not img then return end local img_name = img:match("(.*)%.png") - if img_name then return img_name..".png" end + + if img_name then + return img_name .. ".png" + end end local function img_col(stack) local def = minetest.registered_items[stack] - if not def then return "" end + if not def then + return "" + end if def.inventory_image ~= "" then local img = get_img(def.inventory_image) - if img then return img end + if img then + return img + end end if def.tiles then @@ -22,30 +30,34 @@ local function img_col(stack) elseif type(tile) == "string" then img = get_img(tile) end - if img then return img end + + if img then + return img + end end return "" end function mailbox:formspec(pos, owner, is_owner) - local spos = pos.x..","..pos.y..","..pos.z + local spos = pos.x .. "," .. pos.y .. "," .. pos.z local meta = minetest.get_meta(pos) local giver, img = "", "" if is_owner then for i = 1, 7 do - local giving = meta:get_string("giver"..i) + local giving = meta:get_string("giver" .. i) if giving ~= "" then - local stack = meta:get_string("stack"..i) + local stack = meta:get_string("stack" .. i) local giver_name = giving:sub(1,12) local stack_name = stack:match("[%w_:]+") local stack_count = stack:match("%s(%d+)") or 1 - giver = giver.."#FFFF00,"..giver_name..","..i.. - ",#FFFFFF,x "..stack_count.."," - img = img..i.."=".. - img_col(stack_name).."^\\[resize:16x16," + giver = giver .. "#FFFF00," .. giver_name .. "," .. i .. + ",#FFFFFF,x " .. stack_count .. "," + + img = img .. i .. "=" .. + img_col(stack_name) .. "^\\[resize:16x16," end end @@ -55,20 +67,21 @@ function mailbox:formspec(pos, owner, is_owner) box[6,0.72;3.3,3.5;#555555] listring[current_player;main] list[current_player;main;0.75,5.25;8,4;] - tableoptions[background=#00000000;highlight=#00000000;border=false] ]].. - "tablecolumns[color;text;image,"..img.."0;color;text]".. - "table[6,0.75;3.3,4;givers;"..giver.."]".. - "list[nodemeta:"..spos..";mailbox;0,0.75;6,4;]".. - "listring[nodemeta:"..spos..";mailbox]".. - xbg..default.get_hotbar_bg(0.75,5.25) + tableoptions[background=#00000000;highlight=#00000000;border=false] ]] .. + "tablecolumns[color;text;image," .. img .. "0;color;text]" .. + "table[6,0.75;3.3,4;givers;" .. giver .. "]" .. + "list[nodemeta:" .. spos .. ";mailbox;0,0.75;6,4;]" .. + "listring[nodemeta:" .. spos .. ";mailbox]" .. + xbg .. default.get_hotbar_bg(0.75, 5.25) end - return [[ size[8,5] - list[current_player;main;0,1.25;8,4;] ]].. - "label[0,0;Send your goods to\n".. + + return "size[8,5]" .. + "list[current_player;main;0,1.25;8,4;]" .. + "label[0,0;Send your goods to\n" .. (minetest.colorize and - minetest.colorize("#FFFF00", owner) or owner).."]".. - "list[nodemeta:"..spos..";drop;3.5,0;1,1;]".. - xbg..default.get_hotbar_bg(0,1.25) + minetest.colorize("#FFFF00", owner) or owner) .. "]" .. + "list[nodemeta:" .. spos .. ";drop;3.5,0;1,1;]" .. + xbg .. default.get_hotbar_bg(0, 1.25) end function mailbox.dig(pos, player) @@ -85,10 +98,10 @@ function mailbox.after_place_node(pos, placer) local player_name = placer:get_player_name() meta:set_string("owner", player_name) - meta:set_string("infotext", player_name.."'s Mailbox") + meta:set_string("infotext", player_name .. "'s Mailbox") local inv = meta:get_inventory() - inv:set_size("mailbox", 6*4) + inv:set_size("mailbox", 6 * 4) inv:set_size("drop", 1) end @@ -97,8 +110,9 @@ function mailbox.rightclick(pos, node, clicker, itemstack, pointed_thing) local player = clicker:get_player_name() local owner = meta:get_string("owner") - minetest.show_formspec(player, "xdecor:mailbox", mailbox:formspec(pos, - owner, (player == owner))) + minetest.show_formspec(player, "xdecor:mailbox", + mailbox:formspec(pos, owner, (player == owner))) + return itemstack end @@ -109,9 +123,10 @@ function mailbox.put(pos, listname, _, stack, player) return -1 else minetest.chat_send_player(player:get_player_name(), - "The mailbox is full") + "The mailbox is full") end end + return 0 end @@ -124,8 +139,8 @@ function mailbox.on_put(pos, listname, _, stack, player) inv:add_item("mailbox", stack) for i = 7, 2, -1 do - meta:set_string("giver"..i, meta:get_string("giver"..(i-1))) - meta:set_string("stack"..i, meta:get_string("stack"..(i-1))) + meta:set_string("giver" .. i, meta:get_string("giver" .. (i - 1))) + meta:set_string("stack" .. i, meta:get_string("stack" .. (i - 1))) end meta:set_string("giver1", player:get_player_name()) @@ -139,6 +154,7 @@ function mailbox.allow_take(pos, listname, index, stack, player) if player:get_player_name() ~= meta:get_string("owner") then return 0 end + return stack:get_count() end @@ -151,7 +167,7 @@ xdecor.register("mailbox", { tiles = {"xdecor_mailbox_top.png", "xdecor_mailbox_bottom.png", "xdecor_mailbox_side.png", "xdecor_mailbox_side.png", "xdecor_mailbox.png", "xdecor_mailbox.png"}, - groups = {cracky=3, oddly_breakable_by_hand=1}, + groups = {cracky = 3, oddly_breakable_by_hand = 1}, on_rotate = screwdriver.rotate_simple, can_dig = mailbox.dig, on_rightclick = mailbox.rightclick, diff --git a/src/mechanisms.lua b/src/mechanisms.lua index 9d79a9f..6139029 100755 --- a/src/mechanisms.lua +++ b/src/mechanisms.lua @@ -12,14 +12,14 @@ local function door_toggle(pos_actuator, pos_door, player) if actuator.name:sub(-4) == "_off" then minetest.set_node(pos_actuator, - {name=actuator.name:gsub("_off", "_on"), param2=actuator.param2}) + {name = actuator.name:gsub("_off", "_on"), param2 = actuator.param2}) end door:open(player) minetest.after(2, function() if minetest.get_node(pos_actuator).name:sub(-3) == "_on" then minetest.set_node(pos_actuator, - {name=actuator.name, param2=actuator.param2}) + {name = actuator.name, param2 = actuator.param2}) end -- Re-get player object (or nil) because 'player' could -- be an invalid object at this time (player left) @@ -35,74 +35,78 @@ end function plate.timer(pos) local objs = minetest.get_objects_inside_radius(pos, 0.8) if not next(objs) or not doors.get then return true end - local minp = {x=pos.x-2, y=pos.y, z=pos.z-2} - local maxp = {x=pos.x+2, y=pos.y, z=pos.z+2} + + local minp = {x = pos.x - 2, y = pos.y, z = pos.z - 2} + local maxp = {x = pos.x + 2, y = pos.y, z = pos.z + 2} local doors = minetest.find_nodes_in_area(minp, maxp, "group:door") for _, player in pairs(objs) do if player:is_player() then - for i=1, #doors do + for i = 1, #doors do door_toggle(pos, doors[i], player) end break end end + return true end ---function plate.register(material, desc, def) --- xdecor.register("pressure_"..material.."_off", { --- description = desc.." Pressure Plate", --- tiles = {"xdecor_pressure_"..material..".png"}, --- drawtype = "nodebox", --- node_box = xdecor.pixelbox(16, {{1, 0, 1, 14, 1, 14}}), --- groups = def.groups, --- sounds = def.sounds, --- sunlight_propagates = true, --- on_rotate = screwdriver.rotate_simple, --- on_construct = plate.construct, --- on_timer = plate.timer --- }) --- xdecor.register("pressure_"..material.."_on", { --- tiles = {"xdecor_pressure_"..material..".png"}, --- drawtype = "nodebox", --- node_box = xdecor.pixelbox(16, {{1, 0, 1, 14, 0.4, 14}}), --- groups = def.groups, --- sounds = def.sounds, --- drop = "xdecor:pressure_"..material.."_off", --- sunlight_propagates = true, --- on_rotate = screwdriver.rotate_simple --- }) ---end +--[[function plate.register(material, desc, def) + xdecor.register("pressure_" .. material .. "_off", { + description = desc .. " Pressure Plate", + tiles = {"xdecor_pressure_" .. material .. ".png"}, + drawtype = "nodebox", + node_box = xdecor.pixelbox(16, {{1, 0, 1, 14, 1, 14}}), + groups = def.groups, + sounds = def.sounds, + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple, + on_construct = plate.construct, + on_timer = plate.timer + }) + xdecor.register("pressure_" .. material .. "_on", { + tiles = {"xdecor_pressure_" .. material .. ".png"}, + drawtype = "nodebox", + node_box = xdecor.pixelbox(16, {{1, 0, 1, 14, 0.4, 14}}), + groups = def.groups, + sounds = def.sounds, + drop = "xdecor:pressure_" .. material .. "_off", + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple + }) +end ---plate.register("wood", "Wooden", { --- sounds = default.node_sound_wood_defaults(), --- groups = {choppy=3, oddly_breakable_by_hand=2, flammable=2} ---}) +plate.register("wood", "Wooden", { + sounds = default.node_sound_wood_defaults(), + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2} +}) ---plate.register("stone", "Stone", { --- sounds = default.node_sound_stone_defaults(), --- groups = {cracky=3, oddly_breakable_by_hand=2} ---}) +plate.register("stone", "Stone", { + sounds = default.node_sound_stone_defaults(), + groups = {cracky = 3, oddly_breakable_by_hand = 2} +})]] xdecor.register("lever_off", { description = "Lever", tiles = {"xdecor_lever_off.png"}, drawtype = "nodebox", node_box = xdecor.pixelbox(16, {{2, 1, 15, 12, 14, 1}}), - groups = {cracky=3, oddly_breakable_by_hand=2}, + groups = {cracky = 3, oddly_breakable_by_hand = 2}, sounds = default.node_sound_stone_defaults(), sunlight_propagates = true, on_rotate = screwdriver.rotate_simple, + on_rightclick = function(pos, node, clicker, itemstack) if not doors.get then return itemstack end - local minp = {x=pos.x-2, y=pos.y-1, z=pos.z-2} - local maxp = {x=pos.x+2, y=pos.y+1, z=pos.z+2} + local minp = {x = pos.x - 2, y = pos.y - 1, z = pos.z - 2} + local maxp = {x = pos.x + 2, y = pos.y + 1, z = pos.z + 2} local doors = minetest.find_nodes_in_area(minp, maxp, "group:door") - for i=1, #doors do + for i = 1, #doors do door_toggle(pos, doors[i], clicker) end + return itemstack end }) @@ -111,7 +115,7 @@ xdecor.register("lever_on", { tiles = {"xdecor_lever_on.png"}, drawtype = "nodebox", node_box = xdecor.pixelbox(16, {{2, 1, 15, 12, 14, 1}}), - groups = {cracky=3, oddly_breakable_by_hand=2, not_in_creative_inventory=1}, + groups = {cracky = 3, oddly_breakable_by_hand = 2, not_in_creative_inventory = 1}, sounds = default.node_sound_stone_defaults(), sunlight_propagates = true, on_rotate = screwdriver.rotate_simple, diff --git a/src/nodes.lua b/src/nodes.lua index 72600ae..f065da1 100755 --- a/src/nodes.lua +++ b/src/nodes.lua @@ -3,12 +3,12 @@ screwdriver = screwdriver or {} local function register_pane(name, desc, def) xpanes.register_pane(name, { description = desc, - tiles = {"xdecor_"..name..".png"}, + tiles = {"xdecor_" .. name .. ".png"}, drawtype = "airlike", paramtype = "light", - textures = {"xdecor_"..name..".png", "xdecor_"..name..".png", "xpanes_space.png"}, - inventory_image = "xdecor_"..name..".png", - wield_image = "xdecor_"..name..".png", + textures = {"xdecor_" .. name .. ".png", "xdecor_" .. name .. ".png", "xpanes_space.png"}, + inventory_image = "xdecor_" .. name .. ".png", + wield_image = "xdecor_" .. name .. ".png", groups = def.groups, sounds = def.sounds or default.node_sound_defaults(), recipe = def.recipe @@ -16,33 +16,41 @@ local function register_pane(name, desc, def) end register_pane("bamboo_frame", "Bamboo Frame", { - groups = {choppy=3, oddly_breakable_by_hand=2, pane=1, flammable=2}, - recipe = {{"default:papyrus", "default:papyrus", "default:papyrus"}, - {"default:papyrus", "farming:cotton", "default:papyrus"}, - {"default:papyrus", "default:papyrus", "default:papyrus"}} + groups = {choppy = 3, oddly_breakable_by_hand = 2, pane = 1, flammable = 2}, + recipe = { + {"default:papyrus", "default:papyrus", "default:papyrus"}, + {"default:papyrus", "farming:cotton", "default:papyrus"}, + {"default:papyrus", "default:papyrus", "default:papyrus"} + } }) register_pane("chainlink", "Chainlink", { - groups = {cracky=3, oddly_breakable_by_hand=2, pane=1}, - recipe = {{"default:steel_ingot", "", "default:steel_ingot"}, - {"", "default:steel_ingot", ""}, - {"default:steel_ingot", "", "default:steel_ingot"}} + groups = {cracky = 3, oddly_breakable_by_hand = 2, pane = 1}, + recipe = { + {"default:steel_ingot", "", "default:steel_ingot"}, + {"", "default:steel_ingot", ""}, + {"default:steel_ingot", "", "default:steel_ingot"} + } }) register_pane("rusty_bar", "Rusty Iron Bars", { sounds = default.node_sound_stone_defaults(), - groups = {cracky=2, pane=1}, - recipe = {{"", "default:dirt", ""}, - {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, - {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}} + groups = {cracky = 2, pane = 1}, + recipe = { + {"", "default:dirt", ""}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } }) register_pane("wood_frame", "Wood Frame", { sounds = default.node_sound_wood_defaults(), - groups = {choppy=2, pane=1, flammable=2}, - recipe = {{"group:wood", "group:stick", "group:wood"}, - {"group:stick", "group:stick", "group:stick"}, - {"group:wood", "group:stick", "group:wood"}} + groups = {choppy = 2, pane = 1, flammable = 2}, + recipe = { + {"group:wood", "group:stick", "group:wood"}, + {"group:stick", "group:stick", "group:stick"}, + {"group:wood", "group:stick", "group:wood"} + } }) xdecor.register("baricade", { @@ -51,7 +59,7 @@ xdecor.register("baricade", { paramtype2 = "facedir", inventory_image = "xdecor_baricade.png", tiles = {"xdecor_baricade.png"}, - groups = {choppy=2, oddly_breakable_by_hand=1, flammable=2}, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, damage_per_second = 4, selection_box = xdecor.nodebox.slab_y(0.3), collision_box = xdecor.pixelbox(2, {{0, 0, 1, 2, 2, 0}}) @@ -61,50 +69,62 @@ xdecor.register("barrel", { description = "Barrel", tiles = {"xdecor_barrel_top.png", "xdecor_barrel_top.png", "xdecor_barrel_sides.png"}, on_place = minetest.rotate_node, - groups = {choppy=2, oddly_breakable_by_hand=1, flammable=2}, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, sounds = default.node_sound_wood_defaults() }) local function register_storage(name, desc, def) xdecor.register(name, { description = desc, - inventory = {size=def.inv_size or 24}, + inventory = {size = def.inv_size or 24}, infotext = desc, tiles = def.tiles, node_box = def.node_box, on_rotate = def.on_rotate, on_place = def.on_place, - groups = def.groups or {choppy=2, oddly_breakable_by_hand=1, flammable=2}, + groups = def.groups or {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, sounds = default.node_sound_wood_defaults() }) end register_storage("cabinet", "Wooden Cabinet", { on_rotate = screwdriver.rotate_simple, - tiles = {"xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", - "xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", - "xdecor_cabinet_sides.png", "xdecor_cabinet_front.png"} + tiles = { + "xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", + "xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", + "xdecor_cabinet_sides.png", "xdecor_cabinet_front.png" + } }) register_storage("cabinet_half", "Half Wooden Cabinet", { inv_size = 8, node_box = xdecor.nodebox.slab_y(0.5, 0.5), on_rotate = screwdriver.rotate_simple, - tiles = {"xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", - "xdecor_half_cabinet_sides.png", "xdecor_half_cabinet_sides.png", - "xdecor_half_cabinet_sides.png", "xdecor_half_cabinet_front.png"} + tiles = { + "xdecor_cabinet_sides.png", "xdecor_cabinet_sides.png", + "xdecor_half_cabinet_sides.png", "xdecor_half_cabinet_sides.png", + "xdecor_half_cabinet_sides.png", "xdecor_half_cabinet_front.png" + } }) -register_storage("empty_shelf", "Empty Shelf", { - on_rotate = screwdriver.rotate_simple, - tiles = {"default_wood.png", "default_wood.png", "default_wood.png", - "default_wood.png", "default_wood.png^xdecor_empty_shelf.png"} -}) +if minetest.get_modpath("moreblocks") then + minetest.register_alias("xdecor:empty_shelf", "moreblocks:empty_shelf") +else + register_storage("empty_shelf", "Empty Shelf", { + on_rotate = screwdriver.rotate_simple, + tiles = { + "default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "default_wood.png^xdecor_empty_shelf.png" + } + }) +end register_storage("multishelf", "Multi Shelf", { on_rotate = screwdriver.rotate_simple, - tiles = {"default_wood.png", "default_wood.png", "default_wood.png", - "default_wood.png", "default_wood.png^xdecor_multishelf.png"}, + tiles = { + "default_wood.png", "default_wood.png", "default_wood.png", + "default_wood.png", "default_wood.png^xdecor_multishelf.png" + }, }) xdecor.register("candle", { @@ -115,13 +135,20 @@ xdecor.register("candle", { wield_image = "xdecor_candle_wield.png", paramtype2 = "wallmounted", walkable = false, - groups = {dig_immediate=3, attached_node=1}, - tiles = {{name = "xdecor_candle_floor.png", - animation = {type="vertical_frames", length=1.5}}, - {name = "xdecor_candle_floor.png", - animation = {type="vertical_frames", length=1.5}}, - {name = "xdecor_candle_wall.png", - animation = {type="vertical_frames", length=1.5}} + groups = {dig_immediate = 3, attached_node = 1}, + tiles = { + { + name = "xdecor_candle_floor.png", + animation = {type="vertical_frames", length = 1.5} + }, + { + name = "xdecor_candle_floor.png", + animation = {type="vertical_frames", length = 1.5} + }, + { + name = "xdecor_candle_wall.png", + animation = {type="vertical_frames", length = 1.5} + } }, selection_box = { type = "wallmounted", @@ -135,12 +162,15 @@ xdecor.register("chair", { description = "Chair", tiles = {"xdecor_wood.png"}, sounds = default.node_sound_wood_defaults(), - groups = {choppy=3, oddly_breakable_by_hand=2, flammable=2}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2}, on_rotate = screwdriver.rotate_simple, node_box = xdecor.pixelbox(16, { - {3, 0, 11, 2, 16, 2}, {11, 0, 11, 2, 16, 2}, - {5, 9, 11.5, 6, 6, 1}, {3, 0, 3, 2, 6, 2}, - {11, 0, 3, 2, 6, 2}, {3, 6, 3, 10, 2, 8} + {3, 0, 11, 2, 16, 2}, + {11, 0, 11, 2, 16, 2}, + {5, 9, 11.5, 6, 6, 1}, + {3, 0, 3, 2, 6, 2}, + {11, 0, 3, 2, 6, 2}, + {3, 6, 3, 10, 2, 8} }), can_dig = xdecor.sit_dig, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) @@ -163,7 +193,7 @@ xdecor.register("cobweb", { liquid_range = 0, walkable = false, selection_box = {type = "regular"}, - groups = {snappy=3, liquid=3, flammable=3}, + groups = {snappy = 3, liquid = 3, flammable = 3}, sounds = default.node_sound_leaves_defaults() }) ]] @@ -171,51 +201,53 @@ local curtain_colors = { "red", } -for _, c in pairs(curtain_colors) do - xdecor.register("curtain_"..c, { - description = c:gsub("^%l", string.upper).." Curtain", +for _, c in ipairs(curtain_colors) do + xdecor.register("curtain_" .. c, { + description = c:gsub("^%l", string.upper) .. " Curtain", walkable = false, tiles = {"wool_white.png"}, color = c, - inventory_image = "wool_white.png^[colorize:"..c.. + inventory_image = "wool_white.png^[colorize:" .. c .. ":170^xdecor_curtain_open_overlay.png^[makealpha:255,126,126", - wield_image = "wool_white.png^[colorize:"..c..":170", + wield_image = "wool_white.png^[colorize:" .. c .. ":170", drawtype = "signlike", paramtype2 = "colorwallmounted", - groups = {dig_immediate=3, flammable=3}, - selection_box = {type="wallmounted"}, + groups = {dig_immediate = 3, flammable = 3}, + selection_box = {type = "wallmounted"}, on_rightclick = function(pos, node, _, itemstack) - minetest.set_node(pos, {name="xdecor:curtain_open_"..c, param2=node.param2}) + minetest.set_node(pos, {name = "xdecor:curtain_open_" .. c, param2 = node.param2}) return itemstack end }) - xdecor.register("curtain_open_"..c, { + xdecor.register("curtain_open_" .. c, { tiles = {"wool_white.png^xdecor_curtain_open_overlay.png^[makealpha:255,126,126"}, color = c, drawtype = "signlike", paramtype2 = "colorwallmounted", walkable = false, - groups = {dig_immediate=3, flammable=3, not_in_creative_inventory=1}, + groups = {dig_immediate = 3, flammable = 3, not_in_creative_inventory = 1}, selection_box = {type="wallmounted"}, - drop = "xdecor:curtain_"..c, + drop = "xdecor:curtain_" .. c, on_rightclick = function(pos, node, _, itemstack) - minetest.set_node(pos, {name="xdecor:curtain_"..c, param2=node.param2}) + minetest.set_node(pos, {name="xdecor:curtain_" .. c, param2 = node.param2}) return itemstack end }) minetest.register_craft({ - output = "xdecor:curtain_"..c.." 4", - recipe = {{"", "wool:"..c, ""}, - {"", "wool:"..c, ""}} + output = "xdecor:curtain_" .. c .. " 4", + recipe = { + {"", "wool:" .. c, ""}, + {"", "wool:" .. c, ""} + } }) end xdecor.register("cushion", { description = "Cushion", tiles = {"xdecor_cushion.png"}, - groups = {snappy=3, flammable=3, fall_damage_add_percent=-50}, + groups = {snappy = 3, flammable = 3, fall_damage_add_percent = -50}, on_place = minetest.rotate_node, node_box = xdecor.nodebox.slab_y(0.5), can_dig = xdecor.sit_dig, @@ -229,7 +261,7 @@ xdecor.register("cushion", { xdecor.register("cushion_block", { description = "Cushion Block", tiles = {"xdecor_cushion.png"}, - groups = {snappy=3, flammable=3, fall_damage_add_percent=-75, not_in_creative_inventory=1} + groups = {snappy = 3, flammable = 3, fall_damage_add_percent = -75, not_in_creative_inventory = 1} }) local function door_access(name) @@ -240,38 +272,67 @@ local xdecor_doors = { japanese = { {"group:wood", "default:paper"}, {"default:paper", "group:wood"}, - {"group:wood", "default:paper"} }, + {"group:wood", "default:paper"} + }, prison = { {"xpanes:bar_flat", "xpanes:bar_flat",}, {"xpanes:bar_flat", "xpanes:bar_flat",}, - {"xpanes:bar_flat", "xpanes:bar_flat"} }, + {"xpanes:bar_flat", "xpanes:bar_flat"} + }, rusty_prison = { {"xpanes:rusty_bar_flat", "xpanes:rusty_bar_flat",}, {"xpanes:rusty_bar_flat", "xpanes:rusty_bar_flat",}, - {"xpanes:rusty_bar_flat", "xpanes:rusty_bar_flat"} }, + {"xpanes:rusty_bar_flat", "xpanes:rusty_bar_flat"} + }, screen = { {"group:wood", "group:wood"}, {"xpanes:chainlink_flat", "xpanes:chainlink_flat"}, - {"group:wood", "group:wood"} }, + {"group:wood", "group:wood"} + }, slide = { {"default:paper", "default:paper"}, {"default:paper", "default:paper"}, - {"group:wood", "group:wood"} }, + {"group:wood", "group:wood"} + }, woodglass = { {"default:glass", "default:glass"}, {"group:wood", "group:wood"}, - {"group:wood", "group:wood"} } + {"group:wood", "group:wood"} + }, } +local mesecons_register + +if minetest.global_exists("mesecon") then + mesecons_register = { effector = { + action_on = function(pos, node) + local door = doors.get(pos) + if door then + door:open() + end + end, + action_off = function(pos, node) + local door = doors.get(pos) + if door then + door:close() + end + end, + rules = mesecon.rules.pplate + }} +end + for name, recipe in pairs(xdecor_doors) do if not doors.register then break end - doors.register(name.."_door", { - tiles = {{name = "xdecor_"..name.."_door.png", backface_culling=true}}, - description = name:gsub("%f[%w]%l", string.upper):gsub("_", " ").." Door", - inventory_image = "xdecor_"..name.."_door_inv.png", + doors.register(name .. "_door", { + tiles = { + {name = "xdecor_" .. name .. "_door.png", backface_culling = true} + }, + description = name:gsub("%f[%w]%l", string.upper):gsub("_", " ") .. " Door", + inventory_image = "xdecor_" .. name .. "_door_inv.png", protected = door_access(name), - groups = {choppy=2, cracky=2, oddly_breakable_by_hand=1, door=1}, - recipe = recipe + groups = {choppy = 2, cracky = 2, oddly_breakable_by_hand = 1, door = 1}, + recipe = recipe, + mesecons = mesecons_register, }) end minetest.register_alias("xdecor:prison_rust_door", "doors:rusty_prison_door") @@ -282,10 +343,12 @@ minetest.register_alias("xdecor:prison_rust_door_b_2", "doors:rusty_prison_door_ xdecor.register("enderchest", { description = "Ender Chest", - tiles = {"xdecor_enderchest_top.png", "xdecor_enderchest_top.png", - "xdecor_enderchest_side.png", "xdecor_enderchest_side.png", - "xdecor_enderchest_side.png", "xdecor_enderchest_front.png"}, - groups = {cracky=1, choppy=1}, + tiles = { + "xdecor_enderchest_top.png", "xdecor_enderchest_top.png", + "xdecor_enderchest_side.png", "xdecor_enderchest_side.png", + "xdecor_enderchest_side.png", "xdecor_enderchest_front.png" + }, + groups = {cracky = 1, choppy = 1}, sounds = default.node_sound_stone_defaults(), on_rotate = screwdriver.rotate_simple, on_construct = function(pos) @@ -295,7 +358,8 @@ xdecor.register("enderchest", { list[current_player;main;0,5;8,4;] listring[current_player;enderchest] listring[current_player;main] ]] - ..xbg..default.get_hotbar_bg(0,5)) + .. xbg .. default.get_hotbar_bg(0,5)) + meta:set_string("infotext", "Ender Chest") end }) @@ -310,7 +374,7 @@ xdecor.register("ivy", { drawtype = "signlike", walkable = false, climbable = true, - groups = {snappy=3, flora=1, attached_node=1, plant=1, flammable=3}, + groups = {snappy = 3, flora = 1, attached_node = 1, plant = 1, flammable = 3}, paramtype2 = "wallmounted", selection_box = {type="wallmounted"}, tiles = {"xdecor_ivy.png"}, @@ -327,38 +391,45 @@ xdecor.register("lantern", { wield_image = "xdecor_lantern_inv.png", paramtype2 = "wallmounted", walkable = false, - groups = {snappy=3, attached_node=1}, - tiles = {{name="xdecor_lantern.png", animation={type="vertical_frames", length=1.5}}}, + groups = {snappy = 3, attached_node = 1}, + tiles = { + { + name = "xdecor_lantern.png", + animation = {type="vertical_frames", length = 1.5} + } + }, selection_box = xdecor.pixelbox(16, {{4, 0, 4, 8, 16, 8}}) }) -for _, l in pairs({"iron", "wooden"}) do - xdecor.register(l.."_lightbox", { - description = l:gsub("^%l", string.upper).." Light Box", - tiles = {"xdecor_"..l.."_lightbox.png"}, - groups = {cracky=3, choppy=3, oddly_breakable_by_hand=2}, +for _, l in ipairs({"iron", "wooden"}) do + xdecor.register(l .. "_lightbox", { + description = l:gsub("^%l", string.upper) .. " Light Box", + tiles = {"xdecor_" .. l .. "_lightbox.png"}, + groups = {cracky = 3, choppy = 3, oddly_breakable_by_hand = 2}, light_source = 13, sounds = default.node_sound_glass_defaults() }) end -for _, f in pairs({"dandelion_white", "dandelion_yellow", "geranium", +for _, f in ipairs({"dandelion_white", "dandelion_yellow", "geranium", "rose", "tulip", "viola"}) do - xdecor.register("potted_"..f, { - description = "Potted "..f:gsub("%f[%w]%l", string.upper):gsub("_", " "), + xdecor.register("potted_" .. f, { + description = "Potted " .. f:gsub("%f[%w]%l", string.upper):gsub("_", " "), walkable = false, - groups = {snappy=3, flammable=3, plant=1, flower=1}, - tiles = {"xdecor_"..f.."_pot.png"}, - inventory_image = "xdecor_"..f.."_pot.png", + groups = {snappy = 3, flammable = 3, plant = 1, flower = 1}, + tiles = {"xdecor_" .. f .. "_pot.png"}, + inventory_image = "xdecor_" .. f .. "_pot.png", drawtype = "plantlike", sounds = default.node_sound_leaves_defaults(), selection_box = xdecor.nodebox.slab_y(0.3) }) minetest.register_craft({ - output = "xdecor:potted_"..f, - recipe = {{"default:clay_brick", "flowers:"..f, - "default:clay_brick"}, {"", "default:clay_brick", ""}} + output = "xdecor:potted_" .. f, + recipe = { + {"default:clay_brick", "flowers:" .. f, "default:clay_brick"}, + {"", "default:clay_brick", ""} + } }) end @@ -376,30 +447,37 @@ xdecor.register("painting_1", { wield_image = "xdecor_painting_empty.png", paramtype2 = "wallmounted", sunlight_propagates = true, - groups = {choppy=3, oddly_breakable_by_hand=2, flammable=2, attached_node=1}, + groups = {choppy = 3, oddly_breakable_by_hand = 2, flammable = 2, attached_node = 1}, sounds = default.node_sound_wood_defaults(), node_box = painting_box, node_placement_prediction = "", on_place = function(itemstack, placer, pointed_thing) local num = math.random(4) local leftover = minetest.item_place_node( - ItemStack("xdecor:painting_"..num), placer, pointed_thing) + ItemStack("xdecor:painting_" .. num), placer, pointed_thing) + if leftover:get_count() == 0 and not minetest.setting_getbool("creative_mode") then itemstack:take_item() end + return itemstack end }) for i = 2, 4 do - xdecor.register("painting_"..i, { - tiles = {"xdecor_painting_"..i..".png"}, + xdecor.register("painting_" .. i, { + tiles = {"xdecor_painting_" .. i .. ".png"}, paramtype2 = "wallmounted", drop = "xdecor:painting_1", sunlight_propagates = true, - groups = {choppy=3, oddly_breakable_by_hand=2, flammable=2, - attached_node=1, not_in_creative_inventory=1}, + groups = { + choppy = 3, + oddly_breakable_by_hand = 2, + flammable = 2, + attached_node = 1, + not_in_creative_inventory = 1 + }, sounds = default.node_sound_wood_defaults(), node_box = painting_box }) @@ -408,7 +486,7 @@ end xdecor.register("stonepath", { description = "Garden Stone Path", tiles = {"default_stone.png"}, - groups = {snappy=3}, + groups = {snappy = 3}, on_rotate = screwdriver.rotate_simple, sounds = default.node_sound_stone_defaults(), sunlight_propagates = true, @@ -423,8 +501,8 @@ local function register_hard_node(name, desc, def) def = def or {} xdecor.register(name, { description = desc, - tiles = {"xdecor_"..name..".png"}, - groups = def.groups or {cracky=1}, + tiles = {"xdecor_" .. name .. ".png"}, + groups = def.groups or {cracky = 1}, sounds = def.sounds or default.node_sound_stone_defaults() }) end @@ -436,19 +514,21 @@ register_hard_node("hard_clay", "Hardened Clay") register_hard_node("moonbrick", "Moon Brick") register_hard_node("stone_tile", "Stone Tile") register_hard_node("stone_rune", "Runestone") + register_hard_node("packed_ice", "Packed Ice", { - groups = {cracky=1, puts_out_fire=1, slippery=3}, + groups = {cracky = 1, puts_out_fire = 1, slippery = 3}, sounds = default.node_sound_glass_defaults() }) + register_hard_node("wood_tile", "Wooden Tile", { - groups = {choppy=1, wood=1, flammable=2}, + groups = {choppy = 1, wood = 1, flammable = 2}, sounds = default.node_sound_wood_defaults() }) xdecor.register("table", { description = "Table", tiles = {"xdecor_wood.png"}, - groups = {choppy=2, oddly_breakable_by_hand=1, flammable=2}, + groups = {choppy = 2, oddly_breakable_by_hand = 1, flammable = 2}, sounds = default.node_sound_wood_defaults(), node_box = xdecor.pixelbox(16, { {0, 14, 0, 16, 2, 16}, {5.5, 0, 5.5, 5, 14, 6} @@ -459,7 +539,7 @@ xdecor.register("tatami", { description = "Tatami", tiles = {"xdecor_tatami.png"}, wield_image = "xdecor_tatami.png", - groups = {snappy=3, flammable=3}, + groups = {snappy = 3, flammable = 3}, sunlight_propagates = true, node_box = xdecor.nodebox.slab_y(0.0625) }) @@ -467,22 +547,31 @@ xdecor.register("tatami", { xdecor.register("trampoline", { description = "Trampoline", tiles = {"xdecor_trampoline.png", "mailbox_blank16.png", "xdecor_trampoline_sides.png"}, - groups = {cracky=3, oddly_breakable_by_hand=1, fall_damage_add_percent=-80, bouncy=90}, + groups = {cracky = 3, oddly_breakable_by_hand = 1, fall_damage_add_percent = -80, bouncy = 90}, node_box = xdecor.nodebox.slab_y(0.5), - sounds = {footstep = {name="xdecor_bouncy", gain=0.8}} + sounds = { + footstep = { + name = "xdecor_bouncy", + gain = 0.8 + } + } }) xdecor.register("tv", { description = "Television", light_source = 11, - groups = {cracky=3, oddly_breakable_by_hand=2}, + groups = {cracky = 3, oddly_breakable_by_hand = 2}, on_rotate = screwdriver.rotate_simple, - tiles = {"xdecor_television_left.png^[transformR270", - "xdecor_television_left.png^[transformR90", - "xdecor_television_left.png^[transformFX", - "xdecor_television_left.png", "xdecor_television_back.png", - {name="xdecor_television_front_animated.png", - animation = {type="vertical_frames", length=80.0}} } + tiles = { + "xdecor_television_left.png^[transformR270", + "xdecor_television_left.png^[transformR90", + "xdecor_television_left.png^[transformFX", + "xdecor_television_left.png", "xdecor_television_back.png", + { + name = "xdecor_television_front_animated.png", + animation = {type = "vertical_frames", length = 80.0} + } + } }) xdecor.register("woodframed_glass", { @@ -490,6 +579,6 @@ xdecor.register("woodframed_glass", { drawtype = "glasslike_framed", sunlight_propagates = true, tiles = {"xdecor_woodframed_glass.png", "xdecor_woodframed_glass_detail.png"}, - groups = {cracky=2, oddly_breakable_by_hand=1}, + groups = {cracky = 2, oddly_breakable_by_hand = 1}, sounds = default.node_sound_glass_defaults() }) diff --git a/src/recipes.lua b/src/recipes.lua index 11b9f27..bc38940 100755 --- a/src/recipes.lua +++ b/src/recipes.lua @@ -95,14 +95,16 @@ minetest.register_craft({ } }) -minetest.register_craft({ - output = "xdecor:empty_shelf", - recipe = { - {"group:wood", "group:wood", "group:wood"}, - {"", "", ""}, - {"group:wood", "group:wood", "group:wood"} - } -}) +if not minetest.get_modpath("moreblocks") then + minetest.register_craft({ + output = "xdecor:empty_shelf", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"", "", ""}, + {"group:wood", "group:wood", "group:wood"} + } + }) +end minetest.register_craft({ output = "xdecor:enderchest", @@ -201,7 +203,7 @@ minetest.register_craft({ minetest.register_craft({ output = "xdecor:painting_1", recipe = { - {"default:sign_wall_wood", "dye:blue"} + {"default:sign_wall_wood", "group:dye"} } }) diff --git a/src/rope.lua b/src/rope.lua index b6d9452..8199db2 100755 --- a/src/rope.lua +++ b/src/rope.lua @@ -6,6 +6,7 @@ function rope.place(itemstack, placer, pointed_thing) local pos = pointed_thing.above local oldnode = minetest.get_node(pos) local stackname = itemstack:get_name() + if minetest.is_protected(pos, placer:get_player_name()) then return itemstack end @@ -18,12 +19,13 @@ function rope.place(itemstack, placer, pointed_thing) oldnode = minetest.get_node(pos) end end + return itemstack end function rope.remove(pos, oldnode, digger, rope_name) local num = 0 - local below = {x=pos.x, y=pos.y, z=pos.z} + local below = {x = pos.x, y = pos.y, z = pos.z} local digger_inv = digger:get_inventory() while minetest.get_node(below).name == rope_name do @@ -31,8 +33,10 @@ function rope.remove(pos, oldnode, digger, rope_name) below.y = below.y - 1 num = num + 1 end + if num == 0 then return end digger_inv:add_item("main", rope_name.." "..num) + return true end @@ -41,14 +45,16 @@ xdecor.register("rope", { drawtype = "plantlike", walkable = false, climbable = true, - groups = {snappy=3, flammable=3}, + groups = {snappy = 3, flammable = 3}, tiles = {"xdecor_rope.png"}, inventory_image = "xdecor_rope_inv.png", wield_image = "xdecor_rope_inv.png", selection_box = xdecor.pixelbox(8, {{3, 0, 3, 2, 8, 2}}), on_place = rope.place, + on_punch = function(pos, node, puncher, pointed_thing) local player_name = puncher:get_player_name() + if not minetest.is_protected(pos, player_name) or minetest.get_player_privs(player_name).protection_bypass then rope.remove(pos, node, puncher, "xdecor:rope") @@ -65,4 +71,4 @@ minetest.register_craft({ {"farming:string"}, {"farming:string"} } -}) \ No newline at end of file +}) diff --git a/src/workbench.lua b/src/workbench.lua index b2a1fb5..ad775f8 100755 --- a/src/workbench.lua +++ b/src/workbench.lua @@ -9,7 +9,7 @@ local registered_nodes = minetest.registered_nodes local nodes = {} for node, def in pairs(registered_nodes) do if xdecor.stairs_valid_def(def) then - nodes[#nodes+1] = node + nodes[#nodes + 1] = node end end @@ -20,102 +20,117 @@ WB.custom_nodes_register = { setmetatable(nodes, { __concat = function(t1, t2) - for i=1, #t2 do - t1[#t1+1] = t2[i] + for i = 1, #t2 do + t1[#t1 + 1] = t2[i] end + return t1 end }) -nodes = nodes..WB.custom_nodes_register +nodes = nodes .. WB.custom_nodes_register -- Nodeboxes definitions workbench.defs = { - -- Name Yield X Y Z W H L + -- Name YieldX YZ WH L {"nanoslab", 16, { 0, 0, 0, 8, 1, 8 }}, {"micropanel", 16, { 0, 0, 0, 16, 1, 8 }}, {"microslab", 8, { 0, 0, 0, 16, 1, 16 }}, {"thinstair", 8, { 0, 7, 0, 16, 1, 8 }, - { 0, 15, 8, 16, 1, 8 }}, + { 0, 15, 8, 16, 1, 8 }}, {"cube", 4, { 0, 0, 0, 8, 8, 8 }}, {"panel", 4, { 0, 0, 0, 16, 8, 8 }}, {"slab", 2, nil }, {"doublepanel", 2, { 0, 0, 0, 16, 8, 8 }, - { 0, 8, 8, 16, 8, 8 }}, + { 0, 8, 8, 16, 8, 8 }}, {"halfstair", 2, { 0, 0, 0, 8, 8, 16 }, - { 0, 8, 8, 8, 8, 8 }}, - {"outerstair", 1, { 0, 0, 0, 16, 8, 16 }, - { 0, 8, 8, 8, 8, 8 }}, + { 0, 8, 8, 8, 8, 8 }}, + {"stair_outer", 1, nil }, {"stair", 1, nil }, - {"innerstair", 1, { 0, 0, 0, 16, 8, 16 }, - { 0, 8, 8, 16, 8, 8 }, - { 0, 8, 0, 8, 8, 8 }} + {"stair_inner", 1, nil } } +local repairable_tools = {"pick", "axe", "shovel", "sword", "hoe", "armor", "shield"} + -- Tools allowed to be repaired function workbench:repairable(stack) - local tools = {"pick", "axe", "shovel", "sword", "hoe", "armor", "shield"} - for _, t in pairs(tools) do - if stack:find(t) then return true end + for _, t in ipairs(repairable_tools) do + if stack:find(t) then + return true + end end - return false end function workbench:get_output(inv, input, name) local output = {} - for i=1, #self.defs do + for i = 1, #self.defs do local nbox = self.defs[i] local count = min(nbox[2] * input:get_count(), input:get_stack_max()) - local item = name.."_"..nbox[1] - item = nbox[3] and item or "stairs:"..nbox[1].."_"..name:match(":(.*)") - output[#output+1] = item.." "..count + local item = name .. "_" .. nbox[1] + + item = nbox[3] and item or "stairs:" .. nbox[1] .. "_" .. name:match(":(.*)") + output[#output + 1] = item .. " " .. count end inv:set_list("forms", output) end +local main_fs = [[ + label[0.9,1.23;Cut] + label[0.9,2.23;Repair] + box[-0.05,1;2.05,0.9;#555555] + box[-0.05,2;2.05,0.9;#555555] + button[0,0;2,1;craft;Crafting] + button[2,0;2,1;storage;Storage] + image[3,1;1,1;gui_furnace_arrow_bg.png^[transformR270] + image[0,1;1,1;worktable_saw.png] + image[0,2;1,1;worktable_anvil.png] + image[3,2;1,1;hammer_layout.png] + list[context;input;2,1;1,1;] + list[context;tool;2,2;1,1;] + list[context;hammer;3,2;1,1;] + list[context;forms;4,0;4,3;] + listring[current_player;main] + listring[context;tool] + listring[current_player;main] + listring[context;hammer] + listring[current_player;main] + listring[context;forms] + listring[current_player;main] + listring[context;input] +]] + +local crafting_fs = [[ + image[5,1;1,1;gui_furnace_arrow_bg.png^[transformR270] + button[0,0;1.5,1;back;< Back] + list[current_player;craft;2,0;3,3;] + list[current_player;craftpreview;6,1;1,1;] + listring[current_player;main] + listring[current_player;craft] +]] + +local storage_fs = [[ + list[context;storage;0,1;8,2;] + button[0,0;1.5,1;back;< Back] + listring[context;storage] + listring[current_player;main] +]] + local formspecs = { -- Main formspec - [[ label[0.9,1.23;Cut] - label[0.9,2.23;Repair] - box[-0.05,1;2.05,0.9;#555555] - box[-0.05,2;2.05,0.9;#555555] - button[0,0;2,1;craft;Crafting] - button[2,0;2,1;storage;Storage] - image[3,1;1,1;gui_furnace_arrow_bg.png^[transformR270] - image[0,1;1,1;worktable_saw.png] - image[0,2;1,1;worktable_anvil.png] - image[3,2;1,1;hammer_layout.png] - list[context;input;2,1;1,1;] - list[context;tool;2,2;1,1;] - list[context;hammer;3,2;1,1;] - list[context;forms;4,0;4,3;] - listring[current_player;main] - listring[context;tool] - listring[current_player;main] - listring[context;hammer] - listring[current_player;main] - listring[context;forms] - listring[current_player;main] - listring[context;input] ]], + main_fs, + -- Crafting formspec - [[ image[5,1;1,1;gui_furnace_arrow_bg.png^[transformR270] - button[0,0;1.5,1;back;< Back] - list[current_player;craft;2,0;3,3;] - list[current_player;craftpreview;6,1;1,1;] - listring[current_player;main] - listring[current_player;craft] ]], + crafting_fs, + -- Storage formspec - [[ list[context;storage;0,1;8,2;] - button[0,0;1.5,1;back;< Back] - listring[context;storage] - listring[current_player;main] ]] + storage_fs, } function workbench:set_formspec(meta, id) meta:set_string("formspec", - "size[8,7;]list[current_player;main;0,3.25;8,4;]".. - formspecs[id]..xbg..default.get_hotbar_bg(0,3.25)) + "size[8,7;]list[current_player;main;0,3.25;8,4;]" .. + formspecs[id] .. xbg .. default.get_hotbar_bg(0,3.25)) end function workbench.construct(pos) @@ -134,11 +149,11 @@ end function workbench.fields(pos, _, fields) if fields.quit then return end + local meta = minetest.get_meta(pos) - local id = fields.back and 1 or - fields.craft and 2 or - fields.storage and 3 + local id = fields.back and 1 or fields.craft and 2 or fields.storage and 3 if not id then return end + workbench:set_formspec(meta, id) end @@ -159,24 +174,26 @@ function workbench.timer(pos) return end - -- Tool's wearing range: 0-65535 | 0 = new condition + -- Tool's wearing range: 0-65535; 0 = new condition tool:add_wear(-500) hammer:add_wear(700) inv:set_stack("tool", 1, tool) inv:set_stack("hammer", 1, hammer) + return true end function workbench.put(_, listname, _, stack) local stackname = stack:get_name() if (listname == "tool" and stack:get_wear() > 0 and - workbench:repairable(stackname)) or - (listname == "input" and registered_nodes[stackname.."_cube"]) or + workbench:repairable(stackname)) or + (listname == "input" and registered_nodes[stackname .. "_cube"]) or (listname == "hammer" and stackname == "cottages:hammer") or listname == "storage" then return stack:get_count() end + return 0 end @@ -202,7 +219,7 @@ function workbench.on_take(pos, listname, index, stack, player) local stackname = stack:get_name() if listname == "input" then - if stackname == inputname and registered_nodes[inputname.."_cube"] then + if stackname == inputname and registered_nodes[inputname .. "_cube"] then workbench:get_output(inv, input, stackname) else inv:set_list("forms", {}) @@ -224,11 +241,13 @@ end xdecor.register("workbench", { description = "Work Bench", - groups = {cracky=2, choppy=2, oddly_breakable_by_hand=1}, + groups = {cracky = 2, choppy = 2, oddly_breakable_by_hand = 1}, sounds = default.node_sound_wood_defaults(), - tiles = {"xdecor_workbench_top.png", "xdecor_workbench_top.png", - "xdecor_workbench_sides.png", "xdecor_workbench_sides.png", - "xdecor_workbench_front.png", "xdecor_workbench_front.png"}, + tiles = { + "xdecor_workbench_top.png","xdecor_workbench_top.png", + "xdecor_workbench_sides.png", "xdecor_workbench_sides.png", + "xdecor_workbench_front.png", "xdecor_workbench_front.png" + }, on_rotate = screwdriver.rotate_simple, can_dig = workbench.dig, on_timer = workbench.timer, @@ -240,12 +259,13 @@ xdecor.register("workbench", { allow_metadata_inventory_move = workbench.move }) -for _, d in pairs(workbench.defs) do -for i=1, #nodes do +for _, d in ipairs(workbench.defs) do +for i = 1, #nodes do local node = nodes[i] + local mod_name, item_name = node:match("^(.-):(.*)") local def = registered_nodes[node] - if d[3] then + if item_name and d[3] then local groups = {} local tiles groups.not_in_creative_inventory = 1 @@ -266,14 +286,14 @@ for i=1, #nodes do tiles = {def.tile_images[1]} end - if not registered_nodes["stairs:slab_"..node:match(":(.*)")] then - stairs.register_stair_and_slab(node:match(":(.*)"), node, - groups, tiles, def.description.." Stair", - def.description.." Slab", def.sounds) + if not registered_nodes["stairs:slab_" .. item_name] then + stairs.register_stair_and_slab(item_name, node, + groups, tiles, def.description .. " Stair", + def.description .. " Slab", def.sounds) end - minetest.register_node(":"..node.."_"..d[1], { - description = def.description.." "..d[1]:gsub("^%l", string.upper), + minetest.register_node(":" .. node .. "_" .. d[1], { + description = def.description .. " " .. d[1]:gsub("^%l", string.upper), paramtype = "light", paramtype2 = "facedir", drawtype = "nodebox", @@ -285,6 +305,16 @@ for i=1, #nodes do sunlight_propagates = true, on_place = minetest.rotate_node }) + + elseif item_name and mod_name then + minetest.register_alias_force( + ("%s:%s_innerstair"):format(mod_name, item_name), + ("stairs:stair_inner_%s"):format(item_name) + ) + minetest.register_alias_force( + ("%s:%s_outerstair"):format(mod_name, item_name), + ("stairs:stair_outer_%s"):format(item_name) + ) end end end @@ -295,7 +325,9 @@ minetest.register_tool("xdecor:hammer", { description = "Hammer", inventory_image = "xdecor_hammer.png", wield_image = "xdecor_hammer.png", - on_use = function() do return end end + on_use = function() do + return end + end }) -- Recipes