Change to use factions instead of ctf_pvp_engine

possibly temporary
This commit is contained in:
Elkien3 2018-04-15 20:05:10 -05:00
parent cd825481e8
commit a55a91ce43
87 changed files with 2138 additions and 3691 deletions

View File

@ -1,22 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

View File

@ -1,215 +0,0 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg

View File

@ -1,23 +0,0 @@
CTF PvP Engine
==============
A highly modular framework for the Minetest game engine, in order to allow
the development of Capture the Flag / City vs City games. Good for any
sort of game where players can join teams - flags are optional, everything
is highly configurable.
Licenses
========
Created by: [rubenwardy](http://rubenwardy.com/).
Copyright (c) 2013 - 2015
**Code:** LGPL 2.1 or later.
**Textures:** CC-BY-SA 3.0
ctf_flag/sounds/trumpet* by tobyk, license: CC-BY 3.0
from: http://freesound.org/people/tobyk/sounds/26198/
Documentation
=============
See the doc_* files, starting with doc_project_overview.md

View File

@ -1,268 +0,0 @@
-- Awaiting core support.
local function __genOrderedIndex( t )
local orderedIndex = {}
for key in pairs(t) do
table.insert( orderedIndex, key )
end
table.sort( orderedIndex )
return orderedIndex
end
local function orderedNext(t, state)
-- Equivalent of the next function, but returns the keys in the alphabetic
-- order. We use a temporary ordered key table that is stored in the
-- table being iterated.
local key = nil
if state == nil then
t.__orderedIndex = __genOrderedIndex( t )
key = t.__orderedIndex[1]
else
for i = 1,table.getn(t.__orderedIndex) do
if t.__orderedIndex[i] == state then
key = t.__orderedIndex[i+1]
end
end
end
if key then
return key, t[key]
end
-- no more value to return, cleanup
t.__orderedIndex = nil
return
end
function orderedPairs(t)
-- Equivalent of the pairs() function on tables. Allows to iterate
-- in order
return orderedNext, t, nil
end
-- Registered
ctf.registered_on_load = {}
function ctf.register_on_load(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_load, func)
if ctf._loaddata then
func(ctf._loaddata)
end
end
ctf.registered_on_save = {}
function ctf.register_on_save(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_save, func)
end
ctf.registered_on_init = {}
function ctf.register_on_init(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_init, func)
if ctf._inited then
func()
end
end
ctf.registered_on_new_team = {}
function ctf.register_on_new_team(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_new_team, func)
end
ctf.registered_on_territory_query = {}
function ctf.register_on_territory_query(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_territory_query, func)
end
ctf.registered_on_new_game = {}
function ctf.register_on_new_game(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_new_game, func)
if ctf._new_game then
func()
end
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
-- Debug helpers
function ctf.error(area, msg)
minetest.log("error", "CTF::" .. area .. " - " ..msg)
end
function ctf.log(area, msg)
if area and area ~= "" then
print("[CaptureTheFlag] (" .. area .. ") " .. msg)
else
print("[CaptureTheFlag] " .. msg)
end
end
function ctf.action(area, msg)
if area and area ~= "" then
minetest.log("action", "[CaptureTheFlag] (" .. area .. ") " .. msg)
else
nubetest.log("action", "[CaptureTheFlag] " .. msg)
end
end
function ctf.warning(area, msg)
print("WARNING: [CaptureTheFlag] (" .. area .. ") " .. msg)
end
function ctf.init()
ctf._inited = true
ctf.log("init", "Initialising!")
-- Set up structures
ctf._defsettings = {}
ctf.teams = {}
ctf.players = {}
-- See minetest.conf.example in the root of this subgame
ctf.log("init", "Creating Default Settings")
ctf._set("diplomacy", true)
ctf._set("players_can_change_team", true)
ctf._set("allocate_mode", 0)
ctf._set("maximum_in_team", -1)
ctf._set("default_diplo_state", "war")
ctf._set("hud", true)
ctf._set("autoalloc_on_joinplayer", true)
ctf._set("friendly_fire", true)
for i = 1, #ctf.registered_on_init do
ctf.registered_on_init[i]()
end
ctf.load()
end
function ctf.reset()
ctf.log("io", "Deleting CTF save data...")
os.remove(minetest.get_worldpath().."/ctf.txt")
ctf.init()
end
-- Set default setting value
function ctf._set(setting, default)
if ctf._defsettings[setting] then
ctf.warning("settings", "Setting " .. dump(setting) .. " redeclared!")
ctf.warning("settings", debug.traceback())
end
ctf._defsettings[setting] = default
if minetest.setting_get("ctf."..setting) then
ctf.log("settings", "- " .. setting .. ": " .. minetest.setting_get("ctf."..setting))
elseif minetest.setting_get("ctf_"..setting) then
ctf.log("settings", "- " .. setting .. ": " .. minetest.setting_get("ctf_"..setting))
ctf.warning("settings", "deprecated setting ctf_"..setting..
" used, use ctf."..setting.." instead.")
end
end
function ctf.setting(name)
local set = minetest.setting_get("ctf."..name) or
minetest.setting_get("ctf_"..name)
local dset = ctf._defsettings[name]
if dset == nil then
ctf.error("setting", "No such setting - " .. name)
return nil
end
if set ~= nil then
if type(dset) == "number" then
return tonumber(set)
elseif type(dset) == "boolean" then
return minetest.is_yes(set)
else
return set
end
else
return dset
end
end
function ctf.load()
ctf.log("io", "Loading CTF state")
local file = io.open(minetest.get_worldpath().."/ctf.txt", "r")
if file then
local table = minetest.deserialize(file:read("*all"))
if type(table) == "table" then
ctf.teams = table.teams
ctf.players = table.players
for i = 1, #ctf.registered_on_load do
ctf.registered_on_load[i](table)
end
return
end
ctf._loaddata = table
else
ctf.log("io", "ctf.txt is not present in the world folder")
ctf._new_game = true
for i = 1, #ctf.registered_on_new_game do
ctf.registered_on_new_game[i]()
end
end
end
minetest.after(0, function()
ctf._loaddata = nil
ctf._mt_loaded = true
end)
function ctf.check_save()
if ctf_flag and ctf_flag.assert_flags then
ctf_flag.assert_flags()
end
if ctf.needs_save then
ctf.save()
end
minetest.after(10, ctf.check_save)
end
minetest.after(10, ctf.check_save)
function ctf.save()
local file = io.open(minetest.get_worldpath().."/ctf.txt", "w")
if file then
local out = {
teams = ctf.teams,
players = ctf.players,
applications = ctf.applications
}
for i = 1, #ctf.registered_on_save do
local res = ctf.registered_on_save[i]()
if res then
for key, value in pairs(res) do
out[key] = value
end
end
end
file:write(minetest.serialize(out))
file:close()
ctf.needs_save = false
else
ctf.error("io", "CTF file failed to save!")
end
end

View File

@ -1,2 +0,0 @@
chatplus?
hudkit

View File

@ -1,83 +0,0 @@
-- diplo states: war, peace, alliance
ctf.diplo = {
diplo = {}
}
ctf.register_on_load(function(table)
ctf.diplo.diplo = table.diplo
end)
ctf.register_on_save(function()
return { diplo = ctf.diplo.diplo }
end)
function ctf.diplo.get(one,two)
if not ctf.diplo.diplo then
return ctf.setting("default_diplo_state")
end
for i = 1, #ctf.diplo.diplo do
local dip = ctf.diplo.diplo[i]
if (dip.one == one and dip.two == two) or
(dip.one == two and dip.two == one) then
return dip.state
end
end
return ctf.setting("default_diplo_state")
end
function ctf.diplo.set(one, two, state)
if ctf.diplo.diplo then
-- Check the table for an existing diplo state
for i = 1, #ctf.diplo.diplo do
local dip = ctf.diplo.diplo[i]
if (dip.one == one and dip.two == two) or
(dip.one == two and dip.two == one) then
dip.state = state
return
end
end
else
ctf.diplo.diplo = {}
end
table.insert(ctf.diplo.diplo,{one=one,two=two,state=state})
end
function ctf.diplo.check_requests(one, two)
local team = ctf.team(two)
if not team.log then
return nil
end
for i=1,#team.log do
if team.log[i].team == one and
team.log[i].type == "request" and
team.log[i].mode == "diplo" then
return team.log[i].msg
end
end
return nil
end
function ctf.diplo.cancel_requests(one, two)
local team = ctf.team(two)
if not team.log then
return
end
for i=1,#team.log do
if team.log[i].team == one and
team.log[i].type == "request" and
team.log[i].mode == "diplo" then
table.remove(team.log,i)
return
end
end
return
end

View File

@ -1,474 +0,0 @@
ctf.gui = {
tabs = {}
}
ctf.register_on_init(function()
ctf._set("gui", true)
ctf._set("gui.team", true)
ctf._set("gui.team.initial", "news")
for name, tab in pairs(ctf.gui.tabs) do
ctf._set("gui.tab." .. name, true)
end
end)
function ctf.gui.register_tab(name, title, func)
ctf.gui.tabs[name] = {
name = name,
title = title,
func = func
}
if ctf._defsettings and ctf._defsettings["gui.tab." .. name] == nil then
ctf._set("gui.tab." .. name, true)
end
end
function ctf.gui.show(name, tab, tname)
if not tab then
tab = ctf.setting("gui.team.initial") or "news"
end
if not tab or not ctf.gui.tabs[tab] or not name or name == "" then
ctf.log("gui", "Invalid tab or name given to ctf.gui.show")
return
end
if not ctf.setting("gui.team") or not ctf.setting("gui") then
return
end
if not ctf.team(tname) then
tname = ctf.player(name).team
end
if ctf.team(tname) then
ctf.action("gui", name .. " views " .. tname .. "'s " .. tab .. " page")
ctf.gui.tabs[tab].func(name, tname)
else
ctf.log("gui", "Invalid team given to ctf.gui.show")
end
end
-- Get tab buttons
function ctf.gui.get_tabs(name, tname)
local result = ""
local id = 1
local function addtab(name,text)
result = result .. "button[" .. (id*1.5-1) .. ",0;1.5,1;" .. name .. ";" .. text .. "]"
id = id + 1
end
for name, tab in pairs(ctf.gui.tabs) do
if ctf.setting("gui.tab." .. name) then
addtab(name, tab.title)
end
end
return result
end
-- Team interface
ctf.gui.register_tab("news", "News", function(name, tname)
local result = ""
local team = ctf.team(tname).log
if not team then
team = {}
end
local amount = 0
for i = 1, #team do
if team[i].type == "request" then
if ctf.can_mod(name, tname) then
amount = amount + 2
local height = (amount*0.5) + 0.5
amount = amount + 1
if team[i].mode == "diplo" then
result = result .. "background[0.5," .. height .. ";8.3,1;diplo_" .. team[i].msg .. ".png]"
if team[i].msg == "alliance" then
result = result .. "label[1," .. height .. ";" ..
team[i].team .. " offers an " ..
minetest.formspec_escape(team[i].msg) .. " treaty]"
else
result = result .. "label[1," .. height .. ";" ..
team[i].team .. " offers a " ..
minetest.formspec_escape(team[i].msg) .. " treaty]"
end
result = result .. "button[6," .. height .. ";1,1;btn_y" .. i .. ";Yes]"
result = result .. "button[7," .. height .. ";1,1;btn_n" .. i .. ";No]"
end
end
else
amount = amount + 1
local height = (amount*0.5) + 0.5
if height > 5 then
break
end
result = result .. "label[0.5," .. height .. ";" ..
minetest.formspec_escape(team[i].msg) .. "]"
end
end
if ctf.can_mod(name, tname) then
result = result .. "button[4,6;2,1;clear;Clear all]"
end
if amount == 0 then
result = "label[0.5,1;Welcome to the news panel]" ..
"label[0.5,1.5;News such as attacks will appear here]"
end
minetest.show_formspec(name, "ctf:news",
"size[10,7]" ..
ctf.gui.get_tabs(name, tname) ..
result)
end)
ctf.gui.register_tab("applications","Applications", function(name, tname)
local result = ""
local data = {}
result = result .. "label[0.5,1;Applicants to join " .. tname .. "]"
for key, value in pairs(ctf.teams) do
if key == tname then
local height = 1.5
for key, value in pairs(value.applications) do
result = result .. "label[0.5.75," .. height .. ";" .. value .. "]"
if ctf.player(name).auth or ctf.player(name).recruit then
result = result .. "button[2.5," .. height .. ";2,1;player_" ..
value .. ";Accept]"
result = result .. "button[4.5," .. height .. ";2,1;player_" ..
value .. ";Reject]"
end
height = height + 1
end
end
end
minetest.show_formspec(name, "ctf:applications",
"size[10,7]" ..
ctf.gui.get_tabs(name, tname) ..
result
)
end)
local scroll_diplomacy = 0
local scroll_max = 0
-- Team interface
ctf.gui.register_tab("diplo", "Diplomacy", function(name, tname)
local result = ""
local data = {}
local amount = 0
for key, value in pairs(ctf.teams) do
if key ~= tname then
table.insert(data,{
team = key,
state = ctf.diplo.get(tname, key),
to = ctf.diplo.check_requests(tname, key),
from = ctf.diplo.check_requests(key, tname)
})
end
end
result = result .. "label[1,1;Diplomacy from the perspective of " .. tname .. "]"
scroll_max = 0
for i = 1, #data do
scroll_max = i
end
scroll_max = scroll_max - 4
if scroll_diplomacy > (scroll_max+4) then
scroll_diplomacy = (scroll_max+4)
end
if scroll_diplomacy > 0 then
result = result .. "button[9.2,0.44;1,3;scroll_up;Up]"
end
if scroll_diplomacy < scroll_max then
result = result .. "button[9.2,3.8;1,3;scroll_down;Down]"
end
for i = 1, #data do
amount = i
local height = (i*1)+0.5
if height > 5 then
break
end
local L = i + scroll_diplomacy
if data[L].state and data[L].team then
result = result .. "background[1," .. height .. ";8.2,1;diplo_" ..
data[L].state .. ".png]"
result = result .. "button[1.25," .. height .. ";2,1;team_" ..
data[L].team .. ";" .. data[L].team .. "]"
result = result .. "label[3.75," .. height .. ";" .. data[L].state
.. "]"
end
if ctf.can_mod(name, tname) and ctf.player(name).team == tname then
if not data[L].from and not data[L].to then
if data[L].state == "war" then
result = result .. "button[7.5," .. height ..
";1.5,1;peace_" .. data[L].team .. ";Peace]"
elseif data[L].state == "peace" then
result = result .. "button[6," .. height ..
";1.5,1;war_" .. data[L].team .. ";War]"
result = result .. "button[7.5," .. height ..
";1.5,1;alli_" .. data[L].team .. ";Alliance]"
elseif data[L].state == "alliance" then
result = result .. "button[6," .. height ..
";1.5,1;peace_" .. data[L].team .. ";Peace]"
end
elseif data[L].from ~= nil then
result = result .. "label[6," .. height ..
";request recieved]"
elseif data[L].to ~= nil then
result = result .. "label[5.5," .. height ..
";request sent]"
result = result .. "button[7.5," .. height ..
";1.5,1;cancel_" .. data[L].team .. ";Cancel]"
end
end
end
minetest.show_formspec(name, "ctf:diplo",
"size[10,7]" ..
ctf.gui.get_tabs(name, tname) ..
result
)
end)
local function formspec_is_ctf_tab(fsname)
for name, tab in pairs(ctf.gui.tabs) do
if fsname == "ctf:" .. name then
return true
end
end
return false
end
function remove_application_log_entry(tname, pname)
local entries = ctf.team(tname).log
if not entries then
return
end
for i = 1, #entries do
if entries[i].mode == "applications" and entries[i].player == pname then
table.remove(entries, i)
return
end
end
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if not formspec_is_ctf_tab(formname) then
return false
end
local name = player:get_player_name()
local tplayer = ctf.player(name)
local tname = tplayer.team
local team = ctf.team(tname)
if not team then
return false
end
-- Do navigation
for tabname, tab in pairs(ctf.gui.tabs) do
if fields[tabname] then
ctf.gui.show(name, tabname)
return true
end
end
-- Todo: move callbacks
-- News page
if fields.clear then
team.log = {}
ctf.needs_save = true
ctf.gui.show(name, "news")
return true
end
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name()
local tplayer = ctf.player(name)
local tname = tplayer.team
local team = ctf.team(tname)
if not team or formname ~= "ctf:news" then
return false
end
for key, field in pairs(fields) do
local ok, id = string.match(key, "btn_([yn])([0123456789]+)")
if ok and id then
if ok == "y" then
ctf.diplo.set(tname, team.log[tonumber(id)].team, team.log[tonumber(id)].msg)
-- Post to acceptor's log
ctf.post(tname, {
msg = "You have accepted the " ..
team.log[tonumber(id)].msg .. " request from " ..
team.log[tonumber(id)].team })
-- Post to request's log
ctf.post(team.log[tonumber(id)].team, {
msg = tname .. " has accepted your " ..
team.log[tonumber(id)].msg .. " request" })
id = id + 1
end
table.remove(team.log, id)
ctf.needs_save = true
ctf.gui.show(name, "news")
return true
end
local applicant_name, id = string.match(key, "player_([^_]+)_([0123456789]+)")
if applicant_name then
local acceptor_name = name
local team_name = tname
local decision = field
ctf.decide_application(
applicant_name,
acceptor_name,
team_name,
decision)
return true
end
end
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
local acceptor_name = player:get_player_name()
local team_name = ctf.player(acceptor_name).team
local team = ctf.team(team_name)
if not team or formname ~= "ctf:applications" then
return false
end
for key, field in pairs(fields) do
if ctf.player(acceptor_name).auth or ctf.player(acceptor_name).recruit then
local applicant_name = string.match(key, "player_(.+)")
if applicant_name then
local decision = field
ctf.decide_application(
applicant_name,
acceptor_name,
team_name,
decision)
ctf.gui.show(acceptor_name, "applications")
return true
end
end
end
end)
local cur_team = nil
minetest.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name()
local tplayer = ctf.player(name)
local tname = tplayer.team
local team = ctf.team(tname)
if not team or formname ~= "ctf:diplo" then
cur_team = nil
return false
end
if cur_team == nil then
cur_team = tname
end
if fields.scroll_up then
if scroll_diplomacy > 0 then
scroll_diplomacy = scroll_diplomacy - 1
else
scroll_diplomacy = 0
end
ctf.gui.show(name, "diplo", cur_team)
end
if fields.scroll_down then
if scroll_diplomacy < (scroll_max) then
scroll_diplomacy = scroll_diplomacy + 1
else
scroll_diplomacy = scroll_max
end
ctf.gui.show(name, "diplo", cur_team)
end
for key, field in pairs(fields) do
local tname2 = string.match(key, "team_(.+)")
if tname2 and ctf.team(tname2) then
ctf.gui.show(name, "diplo", tname2)
cur_team = tname2
return true
end
if ctf.can_mod(name, tname) then
tname2 = string.match(key, "peace_(.+)")
if tname2 then
if ctf.diplo.get(tname, tname2) == "war" then
ctf.post(tname2, {
type = "request",
msg = "peace",
team = tname,
mode = "diplo" })
else
ctf.diplo.set(tname, tname2, "peace")
ctf.post(tname, {
msg = "You have cancelled the alliance treaty with " .. tname2 })
irc:say(tname .. " has cancelled the alliance treaty with " .. tname2 .. "!")
minetest.chat_send_all(tname .. " has cancelled the alliance treaty with " .. tname2 .. "!")
ctf.post(tname2, {
msg = tname .. " has cancelled the alliance treaty" })
end
ctf.gui.show(name, "diplo")
return true
end
tname2 = string.match(key, "war_(.+)")
if tname2 then
ctf.diplo.set(tname, tname2, "war")
ctf.post(tname, {
msg = "You have declared war on " .. tname2 })
irc:say(tname .. " has declared war on " .. tname2 .. "!")
minetest.chat_send_all(tname .. " has declared war on " .. tname2 .. "!")
ctf.post(tname2, {
msg = tname .. " has declared war on you" })
ctf.gui.show(name, "diplo")
return true
end
tname2 = string.match(key, "alli_(.+)")
if tname2 then
ctf.post(tname2, {
type = "request",
msg = "alliance",
team = tname,
mode = "diplo" })
ctf.gui.show(name, "diplo")
return true
end
tname2 = string.match(key, "cancel_(.+)")
if tname2 then
ctf.diplo.cancel_requests(tname, tname2)
ctf.gui.show(name, "diplo")
return true
end
end -- end if can mod
end -- end for each field
end)

