capturetheflag/mods/ctf/ctf_map/chest.lua

219 lines
6.8 KiB
Lua
Raw Normal View History

local blacklist = {
"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
2019-03-17 01:36:15 +00:00
minetest.register_node("ctf_map: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", 4 * 7)
inv:set_size("pro", 4 * 7)
inv:set_size("helper", 1 * 1)
end,
on_rightclick = function(pos, node, player)
local name = player:get_player_name()
if chest_color ~= ctf.player(name).team then
minetest.chat_send_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
2019-03-17 01:36:15 +00:00
ctf.warning("ctf_map", "Unowned team chest")
minetest.set_node(pos, { name = "air" })
return
end
ctf.warning("ctf_map", "Wrong chest, changing to " ..
territory_owner .. " from " .. chest_color)
2019-03-17 01:36:15 +00:00
minetest.set_node(pos, "ctf_map:chest_" .. territory_owner)
end
local formspec = table.concat({
"size[8,12]",
default.gui_bg,
default.gui_bg_img,
default.gui_slots,
default.get_hotbar_bg(0,7.85),
"list[current_player;main;0,7.85;8,1;]",
"list[current_player;main;0,9.08;8,3;8]",
}, "")
local pstat = ctf_stats.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 try to capture the flag.\n" ..
"Find resources in chests scattered around the map."
formspec = formspec .. "label[0.75,3;" .. minetest.formspec_escape(msg) .. "]"
minetest.show_formspec(name, "ctf_map:no_access", formspec)
return
end
local is_pro = get_is_player_pro(pstat)
local chestinv = "nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z
formspec = formspec .. "list[" .. chestinv .. ";main;0,0.3;4,7;]" ..
"background[4,-0.2;4.15,7.7;ctf_map_pro_section.png;false]"
if is_pro then
formspec = formspec .. "list[" .. chestinv .. ";pro;4,0.3;4,7;]" ..
"listring[" .. chestinv ..";pro]" ..
2018-12-30 23:08:55 +00:00
"listring[" .. chestinv .. ";helper]" ..
"label[5,-0.2;" ..
minetest.formspec_escape("Pro players only") .. "]"
else
formspec = formspec .. "label[4.75,3;" ..
minetest.formspec_escape("You need at least 1000" ..
"\nscore and 1.5+ KD to\naccess the pro section") .. "]"
end
formspec = formspec ..
2018-12-30 23:08:55 +00:00
"listring[" .. chestinv ..";main]" ..
"listring[current_player;main]"
minetest.show_formspec(name, "ctf_map:chest", formspec)
end,
allow_metadata_inventory_move = function(pos, from_list, from_index,
to_list, to_index, count, player)
local name = player:get_player_name()
if chest_color ~= ctf.player(name).team then
minetest.chat_send_player(name, "You're not on team " .. chest_color)
return 0
end
local pstat = ctf_stats.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
2018-12-30 23:08:55 +00:00
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)
2018-12-30 23:08:55 +00:00
if listname == "helper" then
return 0
end
local name = player:get_player_name()
if chest_color ~= ctf.player(name).team then
minetest.chat_send_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(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
2018-12-30 23:08:55 +00:00
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)
2018-12-30 23:08:55 +00:00
if listname == "helper" then
return 0
end
local name = player:get_player_name()
if chest_color ~= ctf.player(name).team then
minetest.chat_send_player(name, "You're not on team " .. chest_color)
return 0
end
local pstat = ctf_stats.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