Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add feature to steal from enemy teamchest while it is open in classic #1321

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mods/ctf/ctf_teamitems/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ctf_core.include_files("team_chest.lua", "team_door.lua")
2 changes: 2 additions & 0 deletions mods/ctf/ctf_teamitems/mod.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name = ctf_teamitems
depends = ctf_core, ctf_modebase, ctf_teams
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,41 @@ local item_value = {
}
--]]

local open_chests = {
-- team_color = {
-- opener0,
-- opener1,
-- opener2,
-- ...
-- },
-- ...
}

local function is_chest_open(team_name)
if open_chests[team_name] and #open_chests[team_name] ~= 0 then
return true
else
return false
end
end


local function can_open_teamchest(teamname, pname)
if ctf_teams.get(pname) == teamname then
return true
elseif ctf_modebase.flag_captured[teamname] then
return true
elseif is_chest_open(teamname) and ctf_modebase.current_mode == "classic" then
return true
else
return false
end
end

local function get_chest_access(name)
local current_mode = ctf_modebase:get_current_mode()
if not current_mode then return false, false end
if not current_mode then
return false, false
end

return current_mode.get_chest_access(name)
end
Expand All @@ -79,17 +107,20 @@ function ctf_teams.is_allowed_in_team_chest(listname, stack, player)
return true
end

local TEAMCHEST_FORMSPEC_NAME = "ctf_teamitemss:chest"

for _, team in ipairs(ctf_teams.teamlist) do
if not ctf_teams.team[team].not_playing then
local chestcolor = ctf_teams.team[team].color
local team_name = tostring(team)
local function get_chest_texture(chest_side, color, mask, extra)
return string.format(
"(default_chest_%s.png" ..
"^[colorize:%s:130)" ..
"^(default_chest_%s.png" ..
"^[mask:ctf_teams_chest_%s_mask.png" ..
"^[colorize:%s:60)" ..
"%s",
"(default_chest_%s.png"
.. "^[colorize:%s:130)"
.. "^(default_chest_%s.png"
.. "^[mask:ctf_teamitems_chest_%s_mask.png"
.. "^[colorize:%s:60)"
.. "%s",
chest_side,
color,
chest_side,
Expand All @@ -99,26 +130,48 @@ for _, team in ipairs(ctf_teams.teamlist) do
)
end

minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= TEAMCHEST_FORMSPEC_NAME then
return
end
if fields.quit ~= "true" then
return
end

local pname = player:get_player_name()
if pname == "" then
return
end
local pteam = ctf_teams.get(pname)
for idx, name in ipairs(open_chests[pteam] or {}) do
if name == pname then
table.remove(open_chests[pteam], idx)
end
end
end)
local def = {
description = HumanReadable(team).." Team's Chest",
description = HumanReadable(team) .. " Team's Chest",
tiles = {
get_chest_texture("top", chestcolor, "top"),
get_chest_texture("top", chestcolor, "top"),
get_chest_texture("side", chestcolor, "side"),
get_chest_texture("side", chestcolor, "side"),
get_chest_texture("side", chestcolor, "side"),
get_chest_texture("front", chestcolor, "side", "^ctf_teams_lock.png"),
get_chest_texture("front", chestcolor, "side", "^ctf_teamitems_lock.png"),
},
paramtype2 = "facedir",
groups = {immortal = 1, team_chest=1},
groups = { immortal = 1, team_chest = 1 },
legacy_facedir_simple = true,
is_ground_content = false,
sounds = default.node_sound_wood_defaults(),
}