View File

@ -1,50 +0,0 @@
ctf.hud = hudkit()
ctf.hud.parts = {}
function ctf.hud.register_part(func)
table.insert(ctf.hud.parts, func)
end
minetest.register_on_leaveplayer(function(player)
ctf.hud.players[player:get_player_name()] = nil
end)
ctf.register_on_join_team(function(name, tname)
if ctf.setting("hud") then
ctf.hud.update(minetest.get_player_by_name(name))
end
end)
function ctf.hud.update(player)
if not player then
return
end
local name = player:get_player_name()
local tplayer = ctf.player(name)
if not tplayer or not tplayer.team or not ctf.team(tplayer.team) then
return
end
-- Team Identifier
for i = 1, #ctf.hud.parts do
ctf.hud.parts[i](player, name, tplayer)
end
end
function ctf.hud.updateAll()
if not ctf.setting("hud") then
return
end
local players = minetest.get_connected_players()
for i = 1, #players do
ctf.hud.update(players[i])
end
end
local function tick()
ctf.hud.updateAll()
minetest.after(10, tick)
end
minetest.after(1, tick)

View File

@ -1,33 +0,0 @@
-- CAPTURE THE FLAG
-- by Andrew "rubenwardy" Ward
-----------------------------------------
ctf = {}
-- Fix for https://github.com/minetest/minetest/issues/2383
local csa = minetest.chat_send_all
function minetest.chat_send_all(msg)
minetest.after(0, function()
csa(msg)
end)
end
-- Privs
minetest.register_privilege("ctf_team_mgr", {
description = "Team manager",
})
minetest.register_privilege("ctf_admin", {
description = "Can create teams, manage players, assign team owners.",
})
-- Modules
dofile(minetest.get_modpath("ctf") .. "/core.lua")
dofile(minetest.get_modpath("ctf") .. "/teams.lua")
dofile(minetest.get_modpath("ctf") .. "/diplomacy.lua")
dofile(minetest.get_modpath("ctf") .. "/gui.lua")
dofile(minetest.get_modpath("ctf") .. "/hud.lua")
-- Init
ctf.init()
ctf.clean_player_lists()

View File

