local blacklist = { "default:pick_wood", "default:axe_wood", "default:shovel_wood", "default:sword_wood", "default:leaves", "default:jungleleaves", "default:pine_needles", "default:acacia_leaves", "default:aspen_leaves" } local function max(a, b) return (a > b) and a or b end local function get_is_player_pro(pstat) local kd = pstat.kills / max(pstat.deaths, 1) return pstat.score > 1000 and kd > 1.5 end local colors = {"red", "blue"} for _, chest_color in pairs(colors) do minetest.register_node("ctf_team_base:chest_" .. chest_color, { description = "Chest", tiles = { "default_chest_top_" .. chest_color .. ".png", "default_chest_top_" .. chest_color .. ".png", "default_chest_side_" .. chest_color .. ".png", "default_chest_side_" .. chest_color .. ".png", "default_chest_side_" .. chest_color .. ".png", "default_chest_front_" .. chest_color .. ".png"}, paramtype2 = "facedir", groups = {immortal = 1, team_chest=1}, legacy_facedir_simple = true, is_ground_content = false, sounds = default.node_sound_wood_defaults(), on_construct = function(pos) local meta = minetest.get_meta(pos) meta:set_string("infotext", "Chest") local inv = meta:get_inventory() inv:set_size("main", 5*4) inv:set_size("pro", 3*4) inv:set_size("helper", 1*1) end, on_rightclick = function(pos, node, player) if chest_color ~= ctf.player(player:get_player_name()).team then minetest.chat_send_player(player:get_player_name(), "You're not on team " .. chest_color) return end local territory_owner = ctf.get_territory_owner(pos) if chest_color ~= territory_owner then if not territory_owner then ctf.warning("ctf_team_base", "Unowned team chest") minetest.set_node(pos, { name = "air" }) return end ctf.warning("ctf_team_base", "Wrong chest, changing to " .. territory_owner .. " from " .. chest_color) minetest.set_node(pos, "ctf_team_base:chest_" .. territory_owner) end local formspec = table.concat({ "size[8,9]", default.gui_bg, default.gui_bg_img, default.gui_slots, "list[current_player;main;0,4.85;8,1;]", "list[current_player;main;0,6.08;8,3;8]", }, "") local pstat = ctf_stats.player(player:get_player_name()) if not pstat or not pstat.score or pstat.score < 10 then local msg = "You need at least 10 score to access the team chest.\n" .. "Try killing an enemy player, or at least attempting to capture the flag.\n" .. "Find resources in chests scattered around the map." formspec = formspec .. "label[1,1;" .. minetest.formspec_escape(msg) .. "]" minetest.show_formspec(player:get_player_name(), "ctf_team_base:no_access", formspec) return end local is_pro = get_is_player_pro(pstat) local chestinv = "nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z formspec = formspec .. "label[0,-0.2;" .. minetest.formspec_escape("Any team member can take from here") .. "]" .. "list[" .. chestinv .. ";main;0,0.3;5,4;]" .. "background[5,-0.2;3.15,4.7;ctf_team_base_pro_only.png;false]" .. "list[" .. chestinv .. ";pro;5,0.3;3,4;]" if is_pro then formspec = formspec .. "listring[" .. chestinv ..";pro]" .. "listring[" .. chestinv .. ";helper]" .. "label[5,-0.2;" .. minetest.formspec_escape("Pro players only (1k+ score, 1.5+ KD)") .. "]" else formspec = formspec .. "label[5,-0.2;" .. minetest.formspec_escape("You need 1k+ score and 1.5+ KD") .. "]" end formspec = formspec .. "listring[" .. chestinv ..";main]" .. "listring[current_player;main]" .. default.get_hotbar_bg(0,4.85) minetest.show_formspec(player:get_player_name(), "ctf_team_base:chest", formspec) end, allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) if chest_color ~= ctf.player(player:get_player_name()).team then minetest.chat_send_player(player:get_player_name(), "You're not on team " .. chest_color) return 0 end local pstat = ctf_stats.player(player:get_player_name()) if not pstat or not pstat.score or pstat.score < 10 then return 0 end if (from_list ~= "pro" and to_list ~= "pro") or get_is_player_pro(pstat) then if to_list == "helper" then -- handle move & overflow local chestinv = minetest.get_inventory({type = "node", pos = pos}) local playerinv = player:get_inventory() local stack = chestinv:get_stack(from_list, from_index) local leftover = playerinv:add_item("main", stack) local n_stack = stack n_stack:set_count(stack:get_count() - leftover:get_count()) chestinv:remove_item("helper", stack) chestinv:remove_item("pro", n_stack) return 0 elseif from_list == "helper" then return 0 else return count end else return 0 end end, allow_metadata_inventory_put = function(pos, listname, index, stack, player) if listname == "helper" then return 0 end if chest_color ~= ctf.player(player:get_player_name()).team then minetest.chat_send_player(player:get_player_name(), "You're not on team " .. chest_color) return 0 end for _, itemstring in ipairs(blacklist) do if stack:get_name() == itemstring then return 0 end end local pstat = ctf_stats.player(player:get_player_name()) if not pstat or not pstat.score or pstat.score < 10 then return 0 end if listname ~= "pro" or get_is_player_pro(pstat) then local chestinv = minetest.get_inventory({type = "node", pos = pos}) if chestinv:room_for_item("pro", stack) then return stack:get_count() else -- handle overflow local playerinv = player:get_inventory() local leftovers = chestinv:add_item("pro", stack) local leftover = chestinv:add_item("main", leftovers) local n_stack = stack n_stack:set_count(stack:get_count() - leftover:get_count()) playerinv:remove_item("main", n_stack) return 0 end else return 0 end end, allow_metadata_inventory_take = function(pos, listname, index, stack, player) if listname == "helper" then return 0 end if chest_color ~= ctf.player(player:get_player_name()).team then minetest.chat_send_player(player:get_player_name(), "You're not on team " .. chest_color) return 0 end local pstat = ctf_stats.player(player:get_player_name()) if not pstat or not pstat.score or pstat.score < 10 then return 0 end if listname ~= "pro" or get_is_player_pro(pstat) then return stack:get_count() else return 0 end end, can_dig = function(pos, player) return false end, on_metadata_inventory_put = function(pos, listname, index, stack, player) minetest.log("action", player:get_player_name() .. " moves " .. (stack:get_name() or "stuff") .. " " .. (stack:get_count() or 0) .. " to chest at " .. minetest.pos_to_string(pos)) end, on_metadata_inventory_take = function(pos, listname, index, stack, player) minetest.log("action", player:get_player_name() .. " takes " .. (stack:get_name() or "stuff") .. " " .. (stack:get_count() or 0) .. " from chest at " .. minetest.pos_to_string(pos)) end }) end