function def.on_construct(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", string.format("%s Team's Chest", HumanReadable(team)))
meta:set_string(
"infotext",
string.format("%s Team's Chest", HumanReadable(team))
)

local inv = meta:get_inventory()
inv:set_size("main", 6 * 7)
Expand All @@ -132,20 +185,33 @@ for _, team in ipairs(ctf_teams.teamlist) do

function def.on_rightclick(pos, node, player)
local name = player:get_player_name()

local flag_captured = ctf_modebase.flag_captured[team]
if not flag_captured and team ~= ctf_teams.get(name) then
local flag_captured = ctf_modebase.flag_captured[team_name]
minetest.log("info", "open_chests" .. minetest.serialize(open_chests))
if not can_open_teamchest(team_name, name) then
hud_events.new(player, {
quick = true,
text = "You're not on team " .. team,
color = "warning",
})
return
end
if ctf_teams.get(name) == team_name then
if not open_chests[team_name] then
open_chests[team_name] = {}
end
table.insert(open_chests[team_name], name)
minetest.after(30, function()
for idx, name2 in ipairs(open_chests[team_name]) do
if name2 == name then
table.remove(open_chests[team_name], idx)
end
end
end)
end

local formspec = table.concat({
"size[10,12]",
default.get_hotbar_bg(1,7.85),
default.get_hotbar_bg(1, 7.85),
"list[current_player;main;1,7.85;8,1;]",
"list[current_player;main;1,9.08;8,3;8]",
}, "")
Expand All @@ -158,46 +224,72 @@ for _, team in ipairs(ctf_teams.teamlist) do
end

if reg_access ~= true then
formspec = formspec .. "label[0.75,3;" ..
minetest.formspec_escape(minetest.wrap_text(
reg_access or "You aren't allowed to access the team chest",
60
)) ..
"]"

minetest.show_formspec(name, "ctf_teams:no_access", formspec)
formspec = formspec
.. "label[0.75,3;"
.. minetest.formspec_escape(
minetest.wrap_text(
reg_access or "You aren't allowed to access the team chest",
60
)
)
.. "]"

minetest.show_formspec(name, "ctf_teamitems:no_access", formspec)
return
end

local chestinv = "nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z

formspec = formspec .. "list[" .. chestinv .. ";main;0,0.3;6,7;]" ..
"background[6,-0.2;4.15,7.7;ctf_map_pro_section.png;false]"
formspec = formspec
.. "list["
.. chestinv
.. ";main;0,0.3;6,7;]"
.. "background[6,-0.2;4.15,7.7;ctf_map_pro_section.png;false]"

if pro_access == true then
formspec = formspec .. "list[" .. chestinv .. ";pro;6,0.3;4,7;]" ..
"listring[" .. chestinv ..";pro]" ..
"listring[" .. chestinv .. ";helper]" ..
"label[7,-0.2;" ..
minetest.formspec_escape("Pro players only") .. "]"
formspec = formspec
.. "list["
.. chestinv
.. ";pro;6,0.3;4,7;]"
.. "listring["
.. chestinv
.. ";pro]"
.. "listring["
.. chestinv
.. ";helper]"
.. "label[7,-0.2;"
.. minetest.formspec_escape("Pro players only")
.. "]"
else
formspec = formspec .. "label[6.5,2;" ..
minetest.formspec_escape(minetest.wrap_text(
pro_access or "You aren't allowed to access the pro section",
20
)) ..
"]"
formspec = formspec
.. "label[6.5,2;"
.. minetest.formspec_escape(
minetest.wrap_text(
pro_access or "You aren't allowed to access the pro section",
20
)
)
.. "]"
end

formspec = formspec ..
"listring[" .. chestinv ..";main]" ..
"listring[current_player;main]"
formspec = formspec
.. "listring["
.. chestinv
.. ";main]"
.. "listring[current_player;main]"

minetest.show_formspec(name, "ctf_teams:chest", formspec)
minetest.show_formspec(name, TEAMCHEST_FORMSPEC_NAME, formspec)
end

function def.allow_metadata_inventory_move(pos, from_list, from_index,
to_list, to_index, count, player)
function def.allow_metadata_inventory_move(
pos,
from_list,
from_index,
to_list,
to_index,
count,
player
)
local name = player:get_player_name()

if team ~= ctf_teams.get(name) then
Expand All @@ -211,10 +303,13 @@ for _, team in ipairs(ctf_teams.teamlist) do

local reg_access, pro_access = get_chest_access(name)

if reg_access == true and (pro_access == true or from_list ~= "pro" and to_list ~= "pro") then
if
reg_access == true
and (pro_access == true or from_list ~= "pro" and to_list ~= "pro")
then
if to_list == "helper" then
-- handle move & overflow
local chestinv = minetest.get_inventory({type = "node", pos = pos})
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)
Expand Down Expand Up @@ -252,7 +347,7 @@ for _, team in ipairs(ctf_teams.teamlist) do
local reg_access, pro_access = get_chest_access(name)

