capturetheflag/mods/ctf_team_base/chest.lua

172 lines
6.2 KiB
Lua

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"}
local chest_name_to_team = {}
for _, chest_color in pairs(colors) do
chest_name_to_team["ctf_team_base:chest_" .. chest_color] = chest_color
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)
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
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[current_name;pro]" ..
"label[5,-0.2;" .. minetest.formspec_escape("Pro players only (1k+ score, good KD)") .. "]"
else
formspec = formspec .. "listring[current_name;pro]" ..
"label[5,-0.2;" .. minetest.formspec_escape("You need 1k+ score and good KD") .. "]"
end
formspec = formspec ..
"listring[current_name;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)
local meta = minetest.get_meta(pos)
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
return count
else
return 0
end
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, 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 listname ~= "pro" or get_is_player_pro(pstat) then
return stack:get_count()
else
return 0
end
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
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
minetest.register_abm({
nodenames = {"group:team_chest"},
interval = 10, -- Run every 10 seconds
chance = 1, -- Select every 1 in 50 nodes
action = function(pos, node, active_object_count, active_object_count_wider)
local current_owner = assert(chest_name_to_team[node.name])
local territory_owner = ctf.get_territory_owner(pos)
if territory_owner and current_owner ~= territory_owner then
ctf.warning("ctf_team_base", "Wrong chest, changing to " .. territory_owner .. " from " .. current_owner)
minetest.set_node(pos, { name = "ctf_team_base:chest_" .. territory_owner })
end
end
})