@ -1,576 +0,0 @@
-- Get or add a team
function ctf.team(name)
if name == nil then
return nil
end
if type(name) == "table" then
if not name.add_team then
ctf.error("team", "Invalid table given to ctf.team")
return
end
return ctf.create_team(name.name, name)
else
local team = ctf.teams[name]
if team then
--Migration to version with applications
if not team.applications then
team.applications = {}
end
if not team.data or not team.players then
ctf.warning("team", "Assertion failed, data{} or players{} not " ..
"found in team{}")
end
return team
else
if name and name:trim() ~= "" then
ctf.warning("team", dump(name) .. " does not exist!")
end
return nil
end
end
end
function ctf.create_team(name, data)
ctf.log("team", "Creating team " .. name)
ctf.teams[name] = {
data = data,
spawn = nil,
players = {},
applications = {}
}
for i = 1, #ctf.registered_on_new_team do
ctf.registered_on_new_team[i](ctf.teams[name])
end
ctf.needs_save = true
return ctf.teams[name]
end
function ctf.remove_team(name)
local team = ctf.team(name)
if team then
for username, player in pairs(team.players) do
player.team = nil
end
for i = 1, #team.flags do
team.flags[i].team = nil
end
ctf.teams[name] = nil
return true
else
return false
end
end
function ctf.list_teams(name)
minetest.chat_send_player(name, "Teams:")
for tname, team in pairs(ctf.teams) do
if team and team.players then
local details = ""
local numPlayers = ctf.count_players_in_team(tname)
details = numPlayers .. " members"
if team.flags then
local numFlags = 0
for flagid, flag in pairs(team.flags) do
numFlags = numFlags + 1
end
details = details .. ", " .. numFlags .. " flags"
end
minetest.chat_send_player(name, ">> " .. tname ..
" (" .. details .. ")")
end
end
end
-- Count number of players in a team
function ctf.count_players_in_team(team)
local count = 0
for name, player in pairs(ctf.team(team).players) do
count = count + 1
end
return count
end
function ctf.new_player(name)
if name then
ctf.players[name] = {
name = name
}
else
ctf.error("team", "Can't create a blank player")
ctf.log("team", debug.traceback())
end
end
-- get a player
function ctf.player(name)
if not ctf.players[name] then
ctf.new_player(name)
end
return ctf.players[name]
end
function ctf.player_or_nil(name)
return ctf.players[name]
end
function ctf.remove_player(name)
ctf.log("team", "Removing player ".. dump(name))
local player = ctf.players[name]
if player then
local team = ctf.team(player.team)
if team then
team.players[name] = nil
end
ctf.players[name] = nil
ctf.needs_save = true
return true
else
return false
end
end
ctf.registered_on_join_team = {}
function ctf.register_on_join_team(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_join_team, func)
end
-- Player joins team
-- Called by /join, /team join or auto allocate.
ctf.registered_on_join_team = {}
function ctf.register_on_join_team(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_join_team, func)
end
-- Player makes an application to team manager to join a team
-- Called by /apply
function ctf.application_join(name, tname)
if not name or name == "" or not tname or tname == "" then
ctf.log("teams", "Missing parameters to ctf.request_join")
end
local player = ctf.player(name)
if player.team and player.team == tname then
minetest.chat_send_player(name, "You are already a member of team " .. tname)
return false
end
if not ctf.setting("players_can_change_team") and player.team and ctf.team(player.team) then
ctf.action("teams", name .. " requested to change to " .. tname)
minetest.chat_send_player(name, "You are not allowed to switch teams, traitor!")
return false
end
local team_data = ctf.team(tname)
if not team_data then
minetest.chat_send_player(name, "No such team.")
ctf.list_teams(name)
minetest.log("action", name .. " requested to join to " .. tname .. ", which doesn't exist")
return false
end
table.insert(team_data.applications,name)
--ctf.post(tname, {msg = name .. " has applied to join!" })
ctf.needs_save = true
return true
end
function ctf.decide_application(applicant_name, acceptor_name, team_name, decision)
if not applicant_name then
return false
end
local applicant = ctf.player(applicant_name)
if not applicant then
return false
end
if decision == "Accept" then
if applicant.team and ctf.setting("players_can_change_team") then
minetest.chat_send_player(acceptor_name, "Player " .. applicant_name .. " already a member of team " .. applicant.team)
else
ctf.join(applicant_name, team_name, true, acceptor_name)
table.insert(ctf.teams[ctf.players[acceptor_name].team].log,{msg=applicant_name .. " was recruited " .. acceptor_name .. "!"})
end
end
for key, field in pairs(ctf.teams) do
ctf.delete_application(applicant_name, key)
end
remove_application_log_entry(team_name, applicant_name)
end
function ctf.delete_application(name, tname)
if not name or name == "" or not tname or tname == "" then
ctf.log("teams", "Missing parameters to ctf.delete_application")
end
local team = ctf.team(tname)
if not team then
minetest.chat_send_player(name, "No such team.")
return false
end
for key, field in pairs(team.applications) do
if field == name then
table.remove(team.applications, key)
ctf.needs_save = true
return true
end
end
return false
end
-- Player joins team
-- Called by /join, /team join, auto allocate or by response of the team manager.
function ctf.join(name, team, force, by)
if not name or name == "" or not team or team == "" then
ctf.log("team", "Missing parameters to ctf.join")
return false
end
local player = ctf.player(name)
if not force and not ctf.setting("players_can_change_team")
and player.team and ctf.team(player.team) then
if by then
if by == name then
ctf.action("teams", name .. " attempted to change to " .. team)
minetest.chat_send_player(by, "You are not allowed to switch teams, traitor!")
else
ctf.action("teams", by .. " attempted to change " .. name .. " to " .. team)
minetest.chat_send_player(by, "Failed to add " .. name .. " to " .. team ..
" as players_can_change_team = false")
end
else
ctf.log("teams", "failed to add " .. name .. " to " .. team ..
" as players_can_change_team = false")
end
return false
end
local team_data = ctf.team(team)
if not team_data then
if by then
minetest.chat_send_player(by, "No such team.")
ctf.list_teams(by)
if by == name then
minetest.log("action", by .. " tried to move " .. name .. " to " .. team .. ", which doesn't exist")
else
minetest.log("action", name .. " attempted to join " .. team .. ", which doesn't exist")
end
else
ctf.log("teams", "failed to add " .. name .. " to " .. team ..
" as team does not exist")
end
return false
end
if player.team then
local oldteam = ctf.team(player.team)
if oldteam then
oldteam.players[player.name] = nil
end
end
player.team = team
team_data.players[player.name] = player
ctf.needs_save = true
minetest.log("action", name .. " joined team " .. team)
minetest.chat_send_all(name.." has joined team "..team)
for i = 1, #ctf.registered_on_join_team do
ctf.registered_on_join_team[i](name, team)
end
return true
end
-- Cleans up the player lists
function ctf.clean_player_lists()
ctf.log("utils", "Cleaning player lists")
for _, str in pairs(ctf.players) do
if str and str.team and ctf.teams[str.team] then
ctf.log("utils", " - Adding player "..str.name.." to team "..str.team)
ctf.teams[str.team].players[str.name] = str
else
ctf.log("utils", " - Skipping player "..str.name)
end
end
end
-- Sees if the player can change stuff in a team
function ctf.can_mod(player,team)
local privs = minetest.get_player_privs(player)
if privs then
if privs.ctf_admin == true then
return true
end
end
if player and ctf.teams[team] and ctf.teams[team].players and ctf.teams[team].players[player] then
if ctf.teams[team].players[player].auth == true then
return true
end
end
return false
end
-- post a message to a team board
function ctf.post(team, msg)
if not ctf.team(team) then
return false
end
if not ctf.team(team).log then
ctf.team(team).log = {}
end
ctf.log("team", "message posted to team board")
table.insert(ctf.team(team).log, 1, msg)
ctf.needs_save = true
return true
end
-- Automatic Allocation
function ctf.autoalloc(name, alloc_mode)
if alloc_mode == 0 then
return
end
local max_players = ctf.setting("maximum_in_team")
local mtot = false -- more than one team
for key, team in pairs(ctf.teams) do
mtot = true
break
end
if not mtot then
ctf.error("autoalloc", "No teams to allocate " .. name .. " to!")
return
end
if alloc_mode == 1 then
local index = {}
for key, team in pairs(ctf.teams) do
if max_players == -1 or ctf.count_players_in_team(key) < max_players then
table.insert(index, key)
end
end
if #index == 0 then
ctf.error("autoalloc", "No teams to join!")
else
return index[math.random(1, #index)]
end
elseif alloc_mode == 2 then
local one = nil
local one_count = -1
local two = nil
local two_count = -1
for key, team in pairs(ctf.teams) do
local count = ctf.count_players_in_team(key)
if (max_players == -1 or count < max_players) then
if count > one_count then
two = one
two_count = one_count
one = key
one_count = count
end
if count > two_count then
two = key
two_count = count
end
end
end
if not one and not two then
ctf.error("autoalloc", "No teams to join!")
elseif one and two then
if math.random() > 0.5 then
return one
else
return two
end
else
if one then
return one
else
return two
end
end
elseif alloc_mode == 3 then
local smallest = nil
local smallest_count = 1000
for key, team in pairs(ctf.teams) do
local count = ctf.count_players_in_team(key)
if not smallest or count < smallest_count then
smallest = key
smallest_count = count
end
end
if not smallest then
ctf.error("autoalloc", "No teams to join!")
else
return smallest
end
else
ctf.error("autoalloc", "Unknown allocation mode: "..ctf.setting("allocate_mode"))
end
end
-- updates the spawn position for a team
function ctf.get_spawn(team)
if ctf.team(team) and ctf.team(team).spawn then
return ctf.team(team).spawn
else
return nil
end
end
function ctf.move_to_spawn(name)
local player = minetest.get_player_by_name(name)
local tplayer = ctf.player(name)
if ctf.team(tplayer.team) then
local spawn = ctf.get_spawn(tplayer.team)
if spawn then
player:moveto(spawn, false)
return true
end
end
return false
end
--[[
minetest.register_on_respawnplayer(function(player)
if not player then
return false
end
return ctf.move_to_spawn(player:get_player_name())
end)--]]
function ctf.get_territory_owner(pos)
local largest = nil
local largest_weight = 0
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
if weight > largest_weight then
largest = team
largest_weight = weight
end
end
end
return largest
end
minetest.register_on_newplayer(function(player)
local alloc_mode = tonumber(ctf.setting("allocate_mode"))
if alloc_mode == 0 then
return
end
local name = player:get_player_name()
local team = ctf.autoalloc(name, alloc_mode)
if team then
ctf.log("autoalloc", name .. " was allocated to " .. team)
ctf.join(name, team)
ctf.move_to_spawn(player:get_player_name())
end
end)
minetest.register_on_joinplayer(function(player)
if not ctf.setting("autoalloc_on_joinplayer") then
return
end
local name = player:get_player_name()
if ctf.team(ctf.player(name).team) then
return
end
local alloc_mode = tonumber(ctf.setting("allocate_mode"))
if alloc_mode == 0 then
return
end
local team = ctf.autoalloc(name, alloc_mode)
if team then
ctf.log("autoalloc", name .. " was allocated to " .. team)
ctf.join(name, team)
ctf.move_to_spawn(player:get_player_name())
end
end)
-- Disable friendly fire.
ctf.registered_on_killedplayer = {}
function ctf.register_on_killedplayer(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf.registered_on_killedplayer, func)
end
local dead_players = {}
minetest.register_on_respawnplayer(function(player)
dead_players[player:get_player_name()] = nil
end)
minetest.register_on_joinplayer(function(player)
dead_players[player:get_player_name()] = nil
end)
minetest.register_on_punchplayer(function(player, hitter,
time_from_last_punch, tool_capabilities, dir, damage)
if player and hitter then
local to = ctf.player(player:get_player_name())
local from = ctf.player(hitter:get_player_name())
if dead_players[player:get_player_name()] then
return
end
if to.team == from.team and to.team ~= "" and to.team ~= nil and to.name ~= from.name then
minetest.chat_send_player(hitter:get_player_name(), player:get_player_name() .. " is on your team!")
if not ctf.setting("friendly_fire") then
return true
end
end
if player:get_hp() - damage <= 0 then
dead_players[player:get_player_name()] = true
local wielded = hitter:get_wielded_item()
local wname = wielded:get_name()
print(wname)
local type = "sword"
if wname:sub(1, 8) == "shooter:" then
if wname == "shooter:grenade" then
type = "grenade"
else
type = "bullet"
end
end
if tool_capabilities.damage_groups.grenade then
type = "grenade"
end
for i = 1, #ctf.registered_on_killedplayer do
ctf.registered_on_killedplayer[i](player:get_player_name(), hitter:get_player_name(), type)
end
return false
end
end
end)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -1,4 +0,0 @@
ctf
chatplus?
irc?
inventory_plus

View File

@ -1,450 +0,0 @@
ctf.register_on_init(function()
ctf.log("chat", "Initialising...")
-- Settings: Chat
ctf._set("chat.team_channel", true)
ctf._set("chat.global_channel", true)
ctf._set("chat.default", "global")
end)
local function team_console_help(name)
minetest.chat_send_player(name, "Try:")
minetest.chat_send_player(name, "/team - show team panel")
minetest.chat_send_player(name, "/team all - list all teams")
minetest.chat_send_player(name, "/team <team> - show details about team 'name'")
minetest.chat_send_player(name, "/team <name> - get which team 'player' is in")
minetest.chat_send_player(name, "/team player <name> - get which team 'player' is in")
local privs = minetest.get_player_privs(name)
if privs and privs.ctf_admin == true then
minetest.chat_send_player(name, "/team add <team> - add a team called name (ctf_admin only)")
minetest.chat_send_player(name, "/team remove <team> - add a team called name (ctf_admin only)")
end
if privs and privs.ctf_team_mgr == true then
minetest.chat_send_player(name, "/team join <name> <team> - add 'player' to team 'team' (ctf_team_mgr only)")
minetest.chat_send_player(name, "/team removeply <name> - add 'player' to team 'team' (ctf_team_mgr only)")
end
end
minetest.register_chatcommand("team", {
description = "Open the team console, or run team command (see /team help)",
func = function(name, param)
local test = string.match(param, "^player ([%a%d_-]+)")
local create = string.match(param, "^add ([%a%d_-]+)")
local remove = string.match(param, "^remove ([%a%d_-]+)")
local j_name, j_tname = string.match(param, "^join ([%a%d_-]+) ([%a%d_]+)")
local l_name = string.match(param, "^removeplr ([%a%d_-]+)")
if create then
local privs = minetest.get_player_privs(name)
if privs and privs.ctf_admin then
if (
string.match(create, "([%a%b_]-)")
and create ~= ""
and create ~= nil
and ctf.team({name=create, add_team=true})
) then
return true, "Added team '"..create.."'"
else
return false, "Error adding team '"..create.."'"
end
else
return false, "You are not a ctf_admin!"
end
elseif remove then
local privs = minetest.get_player_privs(name)
if privs and privs.ctf_admin then
if ctf.remove_team(remove) then
return true, "Removed team '" .. remove .. "'"
else
return false, "Error removing team '" .. remove .. "'"
end
else
return false, "You are not a ctf_admin!"
end
elseif param == "all" then
ctf.list_teams(name)
elseif ctf.team(param) then
minetest.chat_send_player(name, "Team "..param..":")
local count = 0
for _, value in pairs(ctf.team(param).players) do
count = count + 1
if value.auth then
minetest.chat_send_player(name, count .. ">> " .. value.name
.. " (team owner)")
elseif value.recruit then
minetest.chat_send_player(name, count .. ">> " .. value.name
.. " (team recruiter)")
else
minetest.chat_send_player(name, count .. ">> " .. value.name)
end
end
elseif ctf.player_or_nil(param) or test then
if not test then
test = param
end
if ctf.player(test).team then
if ctf.player(test).auth then
return true, test ..
" is in team " .. ctf.player(test).team.." (team owner)"
elseif ctf.player(test).recruit then
return true, test ..
" is in team " .. ctf.player(test).team.." (team recruiter)"
else
return true, test ..
" is in team " .. ctf.player(test).team
end
else
return true, test.." is not in a team"
end
elseif j_name and j_tname then
local privs = minetest.get_player_privs(name)
if privs and privs.ctf_team_mgr then
if ctf.join(j_name, j_tname, true, name) then
return true, "Successfully added " .. j_name .. " to " .. j_tname
else
return false, "Failed to add " .. j_name .. " to " .. j_tname
end
else
return true, "You are not a ctf_team_mgr!"
end
elseif l_name then
local privs = minetest.get_player_privs(name)
if privs and privs.ctf_team_mgr then
if ctf.remove_player(l_name) then
return true, "Removed player " .. l_name
else
return false, "Failed to remove player."
end
else
return false, "You are not a ctf_team_mgr!"
end
elseif param=="help" then
team_console_help(name)
else
if param ~= "" and param ~= nil then
minetest.chat_send_player(name, "'"..param.."' is an invalid parameter to /team")
team_console_help(name)
end
if ctf.setting("gui") then
if (ctf and
ctf.players and
ctf.players[name] and
ctf.players[name].team) then
print("showing")
ctf.gui.show(name)
return true, "Showing the team window"
else
return false, "You're not part of a team!"
end
else
return false, "GUI is disabled!"
end
end
return false, "Nothing could be done"
end
})
minetest.register_chatcommand("apply", {
params = "teamname",
description = "Apply to join to team",
func = function(name, param)
if ctf.application_join(name, param) then
return true, "Application sent to team " .. param .. "!"
else
return false, "Failed to apply to team!"
end
end
})
minetest.register_chatcommand("join", {
params = "player name",
description = "Add to team",
func = function(name, param)
local team = ctf.player(name).team
if minetest.get_auth_handler().get_auth(param) == nil then
return false, "Player '" .. param .. "' dosn't exist!"
elseif ctf.player(param).team then
return false, param .. " is already in a team!"
else
if ctf.player(name).auth or ctf.player(name).recruit then
if ctf.join(param, team, false, name) then
return true, "Joined " .. param .. " to " .. team .. "!"
else
return false, "Failed to join team!"
end
else
return false, "You are not a team owner/recuiter!"
end
end
end
})
minetest.register_chatcommand("teamkick", {
params = "player name",
description = "Kick player from your team",
func = function(name, param)
local team = ctf.player(name).team
if ctf.player(param).team ~= team then
return false, param .. " is not in your team!"
else
if ctf.player(name).auth or ctf.player(name).recruit then
if ctf.player(param).auth or ctf.player(param).recuiter then
return false, param.. " is a team owner or recruiter!"
else
if ctf.remove_player(param) then
return true, "Kicked " .. param .. " from " .. team .. "!"
else
return false, "Failed to kick " .. param.. "!"
end
end
else
return false, "You are not the team owner!"
end
end
end})
minetest.register_chatcommand("teamleave", {
params = "none",
description = "Leave your team",
func = function(name, param)
local team = ctf.player(name).team
if ctf.player(name).team ~= nil then
if ctf.remove_player(name) then
return true, "You have left " .. team .. "!"
else
return false, "Failed to leave " .. team.. "!"
end
else
return false, "You are not in a team!"
end
end
})
--[[
minetest.register_chatcommand("join", {
params = "player name",
description = "Add to team",
func = function(name, param)
if ctf.join(name, param, false, name) then
return true, "Joined team " .. param .. "!"
else
return false, "Failed to join team!"
end
end
})--]]
minetest.register_chatcommand("ctf_clean", {
description = "Do admin cleaning stuff",
privs = {ctf_admin=true},
func = function(name, param)
ctf.log("chat", "Cleaning CTF...")
ctf.clean_player_lists()
if ctf_flag and ctf_flag.assert_flags then
ctf_flag.assert_flags()
end
return true, "CTF cleaned!"
end
})
minetest.register_chatcommand("ctf_reset", {
description = "Delete all CTF saved states and start again.",
privs = {ctf_admin=true},
func = function(name, param)
minetest.chat_send_all("The CTF core was reset by the admin. All team memberships," ..
"flags, land ownerships etc have been deleted.")
ctf.reset()
return true, "Reset CTF core."
end,
})
minetest.register_chatcommand("ctf_reload", {
description = "reload the ctf main frame and get settings",
privs = {ctf_admin=true},
func = function(name, param)
ctf.needs_save = true
ctf.init()
return true, "CTF core reloaded!"
end
})
minetest.register_chatcommand("ctf_ls", {
description = "ctf: list settings",
privs = {ctf_admin=true},
func = function(name, param)
minetest.chat_send_player(name, "Settings:")
for set, def in orderedPairs(ctf._defsettings) do
minetest.chat_send_player(name, " - " .. set .. ": " .. dump(ctf.setting(set)))
print("\"" .. set .. "\" " .. dump(ctf.setting(set)))
end
return true
end
})
minetest.register_chatcommand("team_owner", {
params = "player name",
description = "Make player team owner",
privs = {ctf_admin=true},
func = function(name, param)
if ctf and ctf.players and ctf.player(param) and ctf.player(param).team and ctf.team(ctf.player(param).team) then
if ctf.player(param).auth == true then
ctf.player(param).auth = false
return true, param.." was downgraded from team admin status"
else
ctf.player(param).auth = true
return true, param.." was upgraded to an admin of "..ctf.player(name).team
end
ctf.needs_save = true
else
return false, "Unable to do that :/ "..param.." does not exist, or is not part of a valid team."
end
end
})
minetest.register_chatcommand("team_recruiter", {
params = "player name",
description = "Make player able to recruit",
func = function(name, param)
if ctf.player(name).auth or minetest.get_player_privs(name).ctf_admin then
if ctf and ctf.players and ctf.player(param) and ctf.player(param).team and ctf.team(ctf.player(param).team) then
if ctf.player(param).recruit == true then
ctf.player(param).recruit = false
return true, param.." was downgraded from team recruiter status"
else
ctf.player(param).recruit = true
return true, param.." was upgraded to a recruiter of "..ctf.player(name).team
end
ctf.needs_save = true
else
return false, "Unable to do that :/ "..param.." does not exist, or is not part of a valid team."
end
else
return false, "You are not the team owner!"
end
end
})
minetest.register_chatcommand("post", {
params = "message",
description = "Post a message on your team's message board",
func = function(name, param)
if ctf and ctf.players and ctf.players[name] and ctf.players[name].team and ctf.teams[ctf.players[name].team] then
if not ctf.player(name).auth then
minetest.chat_send_player(name, "You do not own that team")
end
if not ctf.teams[ctf.players[name].team].log then
ctf.teams[ctf.players[name].team].log = {}
end
table.insert(ctf.teams[ctf.players[name].team].log,{msg=param})
minetest.chat_send_player(name, "Posted: "..param)
else
minetest.chat_send_player(name, "Could not post message")
end
end,
})
minetest.register_chatcommand("all", {
params = "msg",
description = "Send a message on the global channel",
func = function(name, param)
if not ctf.setting("chat.global_channel") then
minetest.chat_send_player(name, "The global channel is disabled")
return
end
if ctf.player(name).team then
local tosend = ctf.player(name).team ..
" <" .. name .. "> " .. param
minetest.chat_send_all(tosend)
if minetest.global_exists("chatplus") then
chatplus.log(tosend)
end
else
minetest.chat_send_all("<"..name.."> "..param)
end
end
})
--[[
minetest.register_chatcommand("t", {
params = "msg",
description = "Send a message on the team channel",
func = function(name, param)
if not ctf.setting("chat.team_channel") then
minetest.chat_send_player(name, "The team channel is disabled.")
return
end
local tname = ctf.player(name).team
local team = ctf.team(tname)
if team then
minetest.log("action", tname .. "<" .. name .. "> ** ".. param .. " **")
if minetest.global_exists("chatplus") then
chatplus.log(tname .. "<" .. name .. "> ** ".. param .. " **")
end
for username, to in pairs(team.players) do
minetest.chat_send_player(username,
tname .. "<" .. name .. "> ** " .. param .. " **")
end
if minetest.global_exists("irc") and irc.feature_mod_channel then
irc:say(irc.config.channel, tname .. "<" .. name .. "> ** " .. param .. " **", true)
end
else
minetest.chat_send_player(name,
"You're not in a team, so you have no team to talk to.")
end
end
})--]]
-- Chat plus stuff
if minetest.global_exists("chatplus") then
function chatplus.log_message(from, msg)
local tname = ctf.player(from).team or ""
chatplus.log(tname .. "<" .. from .. "> " .. msg)
end
chatplus.register_handler(function(from, to, msg)
if not ctf.setting("chat.team_channel") then
-- Send to global
return nil
end
if ctf.setting("chat.default") ~= "team" then
if ctf.player(from).team then
minetest.chat_send_player(to, ctf.player(from).team ..
"<" .. from .. "> " .. msg)
return false
else
return nil
end
end
-- Send to team
local fromp = ctf.player(from)
local top = ctf.player(to)
if not fromp.team then
if not ctf.setting("chat.global_channel") then
-- Send to global
return nil
else
-- Global channel is disabled
minetest.chat_send_player(from,
"You are not yet part of a team! Join one so you can chat to people.",
false)
return false
end
end
if top.team == fromp.team then
minetest.chat_send_player(to, "<" .. from .. "> ** " .. msg .. " **")
end
return false
end)
end
minetest.register_on_joinplayer(function(player)
inventory_plus.register_button(player,"ctf", "ctf")
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if fields.ctf then
ctf.gui.show(player:get_player_name())
end
end)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 438 B

View File

@ -1,2 +0,0 @@
ctf
3d_armor?

View File

@ -1,60 +0,0 @@
ctf.gui.register_tab("settings", "Settings", function(name, team)
local color = ""
if ctf.team(team).data.color then
color = ctf.team(team).data.color
end
local result = "field[3,2;4,1;color;Team Color;" .. color .. "]" ..
"button[4,6;2,1;save;Save]"
if not ctf.can_mod(name,team) then
result = "label[0.5,1;You do not own this team!"
end
minetest.show_formspec(name, "ctf:settings",
"size[10,7]" ..
ctf.gui.get_tabs(name, team) ..
result
)
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "ctf:settings" then
return false
end
-- Settings page
if fields.save then
local name = player:get_player_name()
local pdata = ctf.player(name)
local team = ctf.team(pdata.team)
ctf.gui.show(name, "settings")
if team and ctf.can_mod(name, pdata.team) then
if ctf.flag_colors[fields.color] then
team.data.color = fields.color
ctf.needs_save = true
minetest.chat_send_player(name, "Team color set to " .. fields.color)
else
local colors = ""
for color, code in pairs(ctf.flag_colors) do
if colors ~= "" then
colors = colors .. ", "
end
colors = colors .. color
end
minetest.chat_send_player(name, "Color " .. fields.color ..
" does not exist! Available: " .. colors)
end
elseif team then
minetest.chat_send_player(name, "You don't have the rights to change settings.")
else
minetest.chat_send_player(name, "You don't appear to be in a team")
end
return true
end
end)

View File

@ -1,92 +0,0 @@
function ctf_colors.get_color(name, tplayer)
local team = ctf.team(tplayer.team)
local tcolor_text = nil
if team then
tcolor_text = team.data.color
end
local tcolor_hex = ctf.flag_colors[tcolor_text]
if not tcolor_hex then
tcolor_hex = "0x000000"
end
return tcolor_text, tcolor_hex
end
function ctf_colors.get_nametag_color(name, tplayer, tcolor_text, tcolor_hex)
if ctf.setting("colors.nametag.tcolor") then
return "0xFF" .. string.sub(tcolor_hex, 3)
else
return "0xFFFFFFFF"
end
end
function ctf_colors.update(player, name, tplayer)
if not player then
player = minetest.get_player_by_name(name)
end
local tcolor_text, tcolor_hex = ctf_colors.get_color(name, tplayer)
if ctf.setting("colors.nametag") then
player:set_nametag_attributes({
color = ctf_colors.get_nametag_color(name, tplayer, tcolor_text, tcolor_hex) })
end
if ctf.setting("colors.skins") and tcolor_text and tcolor_hex then
if minetest.global_exists("armor") then
-- TODO: how should support for skin mods be done?
if minetest.get_modpath("player_textures") then
local filename = minetest.get_modpath("player_textures").."/textures/player_"..name
local f = io.open(filename..".png")
if f then
f:close()
armor.textures[name].skin ="player_"..name..".png"
armor:update_player_visuals(player)
else
armor.textures[name].skin = "ctf_colors_skin_" .. tcolor_text .. ".png"
armor:update_player_visuals(player)
end
end
else
player:set_properties({
textures = {"ctf_colors_skin_" .. tcolor_text .. ".png"}
})
end
end
if not ctf.hud:exists(player, "ctf:hud_team") then
ctf.hud:add(player, "ctf:hud_team", {
hud_elem_type = "text",
position = {x = 1, y = 0},
scale = {x = 100, y = 100},
text = "Team " .. tplayer.team,
number = tcolor_hex,
offset = {x = -20, y = 20},
alignment = {x = -1, y = 0}
})
else
ctf.hud:change(player, "ctf:hud_team", "text", "Team " .. tplayer.team)
ctf.hud:change(player, "ctf:hud_team", "number", tcolor_hex)
end
end
ctf.hud.register_part(ctf_colors.update)
--[[if minetest.global_exists("armor") and armor.get_player_skin then
print("3d_armor detected!")
local old = armor.get_player_skin
function armor.get_player_skin(self, name)
local player = ctf.player(name)
local team = ctf.team(player.team)
if team and team.data.color and ctf.flag_colors[team.data.color] then
print("Return ctf_colors_skin_" .. team.data.color .. ".png")
return "ctf_colors_skin_" .. team.data.color .. ".png"
end
print("ctf_colors -!- Reverting to default armor skin")
return old(self, name)
end
end]]

View File

@ -1,27 +0,0 @@
-- Supported colors
ctf_colors = {}
ctf_colors.colors = {
red = "0xFF4444",
cyan = "0x00FFFF",
blue = "0x4466FF",
purple = "0x800080",
yellow = "0xFFFF00",
green = "0x00FF00",
pink = "0xFF00FF",
silver = "0xC0C0C0",
gray = "0x808080",
black = "0x000000",
orange = "0xFFA500",
gold = "0x808000"
}
ctf.flag_colors = ctf_colors.colors
ctf.register_on_init(function()
ctf.log("colors", "Initialising...")
ctf._set("colors.skins", false)
ctf._set("colors.nametag", true)
ctf._set("colors.nametag.tcolor", false)
end)
dofile(minetest.get_modpath("ctf_colors") .. "/hud.lua")
dofile(minetest.get_modpath("ctf_colors") .. "/gui.lua")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -1,237 +0,0 @@
ctf_flag.registered_on_capture = {}
function ctf_flag.register_on_capture(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf_flag.registered_on_capture, func)
end
ctf_flag.registered_on_pick_up = {}
function ctf_flag.register_on_pick_up(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf_flag.registered_on_pick_up, func)
end
ctf_flag.registered_on_drop = {}
function ctf_flag.register_on_drop(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf_flag.registered_on_drop, func)
end
ctf_flag.registered_on_precapture = {}
function ctf_flag.register_on_precapture(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf_flag.registered_on_precapture, func)
end
ctf_flag.registered_on_prepick_up = {}
function ctf_flag.register_on_prepick_up(func)
if ctf._mt_loaded then
error("You can't register callbacks at game time!")
end
table.insert(ctf_flag.registered_on_prepick_up, func)
end
function ctf_flag.collect_claimed()
local claimed = {}
for _, team in pairs(ctf.teams) do
for i = 1, #team.flags do
if team.flags[i].claimed then
table.insert(claimed, team.flags[i])
end
end
end
return claimed
end
function ctf_flag.get_claimed_by_player(name)
local claimed = ctf_flag.collect_claimed()
for _, flag in pairs(claimed) do
if flag.claimed.player == name then
return name
end
end
end
function ctf_flag.player_drop_flag(name)
if not name then
return
end
local claimed = ctf_flag.collect_claimed()
for i = 1, #claimed do
local flag = claimed[i]
if flag.claimed.player == name then
flag.claimed = nil
local flag_name = ""
if flag.name then
flag_name = flag.name .. " "
end
flag_name = flag.team .. "'s " .. flag_name .. "flag"
ctf.hud.updateAll()
ctf.action("flag", name .. " dropped " .. flag_name)
minetest.chat_send_all(flag_name.." has returned.")
for i = 1, #ctf_flag.registered_on_drop do
ctf_flag.registered_on_drop[i](name, flag)
end
end
end
end
-- add a flag to a team
function ctf_flag.add(team, pos)
if not team or team == "" then
return
end
ctf.log("flag", "Adding flag to " .. team .. " at (" .. pos.x ..
", " .. pos.y .. ", " .. pos.z .. ")")
if not ctf.team(team).flags then
ctf.team(team).flags = {}
end
pos.team = team
table.insert(ctf.team(team).flags,pos)
ctf.needs_save = true
end
function ctf_flag.update(pos)
if minetest.get_node(pos).name ~= "ctf_flag:flag" then
return
end
local top = {x=pos.x,y=pos.y+1,z=pos.z}
local flagmeta = minetest.get_meta(pos)
if not flagmeta then
return
end
local flag_team_data = ctf_flag.get(pos)
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))
minetest.set_node(pos,{name="air"})
minetest.set_node(top,{name="air"})
return
end
local topmeta = minetest.get_meta(top)
local flag_name = flag_team_data.name
if flag_name and flag_name ~= "" then
flagmeta:set_string("infotext", flag_name.." - "..flag_team_data.team)
else
flagmeta:set_string("infotext", flag_team_data.team.."'s flag")
end
if not ctf.team(flag_team_data.team).data.color then
ctf.team(flag_team_data.team).data.color = "red"
ctf.needs_save = true
end
if flag_team_data.claimed then
minetest.set_node(top,{name="ctf_flag:flag_captured_top"})
else
minetest.set_node(top,{name="ctf_flag:flag_top_"..ctf.team(flag_team_data.team).data.color})
end
topmeta = minetest.get_meta(top)
if flag_name and flag_name ~= "" then
topmeta:set_string("infotext", flag_name.." - "..flag_team_data.team)
else
topmeta:set_string("infotext", flag_team_data.team.."'s flag")
end
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
ctf.log("flag", "Deleting flag from " .. team .. " at (" .. pos.x ..
", " .. pos.y .. ", " .. pos.z .. ")")
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.assert_flag(flag)
minetest.get_voxel_manip(flag, { x = flag.x + 1, y = flag.y + 1, z = flag.z + 1})
local nodename = minetest.get_node(flag).name
if nodename ~= "ctf_flag:flag" then
ctf.log("flag", flag.team .. " has wrong node at flag position, " .. nodename .. ", correcting...")
minetest.set_node(flag, { name = "ctf_flag:flag"})
ctf_flag.update(flag)
end
end
function ctf_flag.assert_flags()
for tname, team in pairs(ctf.teams) do
ctf_flag.assert_flags_team(tname)
end
end
function ctf_flag.assert_flags_team(tname)
local team = ctf.team(tname)
if not tname or not team then
return false
end
if not team.flags then
team.flags = {}
end
for i=1, #team.flags do
ctf_flag.assert_flag(team.flags[i])
end
end

