poikilos
6 years ago
committed by
Jacob Gustafson
18 changed files with 3322 additions and 0 deletions
@ -0,0 +1 @@ |
|||||
|
See "oldcoder.txt". |
@ -0,0 +1,39 @@ |
|||||
|
┌──────────────────────────────────────────────────────────────────────┐ |
||||
|
│ Copyright (c) 2015-2017 kilbith <jeanpatrick.guerrero@gmail.com> │ |
||||
|
│ │ |
||||
|
│ 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. |
@ -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/ |
@ -0,0 +1 @@ |
|||||
|
minetest.register_alias("xdecor:crafting_guide", "craftguide:book") |
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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)) |
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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() |
||||
|
}) |
@ -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. |
@ -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"} |
||||
|
} |
||||
|
}) |
||||
|
|
@ -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"} |
||||
|
} |
||||
|
}) |
@ -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 |
@ -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"} |
||||
|
} |
||||
|
}) |
Loading…
Reference in new issue