if reg_access == true and (pro_access == true or listname ~= "pro") then
local chestinv = minetest.get_inventory({type = "node", pos = pos})
local chestinv = minetest.get_inventory({ type = "node", pos = pos })
if chestinv:room_for_item("pro", stack) then
return stack:get_count()
else
Expand Down Expand Up @@ -281,7 +376,7 @@ for _, team in ipairs(ctf_teams.teamlist) do

local name = player:get_player_name()

if team ~= ctf_teams.get(name) then
if not can_open_teamchest(team_name, name) then
hud_events.new(player, {
quick = true,
text = "You're not on team " .. team,
Expand All @@ -299,38 +394,63 @@ for _, team in ipairs(ctf_teams.teamlist) do
end
end


function def.on_metadata_inventory_put(pos, listname, index, stack, player)
minetest.log("action", string.format("%s puts %s to team chest at %s",
player:get_player_name(),
stack:to_string(),
minetest.pos_to_string(pos)
))
local meta = stack:get_meta()
local dropped_by = meta:get_string("dropped_by")
local pname = player:get_player_name()
if dropped_by ~= pname and dropped_by ~= "" then
local cur_mode = ctf_modebase:get_current_mode()
if pname and cur_mode then
--local score = (item_value[stack:get_name()] or 0) * stack:get_count()
cur_mode.recent_rankings.add(pname, { score = 1 }, false)
function def.on_metadata_inventory_put(pos, listname, index, stack, player)
minetest.log(
"action",
string.format(
"%s puts %s to team chest at %s",
player:get_player_name(),
stack:to_string(),
minetest.pos_to_string(pos)
)
)
local meta = stack:get_meta()
local dropped_by = meta:get_string("dropped_by")
local pname = player:get_player_name()
if dropped_by ~= pname and dropped_by ~= "" then
local cur_mode = ctf_modebase:get_current_mode()
if pname and cur_mode then
--local score = (item_value[stack:get_name()] or 0) * stack:get_count()
cur_mode.recent_rankings.add(pname, { score = 1 }, false)
end
end
meta:set_string("dropped_by", "")
local inv = minetest.get_inventory({ type = "node", pos = pos })
local stack_ = inv:get_stack(listname, index)
stack_:get_meta():set_string("dropped_by", "")
inv:set_stack(listname, index, stack_)
end
meta:set_string("dropped_by", "")
local inv = minetest.get_inventory({ type="node", pos=pos })
local stack_ = inv:get_stack(listname,index)
stack_:get_meta():set_string("dropped_by", "")
inv:set_stack(listname, index, stack_)
end

function def.on_metadata_inventory_take(pos, listname, index, stack, player)
minetest.log("action", string.format("%s takes %s from team chest at %s",
player:get_player_name(),
stack:to_string(),
minetest.pos_to_string(pos)
))
minetest.log(
"action",
string.format(
"%s takes %s from team chest at %s",
player:get_player_name(),
stack:to_string(),
minetest.pos_to_string(pos)
)
)
if ctf_teams.get(player:get_player_name()) ~= team_name then
for _i = 1, stack:get_count(), 0 do
minetest.sound_play(
{ name = "ctf_teamitems_teamchest_steal" },
{ pos = pos, max_hearing_distance = 12 }
)
end
for pname, pteam in pairs(ctf_teams.player_team) do
if pteam == team then
hud_events.new(pname, {
text = player:get_player_name()
.. " is stealing from your team's chest!",
color = "warning",
quick = true,
})
end
end
end
end

minetest.register_node("ctf_teams:chest_" .. team, def)
minetest.register_node("ctf_teamitems:chest_" .. team, def)
end
end
Loading