View File

@ -1,3 +0,0 @@
ctf
ctf_colors
chatplus?

View File

@ -1,253 +0,0 @@
local function do_capture(attname, flag, returned)
local team = flag.team
local attacker = ctf.player(attname)
local flag_name = ""
if flag.name then
flag_name = flag.name .. " "
end
flag_name = team .. "'s " .. flag_name .. "flag"
if ctf.setting("flag.capture_take") and not returned then
for i = 1, #ctf_flag.registered_on_prepick_up do
if not ctf_flag.registered_on_prepick_up[i](attname, flag) then
return
end
end
minetest.chat_send_all(flag_name.." has been picked up by "..
attname.." (team "..attacker.team..")")
ctf.action("flag", attname .. " picked up " .. flag_name)
-- Post to flag owner's board
ctf.post(team, {
msg = flag_name .. " has been taken by " .. attname .. " of ".. attacker.team,
icon="flag_red" })
-- Post to attacker's board
ctf.post(attacker.team, {
msg = attname .. " snatched '" .. flag_name .. "' from " .. team,
icon="flag_green"})
-- Add to claimed list
flag.claimed = {
team = attacker.team,
player = attname
}
ctf.hud.updateAll()
ctf_flag.update(flag)
for i = 1, #ctf_flag.registered_on_pick_up do
ctf_flag.registered_on_pick_up[i](attname, flag)
end
else
for i = 1, #ctf_flag.registered_on_precapture do
if not ctf_flag.registered_on_precapture[i](attname, flag) then
return
end
end
minetest.chat_send_all(flag_name.." has been captured "..
" by "..attname.." (team "..attacker.team..")")
irc:say(flag_name.." has been captured by "..attname.." (team "..attacker.team..")")
ctf.action("flag", attname .. " captured " .. flag_name)
-- Post to flag owner's board
ctf.post(team, {
msg = flag_name .. " has been captured by " .. attacker.team,
icon="flag_red"})
-- Post to attacker's board
ctf.post(attacker.team, {
msg = attname .. " captured '" .. flag_name .. "' from " .. team,
icon="flag_green"})
-- Take flag
if ctf.setting("flag.allow_multiple") then
ctf_flag.delete(team, vector.new(flag))
ctf_flag.add(attacker.team, vector.new(flag))
else
minetest.set_node(pos,{name="air"})
ctf_flag.delete(team,pos)
end
for i = 1, #ctf_flag.registered_on_capture do
ctf_flag.registered_on_capture[i](attname, flag)
end
end
ctf.needs_save = true
end
local function player_drop_flag(player)
return ctf_flag.player_drop_flag(player:get_player_name())
end
minetest.register_on_dieplayer(player_drop_flag)
minetest.register_on_leaveplayer(player_drop_flag)
ctf_flag = {
on_punch_top = function(pos, node, puncher)
pos.y = pos.y - 1
ctf_flag.on_punch(pos, node, puncher)
end,
on_rightclick_top = function(pos, node, clicker)
pos.y = pos.y - 1
ctf_flag.on_rightclick(pos, node, clicker)
end,
on_rightclick = function(pos, node, clicker)
local name = clicker:get_player_name()
local flag = ctf_flag.get(pos)
if not flag then
return
end
if flag.claimed then
if ctf.setting("flag.capture_take") then
minetest.chat_send_player(name, "This flag has been taken by "..flag.claimed.player)
minetest.chat_send_player(name, "who is a member of team "..flag.claimed.team)
return
else
minetest.chat_send_player(name, "Oops! This flag should not be captured. Reverting...")
flag.claimed = nil
end
end
ctf.gui.flag_board(name, pos)
end,
on_punch = function(pos, node, puncher)
local name = puncher:get_player_name()
if not puncher or not name then
return
end
local flag = ctf_flag.get(pos)
if not flag then
return
end
if flag.claimed then
if ctf.setting("flag.capture_take") then
minetest.chat_send_player(name, "This flag has been taken by " .. flag.claimed.player)
minetest.chat_send_player(name, "who is a member of team " .. flag.claimed.team)
return
else
minetest.chat_send_player(name, "Oops! This flag should not be captured. Reverting.")
flag.claimed = nil
end
end
local team = flag.team
if not team then
return
end
if ctf.team(team) and ctf.player(name).team then
if ctf.player(name).team == team then
-- Clicking on their team's flag
if ctf.setting("flag.capture_take") then
ctf_flag._flagret(name)
end
else
-- Clicked on another team's flag
local diplo = ctf.diplo.get(team, ctf.player(name).team) or
ctf.setting("default_diplo_state")
if diplo ~= "war" then
minetest.chat_send_player(name, "You are at peace with this team!")
return
end
do_capture(name, flag)
end
else
minetest.chat_send_player(name, "You are not part of a team!")
end
end,
_flagret = function(name)
local claimed = ctf_flag.collect_claimed()
for i = 1, #claimed do
local flag = claimed[i]
if flag.claimed.player == name then
do_capture(name, flag, true)
end
end
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Unowned flag")
end,
after_place_node = function(pos, placer)
local name = placer:get_player_name()
if not pos or not name then
minetest.set_node(pos, {name="air"})
return
end
local meta = minetest.get_meta(pos)
if not meta then
minetest.set_node(pos, {name="air"})
return
end
local tplayer = ctf.player_or_nil(name)
if tplayer and ctf.team(tplayer.team) then
if not minetest.check_player_privs(name, {ctf_place_flag=true}) then
minetest.chat_send_player(name, "You're not allowed to place flags! Reported to admin for investigation.")
minetest.set_node(pos, {name="air"})
if minetest.global_exists("chatplus") then
chatplus.send_mail("*SERVER*", minetest.setting_get("name"),
"player " .. name .. " attempted to place flag!")
end
return
end
local tname = tplayer.team
local team = ctf.team(tplayer.team)
meta:set_string("infotext", tname.."'s flag")
-- add flag
ctf_flag.add(tname, pos)
-- TODO: fix this hackiness
if team.spawn and not ctf.setting("flag.allow_multiple") and
minetest.get_node(team.spawn).name == "ctf_flag:flag" then
-- send message
minetest.chat_send_all(tname .. "'s flag has been moved")
minetest.set_node(team.spawn, {name="air"})
minetest.set_node({
x = team.spawn.x,
y = team.spawn.y+1,
z = team.spawn.z
}, {name="air"})
team.spawn = pos
end
ctf.needs_save = true
local pos2 = {
x = pos.x,
y = pos.y + 1,
z = pos.z
}
if not team.data.color then
team.data.color = "red"
ctf.needs_save = true
end
minetest.set_node(pos2, {name="ctf_flag:flag_top_"..team.data.color})
local meta2 = minetest.get_meta(pos2)
meta2:set_string("infotext", tname.."'s flag")
else
minetest.chat_send_player(name, "You are not part of a team!")
minetest.set_node(pos, {name="air"})
end
end
}

