diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/00README b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/00README new file mode 100644 index 0000000..1aa78a4 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/00README @@ -0,0 +1 @@ +See "oldcoder.txt". diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/LICENSE b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/LICENSE new file mode 100644 index 0000000..8b744c6 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/LICENSE @@ -0,0 +1,39 @@ +┌──────────────────────────────────────────────────────────────────────┐ +│ Copyright (c) 2015-2017 kilbith │ +│ │ +│ Code: BSD │ +│ Textures: WTFPL (credits: Gambit, kilbith, Cisoun) │ +│ Sounds: │ +│ - xdecor_boiling_water.ogg - by Audionautics - CC BY-SA │ +│ freesound.org/people/Audionautics/sounds/133901/ │ +│ - xdecor_enchanting.ogg - by Timbre - CC BY-SA-NC │ +│ freesound.org/people/Timbre/sounds/221683/ │ +│ - xdecor_bouncy.ogg - by Blender Foundation - CC BY 3.0 │ +│ opengameart.org/content/funny-comic-cartoon-bounce-sound │ +└──────────────────────────────────────────────────────────────────────┘ + + +Copyright (c) 1998, Regents of the University of California +All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +* Neither the name of the University of California, Berkeley nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/README.md b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/README.md new file mode 100644 index 0000000..a84d03b --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/README.md @@ -0,0 +1,50 @@ +# Minetest Handpainted Texture Pack + +**!!! WORK IN PROGRESS !!!** + +This will be a high-res (128x128) texture pack for Minetest. Its license is CC0 1.0. + +The files in this repo are actually [webtoon](https://github.com/pithydon/webtoon) +CC0 texture pack, which I keep rewriting with the new textures. + +The textures are largely my own work, but a lot of them are taken out of other +CC0 works. + +I won't be commiting extremely often in order to not bloat the repo with binary file +changes. + +Most notable texture sources (feel free to send me more sources or your own contributions): + +- https://www.blendswap.com/blends/view/74021 +- https://opengameart.org/content/glitch-sprite-assets-huge-collection +- https://opengameart.org/content/glitch-alpine-landscape-svg +- https://opengameart.org/content/handpainted-tileable-textures-512%D1%85512 +- https://opengameart.org/content/handpainted-stone-wall-textures +- https://opengameart.org/content/4-hand-painted-ground-textures +- https://opengameart.org/content/rpg-item-collection-3 +- https://opengameart.org/content/rpg-item-collection-2 +- https://opengameart.org/content/rpg-item-collection-1 +- https://opengameart.org/content/crate-barrel-bundle +- https://opengameart.org/content/desert-rock +- https://opengameart.org/content/glitch-groddle-forestmeadow-terrain-svg +- https://opengameart.org/content/free-handpainted-plants-2 +- https://opengameart.org/content/free-handpainted-plants +- https://opengameart.org/content/chest-blizzard-style +- https://opengameart.org/content/free-lowpoly-golds +- https://opengameart.org/content/stone-coffin +- https://opengameart.org/content/free-textures-pack-59 +- https://www.blendswap.com/blends/view/46952 +- https://www.blendswap.com/blends/view/73730 +- https://opengameart.org/content/wyrmsun-cc0-over-900-items +- https://opengameart.org/content/40-procedural-textures +- https://opengameart.org/content/procedural-texture-pack?page=1 +- https://opengameart.org/content/cool-leaves-textures +- https://www.deviantart.com/yughues/art/Free-IDKWIAD-3-730335893 +- https://www.deviantart.com/yughues/art/Free-IDKWIAD-4-732217780 +- https://opengameart.org/content/freebies-mundo-commissions +- https://pixabay.com/en/floral-paisley-background-flower-1556345/ +- https://deepart.io +- https://opengameart.org/content/fantasy-crystal-set +- https://opengameart.org/content/cute-prop-models +- https://www.blendswap.com/blends/view/89476 +- https://pixabay.com/en/bread-food-bakery-foodstuff-baking-3365842/ diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/alias.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/alias.lua new file mode 100644 index 0000000..dc95741 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/alias.lua @@ -0,0 +1 @@ +minetest.register_alias("xdecor:crafting_guide", "craftguide:book") diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/chess.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/chess.lua new file mode 100644 index 0000000..f037eee --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/chess.lua @@ -0,0 +1,892 @@ +local realchess = {} +screwdriver = screwdriver or {} + +local function index_to_xy(idx) + idx = idx - 1 + local x = idx % 8 + local y = (idx - x) / 8 + return x, y +end + +local function xy_to_index(x, y) + return x + y * 8 + 1 +end + +local function get_square(a, b) + return (a * 8) - (8 - b) +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 + t[#t + 1] = inv:get_stack("board", i):get_name() + end + + return t +end + +local function attacked(color, idx, board) + local threatDetected = false + local kill = color == "white" + local pawnThreats = {kill, false, kill, false, false, not kill, false, not kill} + + for dir = 1, 8 do + if not threatDetected then + local col, row = index_to_xy(idx) + col, row = col + 1, row + 1 + + for step = 1, 8 do + row = row + rowDirs[dir] + col = col + colDirs[dir] + + if row >= 1 and row <= 8 and col >= 1 and col <= 8 then + local square = get_square(row, col) + local square_name = board[square] + local piece, pieceColor = square_name:match(":(%w+)_(%w+)") + + if piece then + if pieceColor ~= color then + if piece == "bishop" and bishopThreats[dir] then + threatDetected = true + elseif piece == "rook" and rookThreats[dir] then + threatDetected = true + elseif piece == "queen" and queenThreats[dir] then + threatDetected = true + else + if step == 1 then + if piece == "pawn" and pawnThreats[dir] then + threatDetected = true + end + if piece == "king" and kingThreats[dir] then + threatDetected = true + end + end + end + end + break + end + end + end + end + end + + return threatDetected +end + +local function locate_kings(board) + local Bidx, Widx + for i = 1, 64 do + local piece, color = board[i]:match(":(%w+)_(%w+)") + if piece == "king" then + if color == "black" then + Bidx = i + else + Widx = i + end + end + end + + return Bidx, Widx +end + +local pieces = { + "realchess:rook_black_1", + "realchess:knight_black_1", + "realchess:bishop_black_1", + "realchess:queen_black", + "realchess:king_black", + "realchess:bishop_black_2", + "realchess:knight_black_2", + "realchess:rook_black_2", + "realchess:pawn_black_1", + "realchess:pawn_black_2", + "realchess:pawn_black_3", + "realchess:pawn_black_4", + "realchess:pawn_black_5", + "realchess:pawn_black_6", + "realchess:pawn_black_7", + "realchess:pawn_black_8", + '','','','','','','','','','','','','','','','', + '','','','','','','','','','','','','','','','', + "realchess:pawn_white_1", + "realchess:pawn_white_2", + "realchess:pawn_white_3", + "realchess:pawn_white_4", + "realchess:pawn_white_5", + "realchess:pawn_white_6", + "realchess:pawn_white_7", + "realchess:pawn_white_8", + "realchess:rook_white_1", + "realchess:knight_white_1", + "realchess:bishop_white_1", + "realchess:queen_white", + "realchess:king_white", + "realchess:bishop_white_2", + "realchess:knight_white_2", + "realchess:rook_white_2" +} + +local pieces_str, x = "", 0 +for i = 1, #pieces do + local p = pieces[i]:match(":(%w+_%w+)") + if pieces[i]:find(":(%w+)_(%w+)") and not pieces_str:find(p) then + pieces_str = pieces_str .. x .. "=" .. p .. ".png," + x = x + 1 + end +end +pieces_str = pieces_str .. "69=mailbox_blank16.png" + +local fs = [[ + size[14.7,10;] + no_prepend[] + bgcolor[#080808BB;true] + background[0,0;14.7,10;chess_bg.png] + list[context;board;0.3,1;8,8;] + listcolors[#00000000;#00000000;#00000000;#30434C;#FFF] + tableoptions[background=#00000000;highlight=#00000000;border=false] + button[10.5,8.5;2,2;new;New game] +]] .. "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 moves = meta:get_string("moves") + local pieceFrom_s = pieceFrom:match(":(%w+_%w+)") + local pieceFrom_si_id = pieces_str:match("(%d+)=" .. pieceFrom_s) + local pieceTo_si_id = pieceTo_s ~= "" and pieces_str:match("(%d+)=" .. pieceTo_s) or "" + + local coordFrom = letters[from_x + 1] .. math.abs(from_y - 8) + local coordTo = letters[to_x + 1] .. math.abs(to_y - 8) + + local new_moves = pieceFrom_si_id .. "," .. + coordFrom .. "," .. + (pieceTo ~= "" and "#33FF33" or "#FFFFFF") .. ", > ,#FFFFFF," .. + coordTo .. "," .. + (pieceTo ~= "" and pieceTo_si_id or "69") .. "," .. + moves + + meta:set_string("moves", new_moves) +end + +local function get_eaten_list(meta, pieceTo, pieceTo_s) + local eaten = meta:get_string("eaten") + if pieceTo ~= "" then + eaten = eaten .. pieceTo_s .. "," + end + + meta:set_string("eaten", eaten) + + local eaten_t = string.split(eaten, ",") + local eaten_img = "" + + local a, b = 0, 0 + for i = 1, #eaten_t do + local is_white = eaten_t[i]:sub(-5,-1) == "white" + local X = (is_white and a or b) % 4 + local Y = ((is_white and a or b) % 16 - X) / 4 + + if is_white then + a = a + 1 + else + b = b + 1 + end + + eaten_img = eaten_img .. + "image[" .. ((X + (is_white and 11.7 or 8.8)) - (X * 0.45)) .. "," .. + ((Y + 5.56) - (Y * 0.2)) .. ";1,1;" .. eaten_t[i] .. ".png]" + end + + meta:set_string("eaten_img", eaten_img) +end + +function realchess.init(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + meta:set_string("formspec", fs) + meta:set_string("infotext", "Chess Board") + meta:set_string("playerBlack", "") + meta:set_string("playerWhite", "") + meta:set_string("lastMove", "") + meta:set_string("blackAttacked", "") + meta:set_string("whiteAttacked", "") + + meta:set_int("lastMoveTime", 0) + meta:set_int("castlingBlackL", 1) + meta:set_int("castlingBlackR", 1) + meta:set_int("castlingWhiteL", 1) + meta:set_int("castlingWhiteR", 1) + + meta:set_string("moves", "") + meta:set_string("eaten", "") + + inv:set_list("board", pieces) + inv:set_size("board", 64) +end + +function realchess.move(pos, from_list, from_index, to_list, to_index, _, player) + if from_list ~= "board" and to_list ~= "board" then + return 0 + end + + local meta = minetest.get_meta(pos) + local playerName = player:get_player_name() + local inv = meta:get_inventory() + local pieceFrom = inv:get_stack(from_list, from_index):get_name() + local pieceTo = inv:get_stack(to_list, to_index):get_name() + local lastMove = meta:get_string("lastMove") + local playerWhite = meta:get_string("playerWhite") + local playerBlack = meta:get_string("playerBlack") + local thisMove -- Will replace lastMove when move is legal + + if pieceFrom:find("white") then + if playerWhite ~= "" and playerWhite ~= playerName then + minetest.chat_send_player(playerName, chat_prefix .. "Someone else plays white pieces!") + return 0 + end + + if lastMove ~= "" and lastMove ~= "black" then + return 0 + end + + if pieceTo:find("white") then + -- Don't replace pieces of same color + return 0 + end + + playerWhite = playerName + thisMove = "white" + + elseif pieceFrom:find("black") then + if playerBlack ~= "" and playerBlack ~= playerName then + minetest.chat_send_player(playerName, chat_prefix .. "Someone else plays black pieces!") + return 0 + end + + if lastMove ~= "" and lastMove ~= "white" then + return 0 + end + + if pieceTo:find("black") then + -- Don't replace pieces of same color + return 0 + end + + playerBlack = playerName + thisMove = "black" + end + + -- MOVE LOGIC + + local from_x, from_y = index_to_xy(from_index) + local to_x, to_y = index_to_xy(to_index) + + -- PAWN + if pieceFrom:sub(11,14) == "pawn" then + if thisMove == "white" then + local pawnWhiteMove = inv:get_stack(from_list, xy_to_index(from_x, from_y - 1)):get_name() + -- white pawns can go up only + if from_y - 1 == to_y then + if from_x == to_x then + if pieceTo ~= "" then + return 0 + elseif to_index >= 1 and to_index <= 8 then + inv:set_stack(from_list, from_index, "realchess:queen_white") + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("black") then + return 0 + elseif to_index >= 1 and to_index <= 8 then + inv:set_stack(from_list, from_index, "realchess:queen_white") + end + else + return 0 + end + elseif from_y - 2 == to_y then + if pieceTo ~= "" or from_y < 6 or pawnWhiteMove ~= "" then + return 0 + end + else + return 0 + 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 + return 0 + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("black") then + return 0 + end + else + return 0 + end + + elseif thisMove == "black" then + local pawnBlackMove = inv:get_stack(from_list, xy_to_index(from_x, from_y + 1)):get_name() + -- black pawns can go down only + if from_y + 1 == to_y then + if from_x == to_x then + if pieceTo ~= "" then + return 0 + elseif to_index >= 57 and to_index <= 64 then + inv:set_stack(from_list, from_index, "realchess:queen_black") + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("white") then + return 0 + elseif to_index >= 57 and to_index <= 64 then + inv:set_stack(from_list, from_index, "realchess:queen_black") + end + else + return 0 + end + elseif from_y + 2 == to_y then + if pieceTo ~= "" or from_y > 1 or pawnBlackMove ~= "" then + return 0 + end + else + return 0 + 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 + return 0 + end + elseif from_x - 1 == to_x or from_x + 1 == to_x then + if not pieceTo:find("white") then + return 0 + end + else + return 0 + end + else + return 0 + end + + -- ROOK + elseif pieceFrom:sub(11,14) == "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 inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then + return 0 + end + end + else + -- Mocing up + -- Ensure that no piece disturbs the way + for i = to_y + 1, from_y - 1 do + if inv:get_stack(from_list, xy_to_index(from_x, i)):get_name() ~= "" then + return 0 + 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 inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then + return 0 + end + end + else + -- Mocing left + -- Ensure that no piece disturbs the way + for i = to_x + 1, from_x - 1 do + if inv:get_stack(from_list, xy_to_index(i, from_y)):get_name() ~= "" then + return 0 + end + end + end + else + -- Attempt to move arbitrarily -> abort + return 0 + end + + if thisMove == "white" or thisMove == "black" then + if pieceFrom:sub(-1) == "1" then + meta:set_int("castlingWhiteL", 0) + elseif pieceFrom:sub(-1) == "2" then + meta:set_int("castlingWhiteR", 0) + end + end + + -- KNIGHT + elseif pieceFrom:sub(11,16) == "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 + return 0 + end + -- Just ensure that destination cell does not contain friend piece + -- ^ It was done already thus everything ok + + -- BISHOP + elseif pieceFrom:sub(11,16) == "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 return 0 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 inv:get_stack(from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then + return 0 + end + end + else + -- 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 + return 0 + 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 inv:get_stack(from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then + return 0 + end + end + else + -- 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 + return 0 + end + end + end + end + + -- QUEEN + elseif pieceFrom:sub(11,15) == "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 + return 0 + end + + if from_x == to_x then + if from_y < to_y then + -- 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 + return 0 + end + end + else + -- 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 + return 0 + 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 inv:get_stack(from_list, xy_to_index(from_x + i, from_y)):get_name() ~= "" then + return 0 + 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 inv:get_stack(from_list, xy_to_index(from_x + i, from_y + i)):get_name() ~= "" then + return 0 + end + end + else + -- 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 + return 0 + end + end + end + else + if from_y == to_y then + -- 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 + return 0 + 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 inv:get_stack(from_list, xy_to_index(from_x - i, from_y + i)):get_name() ~= "" then + return 0 + end + end + else + -- 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 + return 0 + end + end + end + end + + -- KING + elseif pieceFrom:sub(11,14) == "king" then + local dx = from_x - to_x + local dy = from_y - to_y + local check = true + + if thisMove == "white" then + if from_y == 7 and to_y == 7 then + if to_x == 1 then + local castlingWhiteL = meta:get_int("castlingWhiteL") + local idx57 = inv:get_stack(from_list, 57):get_name() + + if castlingWhiteL == 1 and idx57 == "realchess:rook_white_1" then + for i = 58, from_index - 1 do + if inv:get_stack(from_list, i):get_name() ~= "" then + return 0 + end + end + inv:set_stack(from_list, 57, "") + inv:set_stack(from_list, 59, "realchess:rook_white_1") + check = false + end + elseif to_x == 6 then + local castlingWhiteR = meta:get_int("castlingWhiteR") + local idx64 = inv:get_stack(from_list, 64):get_name() + + if castlingWhiteR == 1 and idx64 == "realchess:rook_white_2" then + for i = from_index + 1, 63 do + if inv:get_stack(from_list, i):get_name() ~= "" then + return 0 + end + end + inv:set_stack(from_list, 62, "realchess:rook_white_2") + inv:set_stack(from_list, 64, "") + check = false + end + end + end + elseif thisMove == "black" then + if from_y == 0 and to_y == 0 then + if to_x == 1 then + local castlingBlackL = meta:get_int("castlingBlackL") + local idx1 = inv:get_stack(from_list, 1):get_name() + + if castlingBlackL == 1 and idx1 == "realchess:rook_black_1" then + for i = 2, from_index - 1 do + if inv:get_stack(from_list, i):get_name() ~= "" then + return 0 + end + end + + inv:set_stack(from_list, 1, "") + inv:set_stack(from_list, 3, "realchess:rook_black_1") + check = false + end + elseif to_x == 6 then + local castlingBlackR = meta:get_int("castlingBlackR") + local idx8 = inv:get_stack(from_list, 1):get_name() + + if castlingBlackR == 1 and idx8 == "realchess:rook_black_2" then + for i = from_index + 1, 7 do + if inv:get_stack(from_list, i):get_name() ~= "" then + return 0 + end + end + + inv:set_stack(from_list, 6, "realchess:rook_black_2") + inv:set_stack(from_list, 8, "") + check = false + end + end + end + end + + if check then + if dx < 0 then + dx = -dx + end + + if dy < 0 then + dy = -dy + end + + if dx > 1 or dy > 1 then + return 0 + end + end + + if thisMove == "white" then + meta:set_int("castlingWhiteL", 0) + meta:set_int("castlingWhiteR", 0) + + elseif thisMove == "black" then + meta:set_int("castlingBlackL", 0) + meta:set_int("castlingBlackR", 0) + end + end + + local board = board_to_table(inv) + board[to_index] = board[from_index] + board[from_index] = "" + + local black_king_idx, white_king_idx = locate_kings(board) + 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 + return 0 + else + meta:set_string("blackAttacked", "true") + end + else + meta:set_string("blackAttacked", "") + end + + if whiteAttacked then + if thisMove == "white" and meta:get_string("whiteAttacked") == "true" then + return 0 + else + meta:set_string("whiteAttacked", "true") + end + else + meta:set_string("whiteAttacked", "") + end + + lastMove = thisMove + + meta:set_string("lastMove", lastMove) + meta:set_int("lastMoveTime", minetest.get_gametime()) + meta:set_string("playerWhite", playerWhite) + meta:set_string("playerBlack", playerBlack) + + 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_eaten_list(meta, pieceTo, pieceTo_s) + + return 1 +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, '') + + 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) + + return false +end + +local function timeout_format(timeout_limit) + local time_remaining = timeout_limit - minetest.get_gametime() + local minutes = math.floor(time_remaining / 60) + local seconds = time_remaining % 60 + + if minutes == 0 then + return seconds .. " sec." + end + + return minutes .. " min. " .. seconds .. " sec." +end + +function realchess.fields(pos, _, fields, sender) + local playerName = sender:get_player_name() + local meta = minetest.get_meta(pos) + local timeout_limit = meta:get_int("lastMoveTime") + 300 + local playerWhite = meta:get_string("playerWhite") + local playerBlack = meta:get_string("playerBlack") + local lastMoveTime = meta:get_int("lastMoveTime") + if fields.quit then 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 + if minetest.get_gametime() >= timeout_limit and + (playerWhite ~= playerName or playerBlack ~= playerName) then + realchess.init(pos) + else + minetest.chat_send_player(playerName, chat_prefix .. + "You can't reset the chessboard, a game has been started. " .. + "If you aren't a current player, try again in " .. + timeout_format(timeout_limit)) + end + end + end +end + +function realchess.dig(pos, player) + if not player then + return false + end + + local meta = minetest.get_meta(pos) + local playerName = player:get_player_name() + local timeout_limit = meta:get_int("lastMoveTime") + 300 + local lastMoveTime = meta:get_int("lastMoveTime") + + -- Timeout is 5 min. by default for digging the chessboard (non-players only) + return (lastMoveTime == 0 and minetest.get_gametime() > timeout_limit) or + minetest.chat_send_player(playerName, chat_prefix .. + "You can't dig the chessboard, a game has been started. " .. + "Reset it first if you're a current player, or dig it again in " .. + timeout_format(timeout_limit)) +end + +minetest.register_node(":realchess:chessboard", { + description = "Chess Board", + drawtype = "nodebox", + paramtype = "light", + paramtype2 = "facedir", + inventory_image = "chessboard_top.png", + wield_image = "chessboard_top.png", + tiles = {"chessboard_top.png", "chessboard_top.png", "chessboard_sides.png"}, + groups = {choppy=3, oddly_breakable_by_hand=2, flammable=3}, + sounds = default.node_sound_wood_defaults(), + node_box = {type = "fixed", fixed = {-.375, -.5, -.375, .375, -.4375, .375}}, + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple, + can_dig = realchess.dig, + on_construct = realchess.init, + on_receive_fields = realchess.fields, + allow_metadata_inventory_move = realchess.move, + on_metadata_inventory_move = realchess.on_move, + allow_metadata_inventory_take = function() return 0 end +}) + +local function register_piece(name, count) + for _, color in pairs({"black", "white"}) do + if not count then + minetest.register_craftitem(":realchess:" .. name .. "_" .. color, { + description = color:gsub("^%l", string.upper) .. " " .. name:gsub("^%l", string.upper), + inventory_image = name .. "_" .. color .. ".png", + stack_max = 1, + groups = {not_in_creative_inventory=1} + }) + else + for i = 1, count do + minetest.register_craftitem(":realchess:" .. name .. "_" .. color .. "_" .. i, { + description = color:gsub("^%l", string.upper) .. " " .. name:gsub("^%l", string.upper), + inventory_image = name .. "_" .. color .. ".png", + stack_max = 1, + groups = {not_in_creative_inventory=1} + }) + end + end + end +end + +register_piece("pawn", 8) +register_piece("rook", 2) +register_piece("knight", 2) +register_piece("bishop", 2) +register_piece("queen") +register_piece("king") + +-- Recipes + +minetest.register_craft({ + output = "realchess:chessboard", + recipe = { + {"dye:black", "dye:white", "dye:black"}, + {"stairs:slab_wood", "stairs:slab_wood", "stairs:slab_wood"} + } +}) diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/cooking.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/cooking.lua new file mode 100644 index 0000000..8cc2d38 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/cooking.lua @@ -0,0 +1,236 @@ +local cauldron, sounds = {}, {} + +-- Add more ingredients here that make a soup. +local ingredients_list = { + "apple", "mushroom", "honey", "pumpkin", "egg", "bread", "meat", + "chicken", "carrot", "potato", "melon", "rhubarb", "cucumber", + "corn", "beans", "berries", "grapes", "tomato", "wheat" +} + +cauldron.cbox = { + {0, 0, 0, 16, 16, 0}, + {0, 0, 16, 16, 16, 0}, + {0, 0, 0, 0, 16, 16}, + {16, 0, 0, 0, 16, 16}, + {0, 0, 0, 16, 8, 16} +} + +function cauldron.stop_sound(pos) + local spos = minetest.hash_node_position(pos) + if sounds[spos] then minetest.sound_stop(sounds[spos]) end +end + +function cauldron.idle_construct(pos) + local timer = minetest.get_node_timer(pos) + timer:start(10.0) + cauldron.stop_sound(pos) +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 + }) + + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Cauldron (active) - Drop some foods inside to make a soup") + + local timer = minetest.get_node_timer(pos) + timer:start(5.0) +end + +function cauldron.filling(pos, node, clicker, itemstack) + local inv = clicker:get_inventory() + local wield_item = clicker:get_wielded_item():get_name() + + if wield_item:sub(1,7) == "bucket:" then + if wield_item:sub(-6) == "_empty" and not (node.name:sub(-6) == "_empty") then + if itemstack:get_count() > 1 then + if inv:room_for_item("main", "bucket:bucket_water 1") then + itemstack:take_item() + inv:add_item("main", "bucket:bucket_water 1") + else + minetest.chat_send_player(clicker:get_player_name(), + "No room in your inventory to add a bucket of water.") + return itemstack + end + else + itemstack:replace("bucket:bucket_water") + end + 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}) + 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} + 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}) + return true +end + +-- Ugly hack to determine if an item has the function `minetest.item_eat` in its definition. +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 + + local ingredients = {} + for _, obj in pairs(objs) do + if obj and not obj:is_player() and obj:get_luaentity().itemstring then + local itemstring = obj:get_luaentity().itemstring + local food = itemstring:match(":([%w_]+)") + + for _, ingredient in pairs(ingredients_list) do + if food and (eatable(itemstring) or food:find(ingredient)) then + 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}) + end + + 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}) + end + return true +end + +function cauldron.take_soup(pos, node, clicker, itemstack) + local inv = clicker:get_inventory() + local wield_item = clicker:get_wielded_item() + + if wield_item:get_name() == "xdecor:bowl" then + if wield_item:get_count() > 1 then + if inv:room_for_item("main", "xdecor:bowl_soup 1") then + itemstack:take_item() + inv:add_item("main", "xdecor:bowl_soup 1") + else + minetest.chat_send_player(clicker:get_player_name(), + "No room in your inventory to add a bowl of soup.") + return itemstack + end + else + itemstack:replace("xdecor:bowl_soup 1") + end + + minetest.set_node(pos, {name="xdecor:cauldron_empty", param2=node.param2}) + end + return itemstack +end + +xdecor.register("cauldron_empty", { + description = "Cauldron", + groups = {cracky=2, oddly_breakable_by_hand=1}, + on_rotate = screwdriver.rotate_simple, + tiles = {"xdecor_cauldron_top_empty.png", "xdecor_cauldron_sides.png"}, + infotext = "Cauldron (empty)", + on_construct = function(pos) + cauldron.stop_sound(pos) + end, + on_rightclick = cauldron.filling, + collision_box = xdecor.pixelbox(16, cauldron.cbox) +}) + +xdecor.register("cauldron_idle", { + groups = {cracky=2, oddly_breakable_by_hand=1, not_in_creative_inventory=1}, + on_rotate = screwdriver.rotate_simple, + tiles = {"xdecor_cauldron_top_idle.png", "xdecor_cauldron_sides.png"}, + drop = "xdecor:cauldron_empty", + infotext = "Cauldron (idle)", + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.filling, + on_construct = cauldron.idle_construct, + on_timer = cauldron.idle_timer +}) + +xdecor.register("cauldron_boiling", { + 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) - 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"}, + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.filling, + on_construct = cauldron.boiling_construct, + 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}, + 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"}, + collision_box = xdecor.pixelbox(16, cauldron.cbox), + on_rightclick = cauldron.take_soup, + on_destruct = function(pos) + cauldron.stop_sound(pos) + end +}) + +-- Craft items + +minetest.register_craftitem("xdecor:bowl", { + description = "Bowl", + inventory_image = "xdecor_bowl.png", + wield_image = "xdecor_bowl.png", + groups = {food_bowl = 1, flammable = 2}, +}) + +minetest.register_craftitem("xdecor:bowl_soup", { + description = "Bowl of soup", + inventory_image = "xdecor_bowl_soup.png", + wield_image = "xdecor_bowl_soup.png", + groups = {not_in_creative_inventory=1}, + stack_max = 1, + on_use = minetest.item_eat(30, "xdecor:bowl") +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:bowl 3", + recipe = { + {"group:wood", "", "group:wood"}, + {"", "group:wood", ""} + } +}) + +minetest.register_craft({ + output = "xdecor:cauldron_empty", + recipe = { + {"default:iron_lump", "", "default:iron_lump"}, + {"default:iron_lump", "", "default:iron_lump"}, + {"default:iron_lump", "default:iron_lump", "default:iron_lump"} + } +}) diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/enchanting.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/enchanting.lua new file mode 100644 index 0000000..5e30d59 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/enchanting.lua @@ -0,0 +1,291 @@ +screwdriver = screwdriver or {} +local ceil, abs, random = math.ceil, math.abs, math.random + +-- Cost in Mese crystal(s) for enchanting. +local mese_cost = 1 + +-- Force of the enchantments. +local enchanting = { + uses = 1.2, -- Durability + times = 0.1, -- Efficiency + damages = 1, -- Sharpness +} + +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} + if orig_caps then + bonus.durable = to_percent(orig_caps.uses, orig_caps.uses * enchanting.uses) + local sum_caps_times = 0 + for i=1, #orig_caps.times do + sum_caps_times = sum_caps_times + orig_caps.times[i] + end + local average_caps_time = sum_caps_times / #orig_caps.times + 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.."%)"}, + } + return minetest.colorize and minetest.colorize(specs[enchant][1], + "\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,2.9;4,0.92;bg_btn.png;sharp;Sharpness]", +} + +function enchanting.formspec(pos, num) + local meta = minetest.get_meta(pos) + local formspec = [[ size[9,9;] + bgcolor[#080808BB;true] + background[0,0;9,9;ench_ui.png] + list[context;tool;0.9,2.9;1,1;] + list[context;mese;2,2.9;1,1;] + list[current_player;main;0.5,4.5;8,4;] + listring[current_player;main] + listring[context;tool] + listring[current_player;main] + listring[context;mese] + 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) + + formspec = formspec..(enchant_buttons[num] or "") + meta:set_string("formspec", formspec) +end + +function enchanting.on_put(pos, listname, _, stack) + if listname == "tool" then + local stackname = stack:get_name() + local tool_groups = { + "axe, pick, shovel", + "sword", + } + + for idx, tools in pairs(tool_groups) do + if tools:find(stackname:match(":(%w+)")) then + enchanting.formspec(pos, idx) + end + end + end +end + +function enchanting.fields(pos, _, fields, sender) + if not next(fields) or fields.quit then return end + local inv = minetest.get_meta(pos):get_inventory() + local tool = inv:get_stack("tool", 1) + 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) + + if mese:get_count() >= mese_cost and minetest.registered_tools[enchanted_tool] then + minetest.sound_play("xdecor_enchanting", { + to_player=sender:get_player_name(), gain=0.8}) + tool:replace(enchanted_tool) + tool:add_wear(orig_wear) + mese:take_item(mese_cost) + inv:set_stack("mese", 1, mese) + inv:set_stack("tool", 1, tool) + end +end + +function enchanting.dig(pos) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("tool") and inv:is_empty("mese") +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 + end + return false +end + +function enchanting.put(_, listname, _, stack) + local stackname = stack:get_name() + if listname == "mese" and stackname == "default:mese_crystal" then + return stack:get_count() + 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 +end + +function enchanting.construct(pos) + local meta = minetest.get_meta(pos) + meta:set_string("infotext", "Enchantment Table") + enchanting.formspec(pos, nil) + + 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") + local timer = minetest.get_node_timer(pos) + timer:start(0.5) +end + +function enchanting.destruct(pos) + for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.9)) do + if obj and obj:get_luaentity() and + obj:get_luaentity().name == "xdecor:book_open" then + obj:remove() + break + end + end +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") + 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 bookshelves = minetest.find_nodes_in_area(minp, maxp, "default:bookshelf") + 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 + minetest.add_particle({ + pos = bookshelf_pos, + 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" + }) + 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}, + light_source = 6, + sounds = default.node_sound_stone_defaults(), + on_rotate = screwdriver.rotate_simple, + can_dig = enchanting.dig, + on_timer = enchanting.timer, + on_construct = enchanting.construct, + on_destruct = enchanting.destruct, + on_receive_fields = enchanting.fields, + 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 +}) + +minetest.register_entity("xdecor:book_open", { + visual = "sprite", + visual_size = {x=0.75, y=0.75}, + collisionbox = {0}, + physical = false, + 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} + + if minetest.get_node(pos_under).name ~= "xdecor:enchantment_table" then + self.object:remove() + end + end +}) + +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] + if not original_tool then break end + local original_toolcaps = original_tool.tool_capabilities + + if original_toolcaps then + local original_damage_groups = original_toolcaps.damage_groups + local original_groupcaps = original_toolcaps.groupcaps + local groupcaps = table.copy(original_groupcaps) + local fleshy = original_damage_groups.fleshy + local full_punch_interval = original_toolcaps.full_punch_interval + local max_drop_level = original_toolcaps.max_drop_level + local group = next(original_groupcaps) + + if enchant == "durable" then + groupcaps[group].uses = ceil(original_groupcaps[group].uses * + enchanting.uses) + elseif enchant == "fast" then + for i, time in pairs(original_groupcaps[group].times) do + groupcaps[group].times[i] = time - enchanting.times + end + elseif enchant == "sharp" then + fleshy = fleshy + enchanting.damages + end + + 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", + wield_image = original_tool.wield_image, + groups = {not_in_creative_inventory=1}, + tool_capabilities = { + groupcaps = groupcaps, damage_groups = {fleshy = fleshy}, + full_punch_interval = full_punch_interval, + max_drop_level = max_drop_level + } + }) + end + end + end + end +end + +enchanting:register_tools("default", { + materials = "steel, bronze, mese, diamond", + tools = { + axe = {enchants = "durable, fast"}, + pick = {enchants = "durable, fast"}, + shovel = {enchants = "durable, fast"}, + sword = {enchants = "sharp"} + } +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:enchantment_table", + recipe = { + {"", "default:book", ""}, + {"default:diamond", "default:obsidian", "default:diamond"}, + {"default:obsidian", "default:obsidian", "default:obsidian"} + } +}) \ No newline at end of file diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/hive.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/hive.lua new file mode 100644 index 0000000..eb52901 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/hive.lua @@ -0,0 +1,91 @@ +local hive = {} +local honey_max = 16 + +function hive.construct(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + local formspec = [[ size[8,5;] + label[0.5,0;Bees are busy making honey...] + image[6,0;1,1;hive_bee.png] + image[5,0;1,1;hive_layout.png] + 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) + + meta:set_string("formspec", formspec) + meta:set_string("infotext", "Artificial Hive") + inv:set_size("honey", 1) + + local timer = minetest.get_node_timer(pos) + timer:start(math.random(64, 128)) +end + +function hive.timer(pos) + local time = (minetest.get_timeofday() or 0) * 24000 + 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) + local honey = honeystack:get_count() + + local radius = 4 + local minp = vector.add(pos, -radius) + local maxp = vector.add(pos, radius) + local flowers = minetest.find_nodes_in_area_under_air(minp, maxp, "group:flower") + + if #flowers > 2 and honey < honey_max then + inv:add_item("honey", "xdecor:honey") + elseif honey == honey_max then + local timer = minetest.get_node_timer(pos) + timer:stop() return true + end + return true +end + +xdecor.register("hive", { + description = "Artificial Hive", + tiles = {"xdecor_hive_top.png", "xdecor_hive_top.png", + "xdecor_hive_side.png", "xdecor_hive_side.png", + "xdecor_hive_side.png", "xdecor_hive_front.png"}, + 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(_, _, puncher) + puncher:set_hp(puncher:get_hp() - 2) + 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) + timer:start(math.random(64, 128)) + end + end +}) + +-- Craft items + +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) +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:hive", + recipe = { + {"group:stick", "group:stick", "group:stick"}, + {"default:paper", "default:paper", "default:paper"}, + {"group:stick", "group:stick", "group:stick"} + } +}) diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/init.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/init.lua new file mode 100644 index 0000000..0311b4d --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/init.lua @@ -0,0 +1,47 @@ +--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.."/alias.lua") +dofile(modpath.."/nodes.lua") +dofile(modpath.."/recipes.lua") + +local subpart = { + "chess", + "cooking", + "enchanting", + "hive", + "itemframe", + "mailbox", + "mechanisms", + "rope", + "workbench" +} + +for _, name in pairs(subpart) do + local enable = minetest.settings:get_bool("enable_xdecor_"..name) + if enable or enable == nil then + dofile(modpath.."/"..name..".lua") + end +end + +--print(string.format("[xdecor] loaded in %.2f ms", (os.clock()-t)*1000)) diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/itemframe.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/itemframe.lua new file mode 100644 index 0000000..5253224 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/itemframe.lua @@ -0,0 +1,171 @@ +local itemframe, tmp = {}, {} +screwdriver = screwdriver or {} + +local function remove_item(pos, node) + local objs = minetest.get_objects_inside_radius(pos, 0.5) + 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 + 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} +} + +local function update_item(pos, node) + remove_item(pos, node) + local meta = minetest.get_meta(pos) + local itemstring = meta:get_string("item") + local posad = facedir[node.param2] + if not posad or itemstring == "" then return end + + pos = vector.add(pos, vector.multiply(posad, 6.5/16)) + tmp.nodename = node.name + 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 timer = minetest.get_node_timer(pos) + timer:start(15.0) +end + +local function drop_item(pos, node) + local meta = minetest.get_meta(pos) + local item = meta:get_string("item") + if item == "" then return end + + minetest.add_item(pos, item) + meta:set_string("item", "") + remove_item(pos, node) + + local timer = minetest.get_node_timer(pos) + timer:stop() +end + +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..")") +end + +function itemframe.timer(pos) + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local num = #minetest.get_objects_inside_radius(pos, 0.5) + + if num == 0 and meta:get_string("item") ~= "" then + update_item(pos, node) + end + return true +end + +function itemframe.rightclick(pos, node, clicker, itemstack) + local meta = minetest.get_meta(pos) + local player_name = clicker:get_player_name() + local owner = meta:get_string("owner") + local admin = minetest.check_player_privs(player_name, "protection_bypass") + + if not admin and (player_name ~= owner or not itemstack) then + return itemstack + end + + drop_item(pos, node) + local itemstring = itemstack:take_item():to_string() + meta:set_string("item", itemstring) + update_item(pos, node) + + return itemstack +end + +function itemframe.punch(pos, node, puncher) + local meta = minetest.get_meta(pos) + local player_name = puncher:get_player_name() + 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) +end + +function itemframe.dig(pos, player) + if not player then return end + local meta = minetest.get_meta(pos) + local player_name = player and player:get_player_name() + local owner = meta:get_string("owner") + local admin = minetest.check_player_privs(player_name, "protection_bypass") + + return admin or player_name == owner +end + +xdecor.register("itemframe", { + description = "Item Frame", + 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"}, + after_place_node = itemframe.after_place, + on_timer = itemframe.timer, + on_rightclick = itemframe.rightclick, + on_punch = itemframe.punch, + can_dig = itemframe.dig, + after_destruct = remove_item +}) + +minetest.register_entity("xdecor:f_item", { + visual = "wielditem", + visual_size = {x=0.33, y=0.33}, + collisionbox = {0}, + physical = false, + textures = {"air"}, + on_activate = function(self, staticdata) + local pos = self.object:getpos() + if minetest.get_node(pos).name ~= "xdecor:itemframe" then + self.object:remove() + end + + if tmp.nodename and tmp.texture then + self.nodename = tmp.nodename + tmp.nodename = nil + self.texture = tmp.texture + tmp.texture = nil + elseif staticdata and staticdata ~= "" then + local data = staticdata:split(";") + if data and data[1] and data[2] then + self.nodename = data[1] + self.texture = data[2] + end + end + if self.texture then + 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 + end + return "" + end +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:itemframe", + recipe = { + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "default:paper", "group:stick"}, + {"group:stick", "group:stick", "group:stick"} + } +}) \ No newline at end of file diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/mailbox.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/mailbox.lua new file mode 100644 index 0000000..5c2dcd2 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/mailbox.lua @@ -0,0 +1,174 @@ +local mailbox = {} +screwdriver = screwdriver or {} + +local function get_img(img) + local img_name = img:match("(.*)%.png") + 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 def.inventory_image ~= "" then + local img = get_img(def.inventory_image) + if img then return img end + end + + if def.tiles then + local tile, img = def.tiles[1] + if type(tile) == "table" then + img = get_img(tile.name) + elseif type(tile) == "string" then + img = get_img(tile) + 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 meta = minetest.get_meta(pos) + local giver, img = "", "" + + if is_owner then + for i = 1, 7 do + local giving = meta:get_string("giver"..i) + if giving ~= "" then + 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," + end + end + + return [[ size[9.5,9] + label[0,0;Mailbox] + label[6,0;Last donators] + 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) + end + 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) +end + +function mailbox.dig(pos, player) + local meta = minetest.get_meta(pos) + local owner = meta:get_string("owner") + local player_name = player and player:get_player_name() + local inv = meta:get_inventory() + + return inv:is_empty("mailbox") and player_name == owner +end + +function mailbox.after_place_node(pos, placer) + local meta = minetest.get_meta(pos) + local player_name = placer:get_player_name() + + meta:set_string("owner", player_name) + meta:set_string("infotext", player_name.."'s Mailbox") + + local inv = meta:get_inventory() + inv:set_size("mailbox", 6*4) + inv:set_size("drop", 1) +end + +function mailbox.rightclick(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) + local player = clicker:get_player_name() + local owner = meta:get_string("owner") + + minetest.show_formspec(player, "xdecor:mailbox", mailbox:formspec(pos, + owner, (player == owner))) + return itemstack +end + +function mailbox.put(pos, listname, _, stack, player) + if listname == "drop" then + local inv = minetest.get_meta(pos):get_inventory() + if inv:room_for_item("mailbox", stack) then + return -1 + else + minetest.chat_send_player(player:get_player_name(), + "The mailbox is full") + end + end + return 0 +end + +function mailbox.on_put(pos, listname, _, stack, player) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + if listname == "drop" and inv:room_for_item("mailbox", stack) then + inv:set_list("drop", {}) + 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))) + end + + meta:set_string("giver1", player:get_player_name()) + meta:set_string("stack1", stack:to_string()) + end +end + +function mailbox.allow_take(pos, listname, index, stack, player) + local meta = minetest.get_meta(pos) + + if player:get_player_name() ~= meta:get_string("owner") then + return 0 + end + return stack:get_count() +end + +function mailbox.allow_move(pos) + return 0 +end + +xdecor.register("mailbox", { + description = "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}, + on_rotate = screwdriver.rotate_simple, + can_dig = mailbox.dig, + on_rightclick = mailbox.rightclick, + allow_metadata_inventory_take = mailbox.allow_take, + allow_metadata_inventory_move = mailbox.allow_move, + on_metadata_inventory_put = mailbox.on_put, + allow_metadata_inventory_put = mailbox.put, + after_place_node = mailbox.after_place_node +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:mailbox", + recipe = { + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"dye:red", "default:paper", "dye:red"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"} + } +}) \ No newline at end of file diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/mechanisms.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/mechanisms.lua new file mode 100644 index 0000000..b065c90 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/mechanisms.lua @@ -0,0 +1,141 @@ +-- Thanks to sofar for helping with that code. + +minetest.setting_set("nodetimer_interval", 0.1) + +local plate = {} +screwdriver = screwdriver or {} + +local function door_toggle(pos_actuator, pos_door, player) + local player_name = player:get_player_name() + local actuator = minetest.get_node(pos_actuator) + local door = doors.get(pos_door) + + if actuator.name:sub(-4) == "_off" then + minetest.set_node(pos_actuator, + {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}) + end + -- Re-get player object (or nil) because 'player' could + -- be an invalid object at this time (player left) + door:close(minetest.get_player_by_name(player_name)) + end) +end + +function plate.construct(pos) + local timer = minetest.get_node_timer(pos) + timer:start(0.1) +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 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 + 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 + +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} +}) + +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}, + 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 doors = minetest.find_nodes_in_area(minp, maxp, "group:door") + + for i=1, #doors do + door_toggle(pos, doors[i], clicker) + end + return itemstack + end +}) + +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}, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + on_rotate = screwdriver.rotate_simple, + drop = "xdecor:lever_off" +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:pressure_stone_off", + type = "shapeless", + recipe = {"group:stone", "group:stone"} +}) + +minetest.register_craft({ + output = "xdecor:pressure_wood_off", + type = "shapeless", + recipe = {"group:wood", "group:wood"} +}) + +minetest.register_craft({ + output = "xdecor:lever_off", + recipe = { + {"group:stick"}, + {"group:stone"} + } +}) \ No newline at end of file diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/nodes.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/nodes.lua new file mode 100644 index 0000000..20bd72e --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/nodes.lua @@ -0,0 +1,490 @@ +screwdriver = screwdriver or {} + +local function register_pane(name, desc, def) + xpanes.register_pane(name, { + description = desc, + 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", + groups = def.groups, + sounds = def.sounds or default.node_sound_defaults(), + recipe = def.recipe + }) +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"}} +}) + +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"}} +}) + +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"}} +}) + +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"}} +}) + +xdecor.register("baricade", { + description = "Baricade", + drawtype = "plantlike", + paramtype2 = "facedir", + inventory_image = "xdecor_baricade.png", + tiles = {"xdecor_baricade.png"}, + 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}}) +}) + +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}, + 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}, + 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}, + 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"} +}) + +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"} +}) + +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"} +}) + +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"}, +}) + +xdecor.register("candle", { + description = "Candle", + light_source = 12, + drawtype = "torchlike", + inventory_image = "xdecor_candle_inv.png", + 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}} + }, + selection_box = { + type = "wallmounted", + wall_top = {-0.25, -0.5, -0.25, 0.25, 0.1, 0.25}, + wall_bottom = {-0.25, -0.5, -0.25, 0.25, 0.1, 0.25}, + wall_side = {-0.5, -0.35, -0.15, -0.15, 0.4, 0.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}, + 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} + }), + can_dig = xdecor.sit_dig, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 -- Sitting position + xdecor.sit(pos, node, clicker, pointed_thing) + return itemstack + end +}) + +xdecor.register("cobweb", { + description = "Cobweb", + drawtype = "plantlike", + tiles = {"xdecor_cobweb.png"}, + inventory_image = "xdecor_cobweb.png", + liquid_viscosity = 8, + liquidtype = "source", + liquid_alternative_flowing = "xdecor:cobweb", + liquid_alternative_source = "xdecor:cobweb", + liquid_renewable = false, + liquid_range = 0, + walkable = false, + selection_box = {type = "regular"}, + groups = {snappy=3, liquid=3, flammable=3}, + sounds = default.node_sound_leaves_defaults() +}) + +local curtain_colors = { + "red", +} + +for _, c in pairs(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.. + ":170^xdecor_curtain_open_overlay.png^[makealpha:255,126,126", + wield_image = "wool_white.png^[colorize:"..c..":170", + drawtype = "signlike", + paramtype2 = "colorwallmounted", + 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}) + return itemstack + end + }) + + 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}, + selection_box = {type="wallmounted"}, + drop = "xdecor:curtain_"..c, + on_rightclick = function(pos, node, _, itemstack) + 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, ""}} + }) +end + +xdecor.register("cushion", { + description = "Cushion", + tiles = {"xdecor_cushion.png"}, + 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, + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + pos.y = pos.y + 0 -- Sitting position + xdecor.sit(pos, node, clicker, pointed_thing) + return itemstack + end +}) + +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} +}) + +local function door_access(name) + return name:find("prison") +end + +local xdecor_doors = { + japanese = { + {"group:wood", "default:paper"}, + {"default:paper", "group:wood"}, + {"group:wood", "default:paper"} }, + prison = { + {"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"} }, + screen = { + {"group:wood", "group:wood"}, + {"xpanes:chainlink_flat", "xpanes:chainlink_flat"}, + {"group:wood", "group:wood"} }, + slide = { + {"default:paper", "default:paper"}, + {"default:paper", "default:paper"}, + {"group:wood", "group:wood"} }, + woodglass = { + {"default:glass", "default:glass"}, + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"} } +} + +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", + protected = door_access(name), + groups = {choppy=2, cracky=2, oddly_breakable_by_hand=1, door=1}, + recipe = recipe + }) +end + +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}, + sounds = default.node_sound_stone_defaults(), + on_rotate = screwdriver.rotate_simple, + on_construct = function(pos) + local meta = minetest.get_meta(pos) + meta:set_string("formspec", [[ size[8,9] + list[current_player;enderchest;0,0;8,4;] + list[current_player;main;0,5;8,4;] + listring[current_player;enderchest] + listring[current_player;main] ]] + ..xbg..default.get_hotbar_bg(0,5)) + meta:set_string("infotext", "Ender Chest") + end +}) + +minetest.register_on_joinplayer(function(player) + local inv = player:get_inventory() + inv:set_size("enderchest", 8*4) +end) + +xdecor.register("ivy", { + description = "Ivy", + drawtype = "signlike", + walkable = false, + climbable = true, + groups = {snappy=3, flora=1, attached_node=1, plant=1, flammable=3}, + paramtype2 = "wallmounted", + selection_box = {type="wallmounted"}, + tiles = {"xdecor_ivy.png"}, + inventory_image = "xdecor_ivy.png", + wield_image = "xdecor_ivy.png", + sounds = default.node_sound_leaves_defaults() +}) + +xdecor.register("lantern", { + description = "Lantern", + light_source = 13, + drawtype = "plantlike", + inventory_image = "xdecor_lantern_inv.png", + 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}}}, + 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}, + light_source = 13, + sounds = default.node_sound_glass_defaults() + }) +end + +for _, f in pairs({"dandelion_white", "dandelion_yellow", "geranium", + "rose", "tulip", "viola"}) do + 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", + 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", ""}} + }) +end + +local painting_box = { + type = "wallmounted", + wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125}, + wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, + wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375} +} + +xdecor.register("painting_1", { + description = "Painting", + tiles = {"xdecor_painting_1.png"}, + inventory_image = "xdecor_painting_empty.png", + wield_image = "xdecor_painting_empty.png", + paramtype2 = "wallmounted", + sunlight_propagates = true, + 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) + 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"}, + 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}, + sounds = default.node_sound_wood_defaults(), + node_box = painting_box + }) +end + +xdecor.register("stonepath", { + description = "Garden Stone Path", + tiles = {"default_stone.png"}, + groups = {snappy=3}, + on_rotate = screwdriver.rotate_simple, + sounds = default.node_sound_stone_defaults(), + sunlight_propagates = true, + node_box = xdecor.pixelbox(16, { + {8, 0, 8, 6, .5, 6}, {1, 0, 1, 6, .5, 6}, + {1, 0, 10, 5, .5, 5}, {10, 0, 2, 4, .5, 4} + }), + selection_box = xdecor.nodebox.slab_y(0.05) +}) + +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}, + sounds = def.sounds or default.node_sound_stone_defaults() + }) +end + +register_hard_node("cactusbrick", "Cactus Brick") +register_hard_node("coalstone_tile", "Coal Stone Tile") +register_hard_node("desertstone_tile", "Desert Stone Tile") +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}, + sounds = default.node_sound_glass_defaults() +}) +register_hard_node("wood_tile", "Wooden Tile", { + 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}, + 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} + }) +}) + +xdecor.register("tatami", { + description = "Tatami", + tiles = {"xdecor_tatami.png"}, + wield_image = "xdecor_tatami.png", + groups = {snappy=3, flammable=3}, + sunlight_propagates = true, + node_box = xdecor.nodebox.slab_y(0.0625) +}) + +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}, + node_box = xdecor.nodebox.slab_y(0.5), + sounds = {footstep = {name="xdecor_bouncy", gain=0.8}} +}) + +xdecor.register("tv", { + description = "Television", + light_source = 11, + 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}} } +}) + +xdecor.register("woodframed_glass", { + description = "Wood Framed 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}, + sounds = default.node_sound_glass_defaults() +}) diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/oldcoder.txt b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/oldcoder.txt new file mode 100644 index 0000000..410f42a --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/oldcoder.txt @@ -0,0 +1,35 @@ +Name: xdecor +Source: Modified version of upstream mod - Do not replace +License: See "LICENSE" + +---------------------------------------------------------------------- + +1. This is a modified version of an upstream mod. The starting point +was obtained initially as follows: + + rm -fr xdecor + git clone https://github.com/minetest-mods/xdecor.git + +---------------------------------------------------------------------- + +2. Changes include: + +2a. Replaced the contents of "depends.txt" with: + +bucket +default +doors +fire? +moreblocks? +oresplus? +stairs +xpanes + +2b. Removed screenshot file(s). + +2c. Added the files "00README" and "oldcoder.txt" (this file). + +---------------------------------------------------------------------- + +3. This mod shouldn't be replaced with an upstream version unless cha- +nge (2a) is duplicated in the new copy. diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/recipes.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/recipes.lua new file mode 100644 index 0000000..cb7ad19 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/recipes.lua @@ -0,0 +1,267 @@ +minetest.register_craft({ + output = "xdecor:baricade", + recipe = { + {"group:stick", "", "group:stick"}, + {"", "default:steel_ingot", ""}, + {"group:stick", "", "group:stick"} + } +}) + +minetest.register_craft({ + output = "xdecor:barrel", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"default:iron_lump", "", "default:iron_lump"}, + {"group:wood", "group:wood", "group:wood"} + } +}) + +minetest.register_craft({ + output = "xdecor:candle", + recipe = { + {"default:torch"} + } +}) + +minetest.register_craft({ + output = "xdecor:cabinet", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"doors:trapdoor", "", "doors:trapdoor"}, + {"group:wood", "group:wood", "group:wood"} + } +}) + +minetest.register_craft({ + output = "xdecor:cabinet_half 2", + recipe = { + {"xdecor:cabinet"} + } +}) + +minetest.register_craft({ + output = "xdecor:cactusbrick", + recipe = { + {"default:brick", "default:cactus"} + } +}) + +minetest.register_craft({ + output = "xdecor:chair", + recipe = { + {"group:stick", "", ""}, + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "", "group:stick"} + } +}) + +minetest.register_craft({ + output = "xdecor:coalstone_tile 4", + recipe = { + {"default:coalblock", "default:stone"}, + {"default:stone", "default:coalblock"} + } +}) + +minetest.register_craft({ + output = "xdecor:cobweb", + recipe = { + {"farming:cotton", "", "farming:cotton"}, + {"", "farming:cotton", ""}, + {"farming:cotton", "", "farming:cotton"} + } +}) + +minetest.register_craft({ + output = "xdecor:cushion 3", + recipe = { + {"wool:red", "wool:red", "wool:red"} + } +}) + +minetest.register_craft({ + output = "xdecor:cushion_block", + recipe = { + {"xdecor:cushion"}, + {"xdecor:cushion"} + } +}) + +minetest.register_craft({ + output = "xdecor:desertstone_tile", + recipe = { + {"default:desert_cobble", "default:desert_cobble"}, + {"default:desert_cobble", "default:desert_cobble"} + } +}) + +minetest.register_craft({ + output = "xdecor:empty_shelf", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"", "", ""}, + {"group:wood", "group:wood", "group:wood"} + } +}) + +minetest.register_craft({ + output = "xdecor:enderchest", + recipe = { + {"", "default:obsidian", ""}, + {"default:obsidian", "default:chest", "default:obsidian"}, + {"", "default:obsidian", ""} + } +}) + +minetest.register_craft({ + output = "xdecor:hard_clay", + recipe = { + {"default:clay", "default:clay"}, + {"default:clay", "default:clay"} + } +}) + +minetest.register_craft({ + output = "xdecor:iron_lightbox", + recipe = { + {"xpanes:bar_flat", "default:torch", "xpanes:bar_flat"}, + {"xpanes:bar_flat", "default:glass", "xpanes:bar_flat"}, + {"xpanes:bar_flat", "default:torch", "xpanes:bar_flat"} + } +}) + +minetest.register_craft({ + output = "xdecor:ivy 4", + recipe = { + {"group:leaves"}, + {"group:leaves"} + } +}) + +minetest.register_craft({ + output = "xdecor:lantern", + recipe = { + {"default:iron_lump"}, + {"default:torch"}, + {"default:iron_lump"} + } +}) + +minetest.register_craft({ + output = "xdecor:moonbrick", + recipe = { + {"default:brick", "default:stone"} + } +}) + +minetest.register_craft({ + output = "xdecor:multishelf", + recipe = { + {"group:wood", "group:wood", "group:wood"}, + {"group:vessel", "group:book", "group:vessel"}, + {"group:wood", "group:wood", "group:wood"} + } +}) + +minetest.register_craft({ + output = "xdecor:packed_ice", + recipe = { + {"default:ice", "default:ice"}, + {"default:ice", "default:ice"} + } +}) + +minetest.register_craft({ + output = "xdecor:painting_1", + recipe = { + {"default:sign_wall_wood", "dye:blue"} + } +}) + +minetest.register_craft({ + output = "xdecor:stone_tile 2", + recipe = { + {"default:cobble", "default:cobble"}, + {"default:cobble", "default:cobble"} + } +}) + +minetest.register_craft({ + output = "xdecor:stone_rune 4", + recipe = { + {"default:stone", "default:stone", "default:stone"}, + {"default:stone", "", "default:stone"}, + {"default:stone", "default:stone", "default:stone"} + } +}) + +minetest.register_craft({ + output = "xdecor:stonepath 16", + recipe = { + {"stairs:slab_cobble", "", "stairs:slab_cobble"}, + {"", "stairs:slab_cobble", ""}, + {"stairs:slab_cobble", "", "stairs:slab_cobble"} + } +}) + +minetest.register_craft({ + output = "xdecor:table", + recipe = { + {"stairs:slab_wood", "stairs:slab_wood", "stairs:slab_wood"}, + {"", "group:stick", ""}, + {"", "group:stick", ""} + } +}) + +minetest.register_craft({ + output = "xdecor:tatami", + recipe = { + {"farming:wheat", "farming:wheat", "farming:wheat"} + } +}) + +minetest.register_craft({ + output = "xdecor:trampoline", + recipe = { + {"farming:string", "farming:string", "farming:string"}, + {"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "xdecor:tv", + recipe = { + {"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"}, + {"default:steel_ingot", "default:glass", "default:steel_ingot"}, + {"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"} + } +}) + +minetest.register_craft({ + output = "xdecor:woodframed_glass", + recipe = { + {"group:stick", "group:stick", "group:stick"}, + {"group:stick", "default:glass", "group:stick"}, + {"group:stick", "group:stick", "group:stick"} + } +}) + +minetest.register_craft({ + output = "xdecor:wood_tile 2", + recipe = { + {"", "group:wood", ""}, + {"group:wood", "", "group:wood"}, + {"", "group:wood", ""} + } +}) + +minetest.register_craft({ + output = "xdecor:wooden_lightbox", + recipe = { + {"group:stick", "default:torch", "group:stick"}, + {"group:stick", "default:glass", "group:stick"}, + {"group:stick", "default:torch", "group:stick"} + } +}) + diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/rope.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/rope.lua new file mode 100644 index 0000000..b6d9452 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/rope.lua @@ -0,0 +1,68 @@ +local rope = {} + +-- Code by Mirko K. (modified by Temperest, Wulfsdad and kilbith) (License: GPL). +function rope.place(itemstack, placer, pointed_thing) + if pointed_thing.type == "node" then + 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 + + while oldnode.name == "air" and not itemstack:is_empty() do + local newnode = {name = stackname, param1 = 0} + minetest.set_node(pos, newnode) + itemstack:take_item() + pos.y = pos.y - 1 + 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 digger_inv = digger:get_inventory() + + while minetest.get_node(below).name == rope_name do + minetest.remove_node(below) + 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 + +xdecor.register("rope", { + description = "Rope", + drawtype = "plantlike", + walkable = false, + climbable = true, + 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") + end + end +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:rope", + recipe = { + {"farming:string"}, + {"farming:string"}, + {"farming:string"} + } +}) \ No newline at end of file diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/settingtypes.txt b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/settingtypes.txt new file mode 100644 index 0000000..f75d75c --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/settingtypes.txt @@ -0,0 +1,11 @@ +#For enabling a subpart of X-Decor. + +enable_xdecor_chess (Enable Chess) bool true +enable_xdecor_cooking (Enable Cooking) bool true +enable_xdecor_enchanting (Enable Enchanting) bool true +enable_xdecor_hive (Enable Hive) bool true +enable_xdecor_itemframe (Enable Itemframe) bool true +enable_xdecor_mailbox (Enable Mailbox) bool true +enable_xdecor_mechanisms (Enable Mechanisms) bool true +enable_xdecor_rope (Enable Rope) bool true +enable_xdecor_workbench (Enable Workbench) bool true \ No newline at end of file diff --git a/patches/Bucket_Game-patched/mods/coderbuild/xdecor/workbench.lua b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/workbench.lua new file mode 100644 index 0000000..ad69361 --- /dev/null +++ b/patches/Bucket_Game-patched/mods/coderbuild/xdecor/workbench.lua @@ -0,0 +1,317 @@ +local workbench = {} +WB = {} +screwdriver = screwdriver or {} +local min, ceil = math.min, math.ceil +local registered_nodes = minetest.registered_nodes + +-- Nodes allowed to be cut +-- Only the regular, solid blocks without metas or explosivity can be cut +local nodes = {} +for node, def in pairs(registered_nodes) do + if xdecor.stairs_valid_def(def) then + nodes[#nodes+1] = node + end +end + +-- Optionally, you can register custom cuttable nodes in the workbench +WB.custom_nodes_register = { + -- "default:leaves", +} + +setmetatable(nodes, { + __concat = function(t1, t2) + for i=1, #t2 do + t1[#t1+1] = t2[i] + end + return t1 + end +}) + +nodes = nodes..WB.custom_nodes_register + +-- Nodeboxes definitions +workbench.defs = { + -- Name Yield X Y Z W H 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 }}, + {"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 }}, + {"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 }}, + {"stair", 1, nil }, + {"innerstair", 1, { 0, 0, 0, 16, 8, 16 }, + { 0, 8, 8, 16, 8, 8 }, + { 0, 8, 0, 8, 8, 8 }} +} + +-- 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 + end + return false +end + +function workbench:get_output(inv, input, name) + local output = {} + 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 + end + + inv:set_list("forms", output) +end + +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] ]], + -- 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] ]], + -- Storage formspec + [[ list[context;storage;0,1;8,2;] + button[0,0;1.5,1;back;< Back] + listring[context;storage] + listring[current_player;main] ]] +} + +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)) +end + +function workbench.construct(pos) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + inv:set_size("tool", 1) + inv:set_size("input", 1) + inv:set_size("hammer", 1) + inv:set_size("forms", 4*3) + inv:set_size("storage", 8*2) + + meta:set_string("infotext", "Work Bench") + workbench:set_formspec(meta, 1) +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 + if not id then return end + workbench:set_formspec(meta, id) +end + +function workbench.dig(pos) + local inv = minetest.get_meta(pos):get_inventory() + return inv:is_empty("input") and inv:is_empty("hammer") and + inv:is_empty("tool") and inv:is_empty("storage") +end + +function workbench.timer(pos) + local timer = minetest.get_node_timer(pos) + local inv = minetest.get_meta(pos):get_inventory() + local tool = inv:get_stack("tool", 1) + local hammer = inv:get_stack("hammer", 1) + + if tool:is_empty() or hammer:is_empty() or tool:get_wear() == 0 then + timer:stop() + return + end + + -- 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 + (listname == "hammer" and stackname == "xdecor:hammer") or + listname == "storage" then + return stack:get_count() + end + return 0 +end + +function workbench.move(_, from_list, _, to_list, _, count) + return (to_list == "storage" and from_list ~= "forms") and count or 0 +end + +function workbench.on_put(pos, listname, _, stack) + local inv = minetest.get_meta(pos):get_inventory() + if listname == "input" then + local input = inv:get_stack("input", 1) + workbench:get_output(inv, input, stack:get_name()) + elseif listname == "tool" or listname == "hammer" then + local timer = minetest.get_node_timer(pos) + timer:start(3.0) + end +end + +function workbench.on_take(pos, listname, index, stack, player) + local inv = minetest.get_meta(pos):get_inventory() + local input = inv:get_stack("input", 1) + local inputname = input:get_name() + local stackname = stack:get_name() + + if listname == "input" then + if stackname == inputname and registered_nodes[inputname.."_cube"] then + workbench:get_output(inv, input, stackname) + else + inv:set_list("forms", {}) + end + elseif listname == "forms" then + local fromstack = inv:get_stack(listname, index) + if not fromstack:is_empty() and fromstack:get_name() ~= stackname then + local player_inv = player:get_inventory() + if player_inv:room_for_item("main", fromstack) then + player_inv:add_item("main", fromstack) + end + end + + input:take_item(ceil(stack:get_count() / workbench.defs[index][2])) + inv:set_stack("input", 1, input) + workbench:get_output(inv, input, inputname) + end +end + +xdecor.register("workbench", { + description = "Work Bench", + 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"}, + on_rotate = screwdriver.rotate_simple, + can_dig = workbench.dig, + on_timer = workbench.timer, + on_construct = workbench.construct, + on_receive_fields = workbench.fields, + on_metadata_inventory_put = workbench.on_put, + on_metadata_inventory_take = workbench.on_take, + allow_metadata_inventory_put = workbench.put, + allow_metadata_inventory_move = workbench.move +}) + +for _, d in pairs(workbench.defs) do +for i=1, #nodes do + local node = nodes[i] + local def = registered_nodes[node] + + if d[3] then + local groups = {} + local tiles + groups.not_in_creative_inventory = 1 + + for k, v in pairs(def.groups) do + if k ~= "wood" and k ~= "stone" and k ~= "level" then + groups[k] = v + end + end + + if def.tiles then + if #def.tiles > 1 and (def.drawtype:sub(1,5) ~= "glass") then + tiles = def.tiles + else + tiles = {def.tiles[1]} + end + else + 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) + end + + minetest.register_node(":"..node.."_"..d[1], { + description = def.description.." "..d[1]:gsub("^%l", string.upper), + paramtype = "light", + paramtype2 = "facedir", + drawtype = "nodebox", + sounds = def.sounds, + tiles = tiles, + groups = groups, + -- `unpack` has been changed to `table.unpack` in newest Lua versions + node_box = xdecor.pixelbox(16, {unpack(d, 3)}), + sunlight_propagates = true, + on_place = minetest.rotate_node + }) + end +end +end + +-- Craft items + +minetest.register_tool("xdecor:hammer", { + description = "Hammer", + inventory_image = "xdecor_hammer.png", + wield_image = "xdecor_hammer.png", + on_use = function() do return end end +}) + +-- Recipes + +minetest.register_craft({ + output = "xdecor:hammer", + recipe = { + {"default:steel_ingot", "group:stick", "default:steel_ingot"}, + {"", "group:stick", ""} + } +}) + +minetest.register_craft({ + output = "xdecor:workbench", + recipe = { + {"group:wood", "group:wood"}, + {"group:wood", "group:wood"} + } +})