Decouple ctf_flag
This commit is contained in:
parent
821edc9637
commit
a1b24f73e1
@ -1,133 +1,33 @@
|
|||||||
ctf.area = {}
|
ctf.area = {}
|
||||||
|
|
||||||
-- add a flag to a team
|
function ctf.area.get_territory_owner(pos)
|
||||||
function ctf.area.add_flag(team,pos)
|
local largest = nil
|
||||||
if not team or team == "" then
|
local largest_weight = 0
|
||||||
return
|
for i = 1, #ctf.registered_on_territory_query do
|
||||||
|
local team, weight = ctf.registered_on_territory_query[i](pos)
|
||||||
|
if team and weight then
|
||||||
|
if weight == -1 then
|
||||||
|
return team
|
||||||
end
|
end
|
||||||
|
if weight > largest_weight then
|
||||||
if not ctf.team(team).flags then
|
largest = team
|
||||||
ctf.team(team).flags = {}
|
largest_weight = weight
|
||||||
end
|
|
||||||
|
|
||||||
pos.team = team
|
|
||||||
table.insert(ctf.team(team).flags,pos)
|
|
||||||
ctf.save()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- get a flag from a team
|
|
||||||
function ctf.area.get_flag(pos)
|
|
||||||
if not pos then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local result = nil
|
|
||||||
for _, team in pairs(ctf.teams) do
|
|
||||||
for i = 1, #team.flags do
|
|
||||||
if (
|
|
||||||
team.flags[i].x == pos.x and
|
|
||||||
team.flags[i].y == pos.y and
|
|
||||||
team.flags[i].z == pos.z
|
|
||||||
) then
|
|
||||||
if result then
|
|
||||||
minetest.chat_send_all("[CTF ERROR] Multiple teams have same flag. Please report this to the server operator / admin")
|
|
||||||
print("CTF ERROR DATA")
|
|
||||||
print("Multiple teams have same flag.")
|
|
||||||
print("This is a sign of ctf.txt corruption.")
|
|
||||||
print("----------------")
|
|
||||||
print(dump(result))
|
|
||||||
print(dump(team.flags[i]))
|
|
||||||
print("----------------")
|
|
||||||
else
|
|
||||||
result = team.flags[i]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
return largest
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
-- delete a flag from a team
|
|
||||||
function ctf.area.delete_flag(team, pos)
|
|
||||||
if not team or team == "" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for i = 1, #ctf.team(team).flags do
|
|
||||||
if (
|
|
||||||
ctf.team(team).flags[i].x == pos.x and
|
|
||||||
ctf.team(team).flags[i].y == pos.y and
|
|
||||||
ctf.team(team).flags[i].z == pos.z
|
|
||||||
) then
|
|
||||||
table.remove(ctf.team(team).flags,i)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Gets the nearest flag in a 25 metre radius block
|
|
||||||
function ctf.area.nearest_flag(pos)
|
|
||||||
if not pos then
|
|
||||||
ctf.error("No position provided to nearest_flag()")
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local nodes = minetest.find_nodes_in_area(
|
|
||||||
{
|
|
||||||
x = pos.x - ctf.setting("flag.protect_distance"),
|
|
||||||
y = pos.y - ctf.setting("flag.protect_distance"),
|
|
||||||
z = pos.z - ctf.setting("flag.protect_distance")
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x = pos.x + ctf.setting("flag.protect_distance"),
|
|
||||||
y = pos.y + ctf.setting("flag.protect_distance"),
|
|
||||||
z = pos.z + ctf.setting("flag.protect_distance")
|
|
||||||
},
|
|
||||||
{"group:is_flag"}
|
|
||||||
)
|
|
||||||
|
|
||||||
if nodes then
|
|
||||||
local closest = nil
|
|
||||||
local _dis = 1000
|
|
||||||
|
|
||||||
for a = 1, #nodes do
|
|
||||||
local this_dis = vector.distance(pos, nodes[a])
|
|
||||||
if this_dis < _dis then
|
|
||||||
closest = nodes[a]
|
|
||||||
_dis = this_dis
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return closest
|
|
||||||
end
|
|
||||||
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- gets the name of the owner of that location
|
|
||||||
function ctf.area.get_area(pos)
|
|
||||||
local closest = ctf.area.nearest_flag(pos)
|
|
||||||
if not closest then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
local flag = ctf.area.get_flag(closest)
|
|
||||||
|
|
||||||
if flag then
|
|
||||||
return flag.team
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- updates the spawn position for a team
|
-- updates the spawn position for a team
|
||||||
function ctf.area.get_spawn(team)
|
function ctf.area.get_spawn(team)
|
||||||
ctf.area.asset_flags(team)
|
ctf_flag.asset_flags(team)
|
||||||
|
|
||||||
if not ctf.team(team) then
|
if not ctf.team(team) then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
if ctf.team(team).spawn and minetest.env:get_node(ctf.team(team).spawn).name == "ctf:flag" then
|
if ctf.team(team).spawn and minetest.env:get_node(ctf.team(team).spawn).name == "ctf:flag" then
|
||||||
local flag = ctf.area.get_flag(ctf.team(team).spawn)
|
local flag = ctf_flag.get(ctf.team(team).spawn)
|
||||||
|
|
||||||
if not flag then
|
if not flag then
|
||||||
return nil
|
return nil
|
||||||
@ -148,24 +48,6 @@ function ctf.area.get_spawn(team)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ctf.area.asset_flags(team)
|
|
||||||
--[[
|
|
||||||
if not team or not ctf.team(team) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
ctf.log("utils", "Checking the flags of "..team)
|
|
||||||
|
|
||||||
local tmp = ctf.team(team).flags
|
|
||||||
local get_res = minetest.env:get_node(tmp[i])
|
|
||||||
for i=1,#tmp do
|
|
||||||
if tmp[i] and (not get_res or not get_res.name == "ctf:flag") then
|
|
||||||
ctf.log("utils", "Replacing flag...")
|
|
||||||
-- TODO: ctf.area.asset_flags
|
|
||||||
end
|
|
||||||
end]]--
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_respawnplayer(function(player)
|
minetest.register_on_respawnplayer(function(player)
|
||||||
if player and ctf.player(player:get_player_name()) then
|
if player and ctf.player(player:get_player_name()) then
|
||||||
local team = ctf.player(player:get_player_name()).team
|
local team = ctf.player(player:get_player_name()).team
|
||||||
|
@ -15,6 +15,17 @@ ctf.registered_on_new_team = {}
|
|||||||
function ctf.register_on_new_team(func)
|
function ctf.register_on_new_team(func)
|
||||||
table.insert(ctf.registered_on_new_team, func)
|
table.insert(ctf.registered_on_new_team, func)
|
||||||
end
|
end
|
||||||
|
ctf.registered_on_territory_query = {}
|
||||||
|
function ctf.register_on_territory_query(func)
|
||||||
|
table.insert(ctf.registered_on_territory_query, func)
|
||||||
|
end
|
||||||
|
|
||||||
|
function vector.distanceSQ(p1, p2)
|
||||||
|
local x = p1.x - p2.x
|
||||||
|
local y = p1.y - p2.y
|
||||||
|
local z = p1.z - p2.z
|
||||||
|
return x*x + y*y + z*z
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ ctf_flag = {
|
|||||||
on_rightclick_top = function(pos, node, clicker)
|
on_rightclick_top = function(pos, node, clicker)
|
||||||
pos.y=pos.y-1
|
pos.y=pos.y-1
|
||||||
|
|
||||||
local flag = ctf.area.get_flag(pos)
|
local flag = ctf_flag.get(pos)
|
||||||
if not flag then
|
if not flag then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -26,7 +26,7 @@ ctf_flag = {
|
|||||||
ctf.gui.flag_board(clicker:get_player_name(),pos)
|
ctf.gui.flag_board(clicker:get_player_name(),pos)
|
||||||
end,
|
end,
|
||||||
on_rightclick = function(pos, node, clicker)
|
on_rightclick = function(pos, node, clicker)
|
||||||
local flag = ctf.area.get_flag(pos)
|
local flag = ctf_flag.get(pos)
|
||||||
if not flag then
|
if not flag then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -49,7 +49,7 @@ ctf_flag = {
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local flag = ctf.area.get_flag(pos)
|
local flag = ctf_flag.get(pos)
|
||||||
if not flag then
|
if not flag then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -111,11 +111,11 @@ ctf_flag = {
|
|||||||
end
|
end
|
||||||
ctf.team(team).spawn = nil
|
ctf.team(team).spawn = nil
|
||||||
if ctf.setting("flag.allow_multiple") == true then
|
if ctf.setting("flag.allow_multiple") == true then
|
||||||
ctf.area.delete_flag(team,pos)
|
ctf_flag.delete(team,pos)
|
||||||
ctf.area.add_flag(ctf.player(player).team,pos)
|
ctf_flag.add(ctf.player(player).team,pos)
|
||||||
else
|
else
|
||||||
minetest.env:set_node(pos,{name="air"})
|
minetest.env:set_node(pos,{name="air"})
|
||||||
ctf.area.delete_flag(team,pos)
|
ctf_flag.delete(team,pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
ctf.save()
|
ctf.save()
|
||||||
@ -148,11 +148,11 @@ ctf_flag = {
|
|||||||
fteam.spawn = nil
|
fteam.spawn = nil
|
||||||
local fpos = {x=ctf.claimed[i].x,y=ctf.claimed[i].y,z=ctf.claimed[i].z}
|
local fpos = {x=ctf.claimed[i].x,y=ctf.claimed[i].y,z=ctf.claimed[i].z}
|
||||||
if ctf.setting("flag.allow_multiple") == true then
|
if ctf.setting("flag.allow_multiple") == true then
|
||||||
ctf.area.delete_flag(fteam.data.name,fpos)
|
ctf_flag.delete(fteam.data.name,fpos)
|
||||||
ctf.area.add_flag(ctf.claimed[i].claimed.team,fpos)
|
ctf_flag.add(ctf.claimed[i].claimed.team,fpos)
|
||||||
else
|
else
|
||||||
minetest.env:set_node(fpos,{name="air"})
|
minetest.env:set_node(fpos,{name="air"})
|
||||||
ctf.area.delete_flag(fteam.data.name,fpos)
|
ctf_flag.delete(fteam.data.name,fpos)
|
||||||
end
|
end
|
||||||
ctf.collect_claimed()
|
ctf.collect_claimed()
|
||||||
end
|
end
|
||||||
@ -178,7 +178,7 @@ ctf_flag = {
|
|||||||
meta:set_string("infotext", team.."'s flag")
|
meta:set_string("infotext", team.."'s flag")
|
||||||
|
|
||||||
-- add flag
|
-- add flag
|
||||||
ctf.area.add_flag(team,pos)
|
ctf_flag.add(team, pos)
|
||||||
|
|
||||||
if ctf.teams[team].spawn and minetest.env:get_node(ctf.teams[team].spawn).name == "ctf_flag:flag" then
|
if ctf.teams[team].spawn and minetest.env:get_node(ctf.teams[team].spawn).name == "ctf_flag:flag" then
|
||||||
if not ctf.setting("flag.allow_multiple") then
|
if not ctf.setting("flag.allow_multiple") then
|
||||||
|
@ -70,7 +70,7 @@ end)
|
|||||||
-- Flag interface
|
-- Flag interface
|
||||||
function ctf.gui.flag_board(name,pos)
|
function ctf.gui.flag_board(name,pos)
|
||||||
ctf.log("gui", name .. " views flag board")
|
ctf.log("gui", name .. " views flag board")
|
||||||
local flag = ctf.area.get_flag(pos)
|
local flag = ctf_flag.get(pos)
|
||||||
if not flag then
|
if not flag then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -123,7 +123,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if fields.save and fields.flag_name then
|
if fields.save and fields.flag_name then
|
||||||
local flag = ctf.area.get_flag(ctf.gui.flag_data[name].pos)
|
local flag = ctf_flag.get(ctf.gui.flag_data[name].pos)
|
||||||
if not flag then
|
if not flag then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -156,7 +156,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
elseif fields.delete then
|
elseif fields.delete then
|
||||||
local pos = ctf.gui.flag_data[name].pos
|
local pos = ctf.gui.flag_data[name].pos
|
||||||
|
|
||||||
local flag = ctf.area.get_flag(ctf.gui.flag_data[name].pos)
|
local flag = ctf_flag.get(ctf.gui.flag_data[name].pos)
|
||||||
|
|
||||||
if not flag then
|
if not flag then
|
||||||
return
|
return
|
||||||
@ -171,7 +171,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
ctf.area.delete_flag(team,pos)
|
ctf_flag.delete(team,pos)
|
||||||
|
|
||||||
minetest.env:set_node(pos,{name="air"})
|
minetest.env:set_node(pos,{name="air"})
|
||||||
pos.y=pos.y+1
|
pos.y=pos.y+1
|
||||||
|
@ -9,10 +9,113 @@ init()
|
|||||||
ctf.register_on_new_team(function(team)
|
ctf.register_on_new_team(function(team)
|
||||||
team.flags = {}
|
team.flags = {}
|
||||||
end)
|
end)
|
||||||
|
ctf.register_on_territory_query(function(pos)
|
||||||
|
local closest = nil
|
||||||
|
local closest_team = nil
|
||||||
|
local closest_distSQ = 1000000
|
||||||
|
local pd = ctf.setting("flag.protect_distance")
|
||||||
|
local pdSQ = pd * pd
|
||||||
|
|
||||||
|
for tname, team in pairs(ctf.teams) do
|
||||||
|
for i = 1, #team.flags do
|
||||||
|
local distSQ = vector.distanceSQ(pos, team.flags[i])
|
||||||
|
if distSQ < pdSQ and distSQ < closest_distSQ then
|
||||||
|
closest = team.flags[i]
|
||||||
|
closest_team = tname
|
||||||
|
closest_distSQ = distSQ
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return closest_team, closest_distSQ
|
||||||
|
end)
|
||||||
ctf_flag = {}
|
ctf_flag = {}
|
||||||
dofile(minetest.get_modpath("ctf_flag") .. "/gui.lua")
|
dofile(minetest.get_modpath("ctf_flag") .. "/gui.lua")
|
||||||
dofile(minetest.get_modpath("ctf_flag") .. "/flag_func.lua")
|
dofile(minetest.get_modpath("ctf_flag") .. "/flag_func.lua")
|
||||||
|
|
||||||
|
-- add a flag to a team
|
||||||
|
function ctf_flag.add(team, pos)
|
||||||
|
if not team or team == "" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not ctf.team(team).flags then
|
||||||
|
ctf.team(team).flags = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
pos.team = team
|
||||||
|
table.insert(ctf.team(team).flags,pos)
|
||||||
|
ctf.save()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- get a flag from a team
|
||||||
|
function ctf_flag.get(pos)
|
||||||
|
if not pos then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local result = nil
|
||||||
|
for _, team in pairs(ctf.teams) do
|
||||||
|
for i = 1, #team.flags do
|
||||||
|
if (
|
||||||
|
team.flags[i].x == pos.x and
|
||||||
|
team.flags[i].y == pos.y and
|
||||||
|
team.flags[i].z == pos.z
|
||||||
|
) then
|
||||||
|
if result then
|
||||||
|
minetest.chat_send_all("[CTF ERROR] Multiple teams have same flag. Please report this to the server operator / admin")
|
||||||
|
print("CTF ERROR DATA")
|
||||||
|
print("Multiple teams have same flag.")
|
||||||
|
print("This is a sign of ctf.txt corruption.")
|
||||||
|
print("----------------")
|
||||||
|
print(dump(result))
|
||||||
|
print(dump(team.flags[i]))
|
||||||
|
print("----------------")
|
||||||
|
else
|
||||||
|
result = team.flags[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return result
|
||||||
|
end
|
||||||
|
|
||||||
|
-- delete a flag from a team
|
||||||
|
function ctf_flag.delete(team, pos)
|
||||||
|
if not team or team == "" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, #ctf.team(team).flags do
|
||||||
|
if (
|
||||||
|
ctf.team(team).flags[i].x == pos.x and
|
||||||
|
ctf.team(team).flags[i].y == pos.y and
|
||||||
|
ctf.team(team).flags[i].z == pos.z
|
||||||
|
) then
|
||||||
|
table.remove(ctf.team(team).flags,i)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function ctf_flag.asset_flags(team)
|
||||||
|
--[[
|
||||||
|
if not team or not ctf.team(team) then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
ctf.log("utils", "Checking the flags of "..team)
|
||||||
|
|
||||||
|
local tmp = ctf.team(team).flags
|
||||||
|
local get_res = minetest.env:get_node(tmp[i])
|
||||||
|
for i=1,#tmp do
|
||||||
|
if tmp[i] and (not get_res or not get_res.name == "ctf:flag") then
|
||||||
|
ctf.log("utils", "Replacing flag...")
|
||||||
|
-- TODO: ctf_flag.asset_flags
|
||||||
|
end
|
||||||
|
end]]--
|
||||||
|
end
|
||||||
|
|
||||||
-- The flag
|
-- The flag
|
||||||
minetest.register_node("ctf_flag:flag", {
|
minetest.register_node("ctf_flag:flag", {
|
||||||
description = "Flag",
|
description = "Flag",
|
||||||
@ -108,7 +211,7 @@ minetest.register_abm({
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local flag_team_data = ctf.area.get_flag(pos)
|
local flag_team_data = ctf_flag.get(pos)
|
||||||
if not flag_team_data or not ctf.team(flag_team_data.team)then
|
if not flag_team_data or not ctf.team(flag_team_data.team)then
|
||||||
ctf.log("flag", "Flag does not exist! Deleting nodes. "..dump(pos))
|
ctf.log("flag", "Flag does not exist! Deleting nodes. "..dump(pos))
|
||||||
minetest.env:set_node(pos,{name="air"})
|
minetest.env:set_node(pos,{name="air"})
|
||||||
|
@ -2,18 +2,16 @@
|
|||||||
local old_is_protected = minetest.is_protected
|
local old_is_protected = minetest.is_protected
|
||||||
|
|
||||||
function minetest.is_protected(pos, name)
|
function minetest.is_protected(pos, name)
|
||||||
local team = ctf.area.get_area(pos)
|
local team = ctf.area.get_territory_owner(pos)
|
||||||
|
|
||||||
if not team then
|
if not team or not ctf.team(team) then
|
||||||
return old_is_protected(pos, name)
|
return old_is_protected(pos, name)
|
||||||
end
|
end
|
||||||
|
|
||||||
if ctf.players and ctf.player(name) and ctf.player(name).team then
|
|
||||||
if ctf.player(name).team == team then
|
if ctf.player(name).team == team then
|
||||||
return old_is_protected(pos, name)
|
return old_is_protected(pos, name)
|
||||||
end
|
else
|
||||||
end
|
|
||||||
|
|
||||||
minetest.chat_send_player(name, "You cannot dig on team "..team.."'s land")
|
minetest.chat_send_player(name, "You cannot dig on team "..team.."'s land")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
@ -60,7 +60,7 @@ if ctf.setting("turrets") then
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local app = ctf.area.get_area(pos)
|
local app = ctf.area.get_territory_owner(pos)
|
||||||
if app and app~=team then
|
if app and app~=team then
|
||||||
team = app
|
team = app
|
||||||
meta:set_string("team",team)
|
meta:set_string("team",team)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user