View File

@ -1,93 +0,0 @@
-- The flag
minetest.register_node("ctf_flag:flag", {
description = "Flag",
drawtype="nodebox",
paramtype = "light",
walkable = false,
tiles = {
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png"
},
node_box = {
type = "fixed",
fixed = {
{0.250000,-0.500000,0.000000,0.312500,0.500000,0.062500}
}
},
groups = {immortal=1,is_flag=1,flag_bottom=1},
on_punch = ctf_flag.on_punch,
on_rightclick = ctf_flag.on_rightclick,
on_construct = ctf_flag.on_construct,
after_place_node = ctf_flag.after_place_node
})
--[[
minetest.register_craft({
output = "ctf_flag:flag",
recipe = {
{"default:stick", "group:wool"},
{"default:stick", "",},
{"default:stick", ""}
}
})
--]]
for color, _ in pairs(ctf.flag_colors) do
minetest.register_node("ctf_flag:flag_top_"..color,{
description = "You are not meant to have this! - flag top",
drawtype="nodebox",
paramtype = "light",
walkable = false,
tiles = {
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png",
"flag_"..color.."2.png",
"flag_"..color..".png"
},
node_box = {
type = "fixed",
fixed = {
{0.250000,-0.500000,0.000000,0.312500,0.500000,0.062500},
{-0.5,0,0.000000,0.250000,0.500000,0.062500}
}
},
groups = {immortal=1,is_flag=1,flag_top=1,not_in_creative_inventory=1},
on_punch = ctf_flag.on_punch_top,
on_rightclick = ctf_flag.on_rightclick_top
})
end
minetest.register_node("ctf_flag:flag_captured_top",{
description = "You are not meant to have this! - flag captured",
drawtype = "nodebox",
paramtype = "light",
walkable = false,
tiles = {
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png",
"default_wood.png"
},
node_box = {
type = "fixed",
fixed = {
{0.250000,-0.500000,0.000000,0.312500,0.500000,0.062500}
}
},
groups = {immortal=1,is_flag=1,flag_top=1,not_in_creative_inventory=1},
on_punch = ctf_flag.on_punch_top,
on_rightclick = ctf_flag.on_rightclick_top
})
minetest.register_abm({
nodenames = {"group:flag_bottom"},
inteval = 5,
chance = 1,
action = ctf_flag.update
})

View File

@ -1,184 +0,0 @@
-- Team interface
ctf.gui.register_tab("flags", "Flags", function(name, team)
local result = ""
local t = ctf.team(team)
if not t then
return
end
local x = 1
local y = 2
result = result .. "label[1,1;Click a flag button to go there]"
if ctf.setting("gui.team.teleport_to_spawn") and minetest.get_setting("static_spawnpoint") then
local x,y,z = string.match(minetest.get_setting("static_spawnpoint"), "(%d+),(%d+),(%d+)")
result = result ..
"button[" .. x .. "," .. y .. ";2,1;goto_"
..f.x.."_"..f.y.."_"..f.z..";"
result = result .. "Spawn]"
x = x + 2
end
for i=1, #t.flags do
local f = t.flags[i]
if x > 8 then
x = 1
y = y + 1
end
if y > 6 then
break
end
result = result ..
"button[" .. x .. "," .. y .. ";2,1;goto_"
..f.x.."_"..f.y.."_"..f.z..";"
if f.name then
result = result .. f.name .. "]"
else
result = result .. "("..f.x..","..f.y..","..f.z..")]"
end
x = x + 2
end
minetest.show_formspec(name, "ctf:flags",
"size[10,7]"..
ctf.gui.get_tabs(name,team)..
result)
end)
minetest.register_on_player_receive_fields(function(player, formname, fields)
-- Todo: fix security issue here
local name = player:get_player_name()
if formname == "ctf:flags" then
for key, field in pairs(fields) do
local x,y,z = string.match(key, "goto_([%d-]+)_([%d-]+)_([%d-]+)")
if x and y and z then
player:setpos({ x=tonumber(x), y=tonumber(y), z=tonumber(z) })
return true
end
end
end
end)
-- Flag interface
function ctf.gui.flag_board(name, pos)
local flag = ctf_flag.get(pos)
if not flag then
return
end
local team = flag.team
if not team then
return
end
if not ctf.can_mod(name, team) then
if ctf.player(name).team and ctf.player(name).team == team then
ctf.gui.show(name)
end
return
end
ctf.log("gui", name .. " views flag board")
local flag_name = flag.name
if not ctf.setting("flag.names") then
flag.name = nil
return
end
if not ctf.setting("gui") then
return
end
if not flag_name then
flag_name = ""
end
if not ctf.gui.flag_data then
ctf.gui.flag_data = {}
end
ctf.gui.flag_data[name] = {pos=pos}
minetest.show_formspec(name, "ctf:flag_board",
"size[6,3]"..
"field[1,1;4,1;flag_name;Flag Name;"..flag_name.."]"..
"button_exit[1,2;2,1;save;Save]"..
"button_exit[3,2;2,1;delete;Delete]"
)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
local name = player:get_player_name()
if not formname=="ctf:flag_board" then
return false
end
if fields.save and fields.flag_name then
local flag = ctf_flag.get(ctf.gui.flag_data[name].pos)
if not flag then
return false
end
local team = flag.team
if not team then
return false
end
if ctf.can_mod(name,team) == false then
return false
end
local flag_name = flag.name
if not flag_name then
flag_name = ""
end
flag.name = fields.flag_name
local msg = flag_name.." was renamed to "..fields.flag_name
if flag_name=="" then
msg = "A flag was named "..fields.flag_name.." at ("..ctf.gui.flag_data[name].pos.x..","..ctf.gui.flag_data[name].pos.z..")"
end
ctf.post(team,{msg=msg,icon="flag_info"})
return true
elseif fields.delete then
local pos = ctf.gui.flag_data[name].pos
local flag = ctf_flag.get(ctf.gui.flag_data[name].pos)
if not flag then
return
end
local team = flag.team
if not team then
return
end
if ctf.can_mod(name,team) == false then
return false
end
ctf_flag.delete(team,pos)
minetest.set_node(pos,{name="air"})
pos.y=pos.y+1
minetest.set_node(pos,{name="air"})
player:get_inventory():add_item('main', 'ctf_flag:flag')
return true
end
end)

View File

