xdecor-libre/src/mailbox.lua
2023-07-10 19:52:38 +02:00

210 lines
5.6 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

local mailbox = {}
screwdriver = screwdriver or {}
local S = minetest.get_translator("xdecor")
local FS = function(...) return minetest.formspec_escape(S(...)) end
-- Max. length of the list of givers in mailbox formspec
local GIVER_LIST_LENGTH = 7
local function get_img(img)
if not img then return end
local img_name = img:match("(.*)%.png")
if img_name then
return img_name .. ".png"
end
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, GIVER_LIST_LENGTH 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
-- List of donors. A line looks like this:
-- <donor name> <item icon> × <item count>
giver = giver .. "#FFFF00," .. giver_name .. "," .. i ..
-- Times a certain item count; used for the mailbox donor list
",#FFFFFF," .. FS("× @1", stack_count) .. ","
img = img .. i .. "=" ..
img_col(stack_name) .. "^\\[resize:16x16,"
end
end
return "size[9.5,9]"
.."label[0,0;"..FS("Mailbox").."]"
.."label[6,0;"..FS("Last donators").."]"
..[[ box[6,0.72;3.3,3.9;#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;"..FS("Send your goods to\n@1",
(minetest.colorize and
minetest.colorize("#FFFF00", owner) or owner)) .. "]" ..
"list[nodemeta:" .. spos .. ";drop;3.5,0;1,1;]" ..
"listring[]" ..
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.blast(pos)
return
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", S("@1's Mailbox", player_name))
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(),
S("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 = GIVER_LIST_LENGTH, 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)
if listname == "drop" then
return 0
end
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 = S("Mailbox"),
_tt_help = S("Lets other players give you things"),
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},
sounds = default.node_sound_metal_defaults(),
on_rotate = screwdriver.rotate_simple,
can_dig = mailbox.dig,
on_blast = mailbox.blast,
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"}
}
})