@ -1,73 +0,0 @@
-- TODO: delete flags if they are removed (ctf.next, or captured)
ctf.hud.register_part(function(player, name, tplayer)
if ctf.setting("flag.waypoints") then
for tname, team in pairs(ctf.teams) do
for _, flag in pairs(team.flags) do
local hud = "ctf:hud_" .. flag.x .. "_" .. flag.y .. "_" .. flag.z
local flag_name = flag.name or tname .. "'s base"
local color = ctf.flag_colors[team.data.color]
if not color then
color = "0x000000"
end
if not ctf.hud:exists(player, hud) then
ctf.hud:add(player, hud, {
hud_elem_type = "waypoint",
name = flag_name,
number = color,
world_pos = {
x = flag.x,
y = flag.y,
z = flag.z
}
})
end
end
end
end
end)
ctf.hud.register_part(function(player, name, tplayer)
-- Check all flags
local alert = nil
local color = "0xFFFFFF"
if ctf.setting("flag.alerts") then
if ctf.setting("flag.alerts.neutral_alert") then
alert = "Punch the enemy flag! Protect your flag!"
end
local claimed = ctf_flag.collect_claimed()
for _, flag in pairs(claimed) do
if flag.claimed.player == name then
alert = "You've got the flag! Run back and punch your flag!"
color = "0xFF0000"
break
elseif flag.team == tplayer.team then
alert = "Kill " .. flag.claimed.player .. ", they have your flag!"
color = "0xFF0000"
break
else
alert = "Protect " .. flag.claimed.player .. ", he's got the enemy flag!"
color = "0xFF0000"
end
end
end
-- Display alert
if alert then
if ctf.hud:exists(player, "ctf:hud_team_alert") then
ctf.hud:change(player, "ctf:hud_team_alert", "text", alert)
ctf.hud:change(player, "ctf:hud_team_alert", "number", color)
else
ctf.hud:add(player, "ctf:hud_team_alert", {
hud_elem_type = "text",
position = {x = 1, y = 0},
scale = {x = 100, y = 100},
text = alert,
number = color,
offset = {x = -10, y = 50},
alignment = {x = -1, y = 0}
})
end
else
ctf.hud:remove(player, "ctf:hud_team_alert")
end
end)

View File

@ -1,163 +0,0 @@
-- Initialise
ctf.register_on_init(function()
ctf.log("flag", "Initialising...")
ctf._set("flag.allow_multiple", true)
ctf._set("flag.capture_take", false)
ctf._set("flag.names", true)
ctf._set("flag.waypoints", true)
ctf._set("flag.protect_distance", 25)
ctf._set("flag.nobuild_radius", 3)
ctf._set("flag.drop_time", 7*60)
ctf._set("flag.drop_warn_time", 60)
ctf._set("flag.alerts", true)
ctf._set("flag.alerts.neutral_alert", true)
ctf._set("gui.team.teleport_to_flag", true)
ctf._set("gui.team.teleport_to_spawn", false)
end)
minetest.register_privilege("ctf_place_flag", {
description = "can place flag"
})
dofile(minetest.get_modpath("ctf_flag") .. "/hud.lua")
dofile(minetest.get_modpath("ctf_flag") .. "/gui.lua")
dofile(minetest.get_modpath("ctf_flag") .. "/flag_func.lua")
dofile(minetest.get_modpath("ctf_flag") .. "/api.lua")
dofile(minetest.get_modpath("ctf_flag") .. "/flags.lua")
ctf.register_on_new_team(function(team)
team.flags = {}
end)
function ctf_flag.get_nearest(pos)
local closest = 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_distSQ = distSQ
end
end
end
return closest, closest_distSQ
end
function ctf_flag.get_nearest_team_dist(pos)
local flag, distSQ = ctf_flag.get_nearest(pos)
if flag then
return flag.team, distSQ
end
end
ctf.register_on_territory_query(ctf_flag.get_nearest_team_dist)
function ctf.get_spawn(team)
if not ctf.team(team) then
return nil
end
if ctf.team(team).spawn then
return ctf.team(team).spawn
end
-- Get spawn from first flag
ctf_flag.assert_flags(team)
if #ctf.team(team).flags > 0 then
return ctf.team(team).flags[1]
else
return nil
end
end
-- Add minimum build range
local old_is_protected = minetest.is_protected
local r = ctf.setting("flag.nobuild_radius")
local rs = r * r
function minetest.is_protected(pos, name)
if r <= 0 or rs == 0 then
return old_is_protected(pos, name)
end
local flag, distSQ = ctf_flag.get_nearest(pos)
if flag and pos.y >= flag.y and distSQ < rs then
minetest.chat_send_player(name,
"Too close to the flag to build! Leave at least " .. r .. " blocks around the flag.")
return true
else
return old_is_protected(pos, name)
end
end
-- Play sound
ctf_flag.register_on_pick_up(function(attname, flag)
local vteam = ctf.team(flag.team)
for name, player in pairs(vteam.players) do
minetest.sound_play({name="trumpet_lose"}, {
to_player = name,
gain = 1.0, -- default
})
end
local ateam = ctf.team(ctf.player(attname).team)
for name, player in pairs(ateam.players) do
minetest.sound_play({name="trumpet_win"}, {
to_player = name,
gain = 1.0, -- default
})
end
end)
-- Change nametag color
local oldntc = ctf_colors.get_nametag_color
function ctf_colors.get_nametag_color(name, tplayer, tcolor_text, tcolor_hex)
if ctf_flag.get_claimed_by_player(name) then
return "0xFFFF0000"
else
return oldntc(name, tplayer, tcolor_text, tcolor_hex)
end
end
ctf_flag.register_on_pick_up(function(attname, flag)
ctf_colors.update(nil, attname, ctf.player(attname))
end)
ctf_flag.register_on_drop(function(attname, flag)
ctf_colors.update(nil, attname, ctf.player(attname))
end)
-- Drop after time
local pickup_times = {}
ctf_flag.register_on_pick_up(function(attname, flag)
pickup_times[attname] = minetest.get_gametime()
end)
ctf_flag.register_on_drop(function(attname, flag)
pickup_times[attname] = nil
end)
ctf_flag.register_on_capture(function(attname, flag)
pickup_times[attname] = nil
end)
ctf.register_on_new_game(function()
pickup_times = {}
end)
local function update_flag_drops()
local time = minetest.get_gametime()
local drop_time = ctf.setting("flag.drop_time")
for name, start in pairs(pickup_times) do
local remaining = drop_time - time + start
if remaining < 0 then
ctf_flag.player_drop_flag(name)
minetest.chat_send_player(name, "You took too long to capture the flag, so it returned!")
elseif remaining < ctf.setting("flag.drop_warn_time") then
minetest.chat_send_player(name, "You have " .. remaining ..
" seconds to capture the flag before it returns.")
end
end
minetest.after(5, update_flag_drops)
end
minetest.after(5, update_flag_drops)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 676 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 618 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 625 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 826 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 635 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 688 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 616 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 812 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 874 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 657 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 671 B

View File

@ -1 +0,0 @@
ctf

View File

@ -1,28 +0,0 @@
-- This mod is used to protect nodes in the capture the flag game
ctf.register_on_init(function()
ctf.log("chat", "Initialising...")
-- Settings: Chat
ctf._set("node_ownership", true)
end)
local old_is_protected = minetest.is_protected
function minetest.is_protected(pos, name)
if not ctf.setting("node_ownership") then
return old_is_protected(pos, name)
end
local team = ctf.get_territory_owner(pos)
if not team or not ctf.team(team) then
return old_is_protected(pos, name)
end
if ctf.player(name).team == team then
return old_is_protected(pos, name)
else
minetest.chat_send_player(name, "You cannot dig on team "..team.."'s land")
return true
end
end

View File

@ -1,80 +0,0 @@
# Data Formats
This file documents the contents of ctf.txt
Values are added to the file using ctf.register_on_save and ctf.register_on_load.
Here are the default values:
```lua
{
players = ctf.players,
teams = ctf.teams,
diplo = ctf.diplo.diplo
}
```
## Players
Commonly called tplayer (may be called data or player in old code).
Player name is commonly called name (but may be called other things in older code).
```lua
ctf.players = {
username = (player_table)
}
(player_table) = {
name = "username",
team = "teamname",
auth = false
-- true if the player is a team admin. Team admins can change team settings.
-- See ctf.can_mod()
-- Note that priv:ctf_admin can also change team settings
}
```
## Teams
Commonly called team.
Team name is commonly called tname (but may be called team in old code).
```lua
ctf.teams = {
teamname = (team_table)
}
(team_table) = {
data = {
name = "teamname",
color = "teamcolor" -- see ctf_colors
},
flags = {
(flag_table), (flag_table)
},
players = {
username1 = (player_table),
username2 = (player_table)
},
spawn = { x=0, y=0, z=0 }
-- fallback team spawn. Read by ctf.get_spawn() and overriding functions
-- Don't use directly, instead call ctf.get_spawn("teamname")
}
(flag_table) = {
x=0, y=0, z=0,
flag_name = "Capital" -- human readable name
}
```
## Diplomacy
```lua
ctf.diplo.diplo = {
(diplo_table), (diplo_table)
}
(diplo_table) = {
one = "teamname1",
two = "teamname2",
state = "war" / "peace" / "alliance"
}
```

View File

@ -1,70 +0,0 @@
# Welcome
The aim of CTF_PvP_Engine is to provide a base to any subgame which uses the
concepts of teams. Flags are a plugin mod, so it isn't CTF as such.
# Modules in CTF_PvP_Engine
## hudkit
A support library to make the HUD API nicer.
WTFPL.
## ctf
Requires hudkit. Support for chatplus.
Core framework, players, teams, diplomacy, hud and gui.
* core - adds saving, loading and settings. All modules depend on this.
* teams - add the concepts of teams and players. All modules except core depend on this.
* diplomacy - adds inter team states of war, peace and alliances.
* gui - adds the team gui on /team. Allows tabs to be registered.
* hud - adds the name of the team in the TR of the screen, and sets the color
## ctf_chat
Requires ctf. Support for chatplus.
Chat commands and chat channels.
## ctf_colors
Requires ctf. Support for 3d_armor.
Adds player colors.
* gui - settings form
* hud - team name color, player skin color, nametag color
* init - table of colors
## ctf_flag
Requires ctf and ctf_colors. Support for chatplus.
Adds flags and flag taking.
* api - flag callbacks, flag management (adding, capturing, updating), flag checking (asserts)
* flag_func - functions for flag node definitions.
* flags - flag node definitions.
* gui - flag naming GUI, flag teleport GUI.
* hud - waypoints, alerts ("Punch the enemy flag!" etc in top right)
* init - get nearest flag, overrides ctf.get_spawn(), minimum build range, pick up sound, flag capture timeout.
## ctf_protect
Adds node ownership / protection to teams.
Requires ctf_flag.
# Past/Other Mods
Please look
## ctf_turret
Adds auto-firing turrets that fire on enemies.
See git history.
## Capture the flag
more mods available in [capture the flag](http://github.com/rubenwardy/capturetheflag/).
* ctf_match - adds the concept of winning, match build time,
and reseting the map / setting up a new game.
Requires ctf_flag

View File

@ -1,58 +0,0 @@
# ctf mod
| name | default value | description |
| -------------------------- | ------------- | ---------------------------------------------------------------- |
| allocate_mode | 0 | 0=off, 1=firstnonfullteam, 2=RandomOfSmallestTwo, 3=SmallestTeam |
| autoalloc_on_joinplayer | true | Trigger auto alloc on join player |
| default_diplo_state | war | war, alliance or peace |
| diplomacy | true | is diplomacy enabled |
| friendly_fire | true | true if players can't hit other players on their team |
| maximum_in_team | -1 | player cap |
| players_can_change_team | true | |
| hud | true | Enable HUD |
| gui | true | Enable GUI |
| gui.team | true | Whether to show team gui (/team) |
| gui.team.initial | news | Initial tab |
| gui.tab.diplo | true | Show diplo tab |
| gui.tab.news | true | Show news tab |
| gui.tab.settings | true | Show settings tab |
# ctf_chat
| name | default value | description |
| -------------------------- | ------------- | ---------------------------------------------------------------- |
| chat.default | global | global or team |
| chat.global_channel | true | |
| chat.team_channel | true | |
# ctf_colors
| name | default value | description |
| -------------------------- | ------------- | ---------------------------------------------------------------- |
| colors.nametag | true | Whether to colour the name tagColour nametag |
| colors.nametag.tcolor | false | Base nametag colour on team colour |
| colors.skins | false | Team skins are coloured |
# ctf_flag
| name | default value | description |
| -------------------------- | ------------- | ---------------------------------------------------------------- |
| flag.alerts | true | prompts like "X has captured your flag" |
| flag.alerts.neutral_alert | true | show prompt in neutral state, ie: "attack and defend!" |
| flag.allow_multiple | true | teams can have multiple flags |
| flag.capture_take | false | whether a player needs to return flag to base to capture |
| flag.drop_time | 420 | time in seconds before a player drops the flag they're holding |
| flag.drop_warn_time | 60 | warning time before drop |
| flag.nobuild_radius | 3 | area around flag where you can't build |
| flag.names | true | enable naming flags |
| flag.protect_distance | 25 | area protection distance |
| flag.waypoints | true | enable waypoints to flags |
| gui.tab.flags | true | Show flags tab |
| gui.team.teleport_to_flag | true | Enable teleport to flag button in flags tab |
| gui.team.teleport_to_spawn | false | Enable teleport to spawn button in flags tab |
# ctf_protect
| name | default value | description |
| -------------------------- | ------------- | ---------------------------------------------------------------- |
| node_ownership | true | whether node protection per team is enabled

View File

@ -1,67 +0,0 @@
function hudkit()
return {
players = {},
add = function(self, player, id, def)
local name = player:get_player_name()
local elements = self.players[name]
if not elements then
self.players[name] = {}
elements = self.players[name]
end
elements[id] = {
id = player:hud_add(def),
def = def
}
return true
end,
exists = function(self, player, id)
if not player then
return false
end
local name = player:get_player_name()
local elements = self.players[name]
if not elements or not elements[id] then
return false
end
return true
end,
change = function(self, player, id, stat, value)
if not player then
return false
end
local name = player:get_player_name()
local elements = self.players[name]
if not elements or not elements[id] or not elements[id].id then
return false
end
if elements[id].def[stat] ~= value then
elements[id].def[stat] = value
player:hud_change(elements[id].id, stat, value)
end
return true
end,
remove = function(self, player, id)
local name = player:get_player_name()
local elements = self.players[name]
if not elements or not elements[id] or not elements[id].id then
return false
end
player:hud_remove(elements[id].id)
elements[id] = nil
return true
end
}
end

104
mods/factions/banner.lua Normal file
View File

@ -0,0 +1,104 @@
-- nodes
minetest.register_node("factions:power_banner", {
drawtype = "normal",
tiles = {"power_banner.png"},
description = "Power Banner",
groups = {cracky=3},
diggable = true,
stack_max = 1,
paramtype = "light",
paramtype2 = "facedir",
after_place_node = function (pos, player, itemstack, pointed_thing)
after_powerbanner_placed(pos, player, itemstack, pointed_thing)
end,
on_dig = function(pos, n, p)
if minetest.is_protected(pos, p:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
local facname = meta:get_string("faction")
if facname then
local faction = factions.factions[facname]
if faction then
faction:decrease_maxpower(config.power_per_banner)
end
end
minetest.node_dig(pos, n, p)
end,
})
minetest.register_node("factions:death_banner", {
drawtype = "normal",
tiles = {"death_banner.png"},
description = "Death Banner",
groups = {cracky=3},
diggable = true,
stack_max = 1,
paramtype = "light",
paramtype2 = "facedir",
after_place_node = function (pos, player, itemstack, pointed_thing)
after_deathbanner_placed(pos, player, itemstack, pointed_thing)
end,
on_dig = function(pos, n, p)
if minetest.is_protected(pos, p:get_player_name()) then
return
end
local meta = minetest.get_meta(pos)
local defending_facname = meta:get_string("faction")
local parcelpos = factions.get_parcel_pos(pos)
if defending_facname then
local faction = factions.factions[defending_facname]
if faction then
faction:stop_attack(parcelpos)
end
end
minetest.remove_node(pos)
end,
})
after_powerbanner_placed = function(pos, player, itemstack, pointed_thing)
--minetest.get_node(pos).param2 = determine_flag_direction(pos, pointed_thing)
local faction = factions.players[player:get_player_name()]
if not faction then
minetest.get_meta(pos):set_string("banner", "bg_white.png")
else
local banner_string = "bg_white.png"--factions[faction].banner
minetest.get_meta(pos):set_string("banner", banner_string)
minetest.get_meta(pos):set_string("faction", faction)
factions.factions[faction]:increase_maxpower(config.power_per_banner)
end
end
after_deathbanner_placed = function(pos, player, itemstack, pointed_thing)
-- minetest.get_node(pos).param2 = determine_flag_direction(pos, pointed_thing)
local attacking_faction = factions.players[player:get_player_name()]
if attacking_faction ~= nil then
local parcelpos = factions.get_parcel_pos(pos)
attacking_faction = factions.factions[attacking_faction]
attacking_faction:attack_parcel(parcelpos)
minetest.get_meta(pos):set_string("faction", attacking_faction.name)
end
minetest.get_meta(pos):set_string("banner", "death_uv.png")
end
if minetest.get_modpath("default") then
minetest.register_craft({
output = 'factions:power_banner',
recipe = {
{'default:mese_crystal','default:mese_crystal','default:mese_crystal'},
{'default:mese_crystal','default:goldblock','default:mese_crystal'},
{'default:mese_crystal','default:mese_crystal','default:mese_crystal'}
}
})
end
if minetest.get_modpath("default") and minetest.get_modpath("bones") then
minetest.register_craft({
output = 'factions:death_banner',
recipe = {
{'default:obsidian','default:obsidian','default:obsidian'},
{'default:obsidian','bones:bones','default:obsidian'},
{'default:obsidian','default:obsidian','default:obsidian'}
}
})
end

View File

@ -0,0 +1,850 @@
-------------------------------------------------------------------------------
-- factions Mod by Sapier
--
-- License WTFPL
--
--! @file chatcommnd.lua
--! @brief factions chat interface
--! @copyright Sapier, agrecascino, shamoanjac, Coder12a
--! @author Sapier, agrecascino, shamoanjac, Coder12a
--! @date 2016-08-12
--
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
local send_error = function(player, message)
minetest.chat_send_player(player, message)
end
factions_chat = {}
factions.commands = {}
factions.register_command = function(cmd_name, cmd, ignore_param_count)
factions.commands[cmd_name] = { -- default command
name = cmd_name,
faction_permissions = {},
global_privileges = {},
format = {},
infaction = true,
description = "This command has no description.",
run = function(self, player, argv)
if self.global_privileges then
local tmp = {}
for i in ipairs(self.global_privileges) do
tmp[self.global_privileges[i]] = true
end
local bool, missing_privs = minetest.check_player_privs(player, tmp)
if not bool then
send_error(player, "Unauthorized.")
return false
end
end
-- checks argument formats
local args = {
factions = {},
players = {},
strings = {},
other = {}
}
if not ignore_param_count then
if #argv < #(self.format) then
send_error(player, "Not enough parameters.")
return false
end
else
if self.format[1] then
local fm = self.format[1]
for i in ipairs(argv) do
if #argv > #(self.format) then
table.insert(self.format, fm)
else
break
end
end
end
end
for i in ipairs(self.format) do
local argtype = self.format[i]
local arg = argv[i]
if argtype == "faction" then
local fac = factions.get_faction(arg)
if not fac then
send_error(player, "Specified faction "..arg.." does not exist")
return false
else
table.insert(args.factions, fac)
end
elseif argtype == "player" then
local pl = minetest.get_player_by_name(arg)
if not pl and not factions.players[arg] then
send_error(player, "Player is not online.")
return false
else
table.insert(args.players, pl)
end
elseif argtype == "string" then
table.insert(args.strings, arg)
else
minetest.log("error", "Bad format definition for function "..self.name)
send_error(player, "Internal server error")
return false
end
end
for i=2, #argv do
if argv[i] then
table.insert(args.other, argv[i])
end
end
-- checks permissions
local player_faction = factions.get_player_faction(player)
if self.infaction and not player_faction then
minetest.chat_send_player(player, "This command is only available within a faction.")
return false
end
if self.faction_permissions then
for i in ipairs(self.faction_permissions) do
if not player_faction:has_permission(player, self.faction_permissions[i]) then
send_error(player, "You don't have permissions to do that.")
return false
end
end
end
-- get some more data
local pos = minetest.get_player_by_name(player):getpos()
local parcelpos = factions.get_parcel_pos(pos)
return self.on_success(player, player_faction, pos, parcelpos, args)
end,
on_success = function(player, faction, pos, parcelpos, args)
minetest.chat_send_player(player, "Not implemented yet!")
end
}
-- override defaults
for k, v in pairs(cmd) do
factions.commands[cmd_name][k] = v
end
end
local init_commands
init_commands = function()
minetest.register_privilege("faction_user",
{
description = "this user is allowed to interact with faction mod",
give_to_singleplayer = true,
}
)
minetest.register_privilege("faction_admin",
{
description = "this user is allowed to create or delete factions",
give_to_singleplayer = true,
}
)
minetest.register_chatcommand("factions",
{
params = "<cmd> <parameter 1> .. <parameter n>",
description = "faction administration functions",
privs = { interact=true,faction_user=true },
func = factions_chat.cmdhandler,
}
)
minetest.register_chatcommand("f",
{
params = "<command> parameters",
description = "Factions commands. Type /f help for available commands.",
privs = { interact=true,faction_user=true},
func = factions_chat.cmdhandler,
}
)
end
-------------------------------------------
-- R E G I S T E R E D C O M M A N D S |
-------------------------------------------
factions.register_command ("claim", {
faction_permissions = {"claim"},
description = "Claim the plot of land you're on.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local can_claim = faction:can_claim_parcel(parcelpos)
if can_claim then
minetest.chat_send_player(player, "Claming parcel "..parcelpos)
faction:claim_parcel(parcelpos)
return true
else
local parcel_faction = factions.get_parcel_faction(parcelpos)
if not parcel_faction then
send_error(player, "You faction cannot claim any (more) parcel(s).")
return false
elseif parcel_faction.name == faction.name then
send_error(player, "This parcel already belongs to your faction.")
return false
else
send_error(player, "This parcel belongs to another faction.")
return false
end
end
end
},false)
factions.register_command("unclaim", {
faction_permissions = {"claim"},
description = "Unclaim the plot of land you're on.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local parcel_faction = factions.get_parcel_faction(parcelpos)
if not parcel_faction then
send_error(player, "This parcel does not exist.")
return false
end
if parcel_faction.name ~= faction.name then
send_error(player, "This parcel does not belong to you.")
return false
else
faction:unclaim_parcel(parcelpos)
return true
end
end
},false)
--list all known factions
factions.register_command("list", {
description = "List all registered factions.",
infaction = false,
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local list = factions.get_faction_list()
local tosend = "Existing factions:"
for i,v in ipairs(list) do
if i ~= #list then
tosend = tosend .. " " .. v .. ","
else
tosend = tosend .. " " .. v
end
end
minetest.chat_send_player(player, tosend, false)
return true
end
},false)
--show factions mod version
factions.register_command("version", {
description = "Displays mod version.",
on_success = function(player, faction, pos, parcelpos, args)
minetest.chat_send_player(player, "factions: version " .. factions_version , false)
end
},false)
--show description of faction
factions.register_command("info", {
format = {"faction"},
description = "Shows a faction's description.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
minetest.chat_send_player(player,
"factions: " .. args.factions[1].name .. ": " ..
args.factions[1].description, false)
return true
end
},false)
factions.register_command("leave", {
description = "Leave your faction.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:remove_player(player)
return true
end
},false)
factions.register_command("kick", {
faction_permissions = {"playerslist"},
format = {"player"},
description = "Kick a player from your faction.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local victim = args.players[1]
local victim_faction = factions.get_player_faction(victim:get_player_name())
if victim_faction and victim:get_player_name() ~= faction.leader then -- can't kick da king
faction:remove_player(victim:get_player_name())
return true
elseif not victim_faction then
send_error(player, victim:get_player_name().." is not in your faction.")
return false
else
send_error(player, victim:get_player_name().." cannot be kicked from your faction.")
return false
end
end
},false)
--create new faction
factions.register_command("create", {
format = {"string"},
infaction = false,
description = "Create a new faction.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
if faction then
send_error(player, "You are already in a faction.")
return false
end
local factionname = args.strings[1]
if factions.can_create_faction(factionname) then
new_faction = factions.new_faction(factionname, nil)
new_faction:add_player(player, new_faction.default_leader_rank)
return true
else
send_error(player, "Faction cannot be created.")
return false
end
end
},false)
factions.register_command("join", {
format = {"faction"},
description = "Join a faction.",
infaction = false,
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local new_faction = args.factions[1]
if new_faction:can_join(player) then
if faction then -- leave old faction
faction:remove_player(player)
end
new_faction:add_player(player)
else
send_error(player, "You cannot join this faction.")
return false
end
return true
end
},false)
factions.register_command("disband", {
faction_permissions = {"disband"},
description = "Disband your faction.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:disband()
return true
end
},false)
factions.register_command("close", {
faction_permissions = {"playerslist"},
description = "Make your faction invite-only.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:toggle_join_free(false)
return true
end
},false)
factions.register_command("open", {
faction_permissions = {"playerslist"},
description = "Allow any player to join your faction.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:toggle_join_free(true)
return true
end
},false)
factions.register_command("description", {
faction_permissions = {"description"},
description = "Set your faction's description",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:set_description(table.concat(args.other," "))
return true
end
},false)
factions.register_command("invite", {
format = {"player"},
faction_permissions = {"playerslist"},
description = "Invite a player to your faction.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:invite_player(args.players[1]:get_player_name())
return true
end
},false)
factions.register_command("uninvite", {
format = {"player"},
faction_permissions = {"playerslist"},
description = "Revoke a player's invite.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:revoke_invite(args.players[1]:get_player_name())
return true
end
},false)
factions.register_command("delete", {
global_privileges = {"faction_admin"},
format = {"faction"},
infaction = false,
description = "Delete a faction.",
on_success = function(player, faction, pos, parcelpos, args)
args.factions[1]:disband()
return true
end
},false)
factions.register_command("ranks", {
description = "List ranks within your faction",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
for rank, permissions in pairs(faction.ranks) do
minetest.chat_send_player(player, rank..": "..table.concat(permissions, " "))
end
return true
end
},false)
factions.register_command("who", {
description = "List players in your faction, and their ranks.",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
if not faction.players then
minetest.chat_send_player(player, "There is nobody in this faction ("..faction.name..")")
return true
end
minetest.chat_send_player(player, "Players in faction "..faction.name..": ")
for p, rank in pairs(faction.players) do
minetest.chat_send_player(player, p.." ("..rank..")")
end
return true
end
},false)
factions.register_command("newrank", {
description = "Add a new rank.",
format = {"string"},
faction_permissions = {"ranks"},
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
if args.strings[1] then
local rank = args.strings[1]
if faction.ranks[rank] then
send_error(player, "Rank already exists")
return false
end
local success = false
local failindex = -1
for _, f in pairs(args.strings) do
if f then
for q, r in pairs(factions.permissions) do
if f == r then
success = true
break
end
end
if not success and _ ~= 1 then
failindex = _
break
end
end
end
if not success then
if args.strings[failindex] then
send_error(player, "Permission " .. args.strings[failindex] .. " is invalid.")
else
send_error(player, "No permission was given.")
end
return false
end
faction:add_rank(rank, args.other)
return true
end
send_error(player, "No rank was given.")
return false
end
},true)
factions.register_command("delrank", {
description = "Replace and delete a rank.",
format = {"string", "string"},
faction_permissions = {"ranks"},
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local rank = args.strings[1]
local newrank = args.strings[2]
if not faction.ranks[rank] or not faction.ranks[newrank] then
send_error(player, "One of the specified ranks do not exist.")
return false
end
faction:delete_rank(rank, newrank)
return true
end
},false)
factions.register_command("setspawn", {
description = "Set the faction's spawn",
faction_permissions = {"spawn"},
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
faction:set_spawn(pos)
return true
end
},false)
factions.register_command("where", {
description = "See whose parcel you stand on.",
infaction = false,
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local parcel_faction = factions.get_parcel_faction(parcelpos)
local place_name = (parcel_faction and parcel_faction.name) or "Wilderness"
minetest.chat_send_player(player, "You are standing on parcel "..parcelpos..", part of "..place_name)
return true
end
},false)
factions.register_command("help", {
description = "Shows help for commands.",
infaction = false,
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
factions_chat.show_help(player)
return true
end
},false)
factions.register_command("spawn", {
description = "Shows your faction's spawn",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local spawn = faction.spawn
if spawn then
local spawn = {spawn.x, spawn.y, spawn.z}
minetest.chat_send_player(player, "Spawn is at ("..table.concat(spawn, ", ")..")")
return true
else
minetest.chat_send_player(player, "Your faction has no spawn set.")
return false
end
end
},false)
factions.register_command("promote", {
description = "Promotes a player to a rank",
format = {"player", "string"},
faction_permissions = {"promote"},
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local rank = args.strings[1]
if faction.ranks[rank] then
faction:promote(args.players[1]:get_player_name(), rank)
return true
else
send_error(player, "The specified rank does not exist.")
return false
end
end
},false)
factions.register_command("power", {
description = "Display your faction's power",
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
minetest.chat_send_player(player, "Power: "..faction.power.."/"..faction.maxpower - faction.usedpower.."/"..faction.maxpower)
return true
end
},false)
--[[
factions.register_command("setbanner", {
description = "Sets the banner you're on as the faction's banner.",
faction_permissions = {"banner"},
on_success = function(player, faction, pos, parcelpos, args)
local meta = minetest.get_meta({x = pos.x, y = pos.y - 1, z = pos.z})
local banner = meta:get_string("banner")
if not banner then
minetest.chat_send_player(player, "No banner found.")
return false
end
faction:set_banner(banner)
end
},false)
--]]
--[[
factions.register_command("convert", {
description = "Load factions in the old format",
infaction = false,
global_privileges = {"faction_admin"},
format = {"string"},
on_success = function(player, faction, pos, parcelpos, args)
if factions.convert(args.strings[1]) then
minetest.chat_send_player(player, "Factions successfully converted.")
else
minetest.chat_send_player(player, "Error.")
end
return true
end
},false)
--]]
factions.register_command("free", {
description = "Forcefully frees a parcel",
infaction = false,
global_privileges = {"faction_admin"},
on_success = function(player, faction, pos, parcelpos, args)
local parcel_faction = factions.get_parcel_faction(parcelpos)
if not parcel_faction then
send_error(player, "No claim at this position")
return false
else
parcel_faction:unclaim_parcel(parcelpos)
return true
end
end
},false)
factions.register_command("chat", {
description = "Send a message to your faction's members",
format = {"string"},
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local msg = table.concat(args.strings, " ")
faction:broadcast(msg, player)
end
},true)
factions.register_command("forceupdate", {
description = "Forces an update tick.",
global_privileges = {"faction_admin"},
on_success = function(player, faction, pos, parcelpos, args)
factions.faction_tick()
end
},false)
factions.register_command("which", {
description = "Gets a player's faction",
infaction = false,
format = {"string"},
global_privileges = {"faction_user"},
on_success = function(player, faction, pos, parcelpos, args)
local playername = args.strings[1]
local faction = factions.get_player_faction(playername)
if not faction then
send_error(player, "Player "..playername.." does not belong to any faction")
return false
else
minetest.chat_send_player(player, "player "..playername.." belongs to faction "..faction.name)
return true
end
end
},false)
factions.register_command("setleader", {
description = "Set a player as a faction's leader",
infaction = false,
global_privileges = {"faction_admin"},
format = {"faction", "player"},
on_success = function(player, faction, pos, parcelpos, args)
local playername = args.players[1]:get_player_name()
local playerfaction = factions.get_player_faction(playername)
local targetfaction = args.factions[1]
if playerfaction.name ~= targetfaction.name then
send_error(player, "Player "..playername.." is not in faction "..targetfaction.name..".")
return false
end
targetfaction:set_leader(playername)
return true
end
},false)
factions.register_command("setadmin", {
description = "Make a faction an admin faction",
infaction = false,
global_privileges = {"faction_admin"},
format = {"faction"},
on_success = function(player, faction, pos, parcelpos, args)
args.factions[1].is_admin = false
return true
end
},false)
factions.register_command("resetpower", {
description = "Reset a faction's power",
infaction = false,
global_privileges = {"faction_admin"},
format = {"faction"},
on_success = function(player, faction, pos, parcelpos, args)
args.factions[1].power = 0
return true
end
},false)
factions.register_command("obliterate", {
description = "Remove all factions",
infaction = false,
global_privileges = {"faction_admin"},
on_success = function(player, faction, pos, parcelpos, args)
for _, f in pairs(factions.factions) do
f:disband("obliterated")
end
return true
end
},false)
factions.register_command("getspawn", {
description = "Get a faction's spawn",
infaction = false,
global_privileges = {"faction_admin"},
format = {"faction"},
on_success = function(player, faction, pos, parcelpos, args)
local spawn = args.factions[1].spawn
if spawn then
minetest.chat_send_player(player, spawn.x..","..spawn.y..","..spawn.z)
return true
else
send_error(player, "Faction has no spawn set.")
return false
end
end
},false)
factions.register_command("whoin", {
description = "Get all members of a faction.",
infaction = false,
global_privileges = {"faction_admin"},
format = {"faction"},
on_success = function(player, faction, pos, parcelpos, args)
local msg = {}
for player, _ in pairs(args.factions[1].players) do
table.insert(msg, player)
end
minetest.chat_send_player(player, table.concat(msg, ", "))
return true
end
},false)
factions.register_command("stats", {
description = "Get stats of a faction.",
infaction = false,
global_privileges = {"faction_admin"},
format = {"faction"},
on_success = function(player, faction, pos, parcelpos, args)
local f = args.factions[1]
minetest.chat_send_player(player, "Power: "..f.power.."/"..f.maxpower - f.usedpower.."/"..f.maxpower)
return true
end
},false)
factions.register_command("seen", {
description = "Check the last time a faction had a member logged in",
infaction = false,
global_privileges = {"faction_admin"},
format = {"faction"},
on_success = function(player, faction, pos, parcelpos, args)
local lastseen = args.factions[1].last_logon
local now = os.time()
local time = now - lastseen
local minutes = math.floor(time / 60)
local hours = math.floor(minutes / 60)
local days = math.floor(hours / 24)
minetest.chat_send_player(player, "Last seen "..days.." day(s), "..
hours % 24 .." hour(s), "..minutes % 60 .." minutes, "..time % 60 .." second(s) ago.")
return true
end
},false)
-------------------------------------------------------------------------------
-- name: cmdhandler(playername,parameter)
--
--! @brief chat command handler
--! @memberof factions_chat
--! @private
--
--! @param playername name
--! @param parameter data supplied to command
-------------------------------------------------------------------------------
factions_chat.cmdhandler = function (playername,parameter)
local player = minetest.env:get_player_by_name(playername)
local params = parameter:split(" ")
local player_faction = factions.get_player_faction(playername)
if parameter == nil or
parameter == "" then
if player_faction then
minetest.chat_send_player(playername, "You are in faction "..player_faction.name..". Type /f help for a list of commands.")
else
minetest.chat_send_player(playername, "You are part of no faction")
end
return
end
local cmd = factions.commands[params[1]]
if not cmd then
send_error(playername, "Unknown command.")
return false
end
local argv = {}
for i=2, #params, 1 do
table.insert(argv, params[i])
end
cmd:run(playername, argv)
end
function table_Contains(t,v)
for k, a in pairs(t) do
if a == v then
return true
end
end
return false
end
-------------------------------------------------------------------------------
-- name: show_help(playername,parameter)
--
--! @brief send help message to player
--! @memberof factions_chat
--! @private
--
--! @param playername name
-------------------------------------------------------------------------------
function factions_chat.show_help(playername)
local MSG = function(text)
minetest.chat_send_player(playername,text,false)
end
MSG("factions mod")
MSG("Usage:")
local has, missing = minetest.check_player_privs(playername, {
faction_admin = true})
for k, v in pairs(factions.commands) do
local args = {}
if has or not table_Contains(v.global_privileges,"faction_admin") then
for i in ipairs(v.format) do
table.insert(args, v.format[i])
end
MSG("\t/factions "..k.." <"..table.concat(args, "> <").."> : "..v.description)
end
end
end
init_commands()

28
mods/factions/config.lua Normal file
View File

@ -0,0 +1,28 @@
-------------------------------------------------------------------------------
-- factions Mod by Sapier
--
-- License WTFPL
--
--! @file config.lua
--! @brief settings file
--! @copyright Coder12a
--! @author Coder12a
--! @date 2018-03-13
--
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
config = {}
config.protection_max_depth = tonumber(minetest.setting_get("protection_max_depth")) or -512
config.power_per_parcel = tonumber(minetest.setting_get("power_per_parcel")) or 0.5
config.power_per_death = tonumber(minetest.setting_get("power_per_death")) or 0.25
config.power_per_tick = tonumber(minetest.setting_get("power_per_tick")) or 0.125
config.tick_time = tonumber(minetest.setting_get("tick_time")) or 60
config.power_per_attack = tonumber(minetest.setting_get("power_per_attack")) or 10
config.faction_name_max_length = tonumber(minetest.setting_get("faction_name_max_length")) or 50
config.rank_name_max_length = tonumber(minetest.setting_get("rank_name_max_length")) or 25
config.maximum_faction_inactivity = tonumber(minetest.setting_get("maximum_faction_inactivity")) or 604800
config.power = tonumber(minetest.setting_get("power")) or 2
config.maxpower = tonumber(minetest.setting_get("maxpower")) or 2
config.power_per_banner = minetest.settings:get_bool("power_per_banner") or 10.
config.attack_parcel = minetest.settings:get_bool("attack_parcel") or false

View File

@ -0,0 +1,2 @@
default?
bones?

View File

@ -0,0 +1 @@
Mod for handling in game factions and reputation.

1020
mods/factions/factions.lua Normal file

File diff suppressed because it is too large Load Diff

30
mods/factions/init.lua Normal file
View File

@ -0,0 +1,30 @@
-------------------------------------------------------------------------------
-- factions Mod by Sapier
--
-- License WTFPL
--
--! @file init.lua
--! @brief factions mod to be used by other mods
--! @copyright Sapier, Coder12a
--! @author Sapier, Coder12a
--! @date 2013-05-08
--!
-- Contact sapier a t gmx net
-------------------------------------------------------------------------------
factions_version = "0.8.1"
core.log("action", "MOD: factions (by sapier) loading ...")
--!path of mod
factions_modpath = minetest.get_modpath("factions")
dofile (factions_modpath .. "/config.lua")
dofile (factions_modpath .. "/banner.lua")
dofile (factions_modpath .. "/factions.lua")
dofile (factions_modpath .. "/chatcommands.lua")
dofile (factions_modpath .. "/nodes.lua")
factions.load()
core.log("action","MOD: factions (by sapier) " .. factions_version .. " loaded.")

1
mods/factions/mod.conf Normal file
View File

@ -0,0 +1 @@
name = factions

71
mods/factions/nodes.lua Normal file
View File

@ -0,0 +1,71 @@
function factions.get_chest_formspec(pos)
local spos = pos.x..","..pos.y..","..pos.z
return "size[8,9]" ..
default.gui_bg ..
default.gui_bg_img ..
default.gui_slots ..
"list[nodemeta:"..spos..";main;0,0.3;8,4;]" ..
"list[current_player;main;0,4.85;8,1;]"..
"list[current_player;main;0,6.08;8,3;8]"..
"listring[nodemeta:"..spos..";main]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.85)
end
function factions.can_use_chest(pos, player)
if not player then
return false
end
local parcel_faction = factions.get_faction_at(pos)
local player_faction = factions.get_player_faction(player)
if not parcel_faction then
return true
end
return player_faction and (parcel_faction.name == player_faction.name)
end
minetest.register_node("factions:chest", {
tiles = {"factions_chest_top.png", "factions_chest_top.png",
"factions_chest_side.png", "factions_chest_side.png",
"factions_chest_side.png", "factions_chest_front.png"},
groups = {choppy = 2},
description = "Faction chest",
paramtype2 = "facedir",
on_construct = function(pos)
minetest.get_meta(pos):get_inventory():set_size("main", 8*4)
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
if factions.can_use_chest(pos, player:get_player_name()) then
return count
else
return 0
end
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
if factions.can_use_chest(pos, player:get_player_name()) then
return stack:get_count()
else
return 0
end
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
if factions.can_use_chest(pos, player:get_player_name()) then
return stack:get_count()
else
return 0
end
end,
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
if factions.can_use_chest(pos, clicker:get_player_name()) then
minetest.show_formspec(clicker:get_player_name(), "factions:chest", factions.get_chest_formspec(pos))
end
return itemstack
end
})
minetest.register_craft({
output = "factions:chest",
type = "shapeless",
recipe = {"default:chest_locked", "default:steel_ingot"}
})

View File

@ -0,0 +1,31 @@
[ValueSettings]
# The max depth of protection from a parcel.
protection_max_depth (Protection max depth) float -50
# Cost of power to claim a parcel of land.
power_per_parcel (Power-per-parcel) float 0.5
# Power lost on death.
power_per_death (Power-per-death) float 0.25
# Power regeneration rate.
power_per_tick (Power-per-tick) float 0.125
# Faction timer. This timer regenerates power if the faction members are online.
tick_time (Faction timer) float 60
# Not in use.
power_per_attack (Power-per-attack) float 10
# Limit how long a faction name can be.
faction_name_max_length (Faction name max) int 50
# Limit how long a rank name can be.
rank_name_max_length (Rank name max length) int 25
# The maximum amount of inactivity before disbanning a faction.
maximum_faction_inactivity (Maximum faction inactivity) int 604800
# Power of a starting faction (needed for parcel claiming).
power (Starting power) float 2
# Maximum power of a faction.
maxpower (Maximum power) float 2
# How much power the banners make.
power_per_banner (power-per-banner) float 10
[BoolSettings]
# Enable or disabled attack_parcel function.
attack_parcel (Enable attack parcel) bool false

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 646 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B