add modstorage storage engine, remove object functions

This commit is contained in:
Evert Prants 2019-01-13 03:54:59 +02:00
parent b610781d0f
commit d50da0c47c
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
9 changed files with 272 additions and 185 deletions

View File

@ -1,3 +1,6 @@
-- Commands and chat modification
-- TODO: Town names in chat
-- Privileges -- Privileges
@ -13,7 +16,7 @@ minetest.register_privilege("towny_admin", {
-- API -- API
-- Send message to all town members who are online -- Send message to all town members who are online
function towny.chat:announce_to_members(town,message) function towny.chat.announce_to_members(town,message)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if tdata then if tdata then
for member in pairs(tdata.members) do for member in pairs(tdata.members) do
@ -27,7 +30,7 @@ end
-- Commands -- Commands
local function invite_player(town,player,target) local function invite_player(town,player,target)
local utown = towny:get_player_town(player) local utown = towny.get_player_town(player)
if not utown or utown ~= town then if not utown or utown ~= town then
return false, "You are not in a town." return false, "You are not in a town."
end end
@ -36,7 +39,7 @@ local function invite_player(town,player,target)
return false, "You can only invite online players to your town." return false, "You can only invite online players to your town."
end end
local target_town = towny:get_player_town(target) local target_town = towny.get_player_town(target)
if target_town then if target_town then
return false, "This player is already in a town!" return false, "This player is already in a town!"
end end
@ -59,15 +62,15 @@ local function join_town(town,player,from_invite)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if not tdata then return false, "No such town" end if not tdata then return false, "No such town" end
if (not from_invite and not tdata.flags['joinable']) then return false, "You cannot join this town." end if (not from_invite and not tdata.flags['joinable']) then return false, "You cannot join this town." end
towny.chat:announce_to_members(town, minetest.colorize("#02aacc", player.." has joined the town!")) towny.chat.announce_to_members(town, minetest.colorize("#02aacc", player.." has joined the town!"))
minetest.chat_send_player(player, ("You have successfully joined the town '%s'!"):format(tdata.name)) minetest.chat_send_player(player, ("You have successfully joined the town '%s'!"):format(tdata.name))
tdata.members[player] = {} tdata.members[player] = {}
towny:mark_dirty(town,false) towny.mark_dirty(town,false)
return true return true
end end
local function invite_respond(player,response) local function invite_respond(player,response)
local utown = towny:get_player_town(player) local utown = towny.get_player_town(player)
if utown or utown ~= town then if utown or utown ~= town then
return false, "You are already in a town." return false, "You are already in a town."
end end
@ -112,19 +115,19 @@ end
local function town_command (name, param) local function town_command (name, param)
if not minetest.get_player_by_name(name) then return false, "Can't run command on behalf of offline player." end if not minetest.get_player_by_name(name) then return false, "Can't run command on behalf of offline player." end
local pr1, pr2 = string.match(param, "^([%a%d_-]+) (.+)$") local pr1, pr2 = string.match(param, "^([%a%d_-]+) (.+)$")
local town = towny:get_player_town(name) local town = towny.get_player_town(name)
-- Pre town requirement -- Pre town requirement
local town_info = nil local town_info = nil
if (pr1 == "create" or pr1 == "new") and pr2 then if (pr1 == "create" or pr1 == "new") and pr2 then
return towny:create_town(nil, name, pr2) return towny.create_town(nil, name, pr2)
elseif (pr1 == "invite" and not minetest.get_player_by_name(pr2)) then elseif (pr1 == "invite" and not minetest.get_player_by_name(pr2)) then
return invite_respond(name, (tyes:lower() == "accept" or minetest.is_yes(tyes))) return invite_respond(name, (tyes:lower() == "accept" or minetest.is_yes(tyes)))
elseif pr1 == "join" and towny:get_town_by_name(pr2) and not town then elseif pr1 == "join" and towny.get_town_by_name(pr2) and not town then
return join_town(pr2,name,false) return join_town(pr2,name,false)
elseif pr1 == "show" or pr1 == "info" then elseif pr1 == "show" or pr1 == "info" then
if towny:get_town_by_name(pr2) then if towny.get_town_by_name(pr2) then
town_info = pr2 town_info = pr2
else else
return false, "No such town." return false, "No such town."
@ -146,23 +149,23 @@ local function town_command (name, param)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if param == "extend" or param == "claim" then if param == "extend" or param == "claim" then
return towny:extend_town(nil, name) return towny.extend_town(nil, name)
elseif param == "leave" then elseif param == "leave" then
return towny:leave_town(name) return towny.leave_town(name)
elseif param == "unclaim" then elseif param == "unclaim" then
return towny:abridge_town(nil, name) return towny.abridge_town(nil, name)
elseif param == "visualize" then elseif param == "visualize" then
towny.regions:visualize_town(town) towny.regions.visualize_town(town)
return true return true
elseif param == "flags" then elseif param == "flags" then
local flags = towny:get_flags(town) local flags = towny.get_flags(town)
if flags then if flags then
return send_flags(player,flags,"Flags of your town") return send_flags(player,flags,"Flags of your town")
end end
elseif (param == "delete" or param == "abandon") or (pr1 == "delete" or pr1 == "abandon") then elseif (param == "delete" or param == "abandon") or (pr1 == "delete" or pr1 == "abandon") then
if towny.chat['delete_verify_' .. name] and pr2 == "I WANT TO DELETE MY TOWN" then if towny.chat['delete_verify_' .. name] and pr2 == "I WANT TO DELETE MY TOWN" then
towny.chat['delete_verify_' .. name] = nil towny.chat['delete_verify_' .. name] = nil
return towny:delete_town(nil, name) return towny.delete_town(nil, name)
else else
towny.chat['delete_verify_' .. name] = true towny.chat['delete_verify_' .. name] = true
minetest.chat_send_player(name, minetest.colorize("#f79204", minetest.chat_send_player(name, minetest.colorize("#f79204",
@ -174,20 +177,20 @@ local function town_command (name, param)
if not tdata.flags["greeting"] then return false, "This town has no greeting message." end if not tdata.flags["greeting"] then return false, "This town has no greeting message." end
return true, return true,
minetest.colorize("#078e36", ("[%s] "):format(towny:get_full_name(town))) .. minetest.colorize("#078e36", ("[%s] "):format(towny.get_full_name(town))) ..
minetest.colorize("#02aacc", tdata.flags["greeting"]) minetest.colorize("#02aacc", tdata.flags["greeting"])
elseif pr1 == "kick" then elseif pr1 == "kick" then
return towny:kick_member(town,name,pr2) return towny.kick_member(town,name,pr2)
elseif pr1 == "set" then elseif pr1 == "set" then
local flag, value = string.match(pr2, "^([%a%d_-]+) (.+)$") local flag, value = string.match(pr2, "^([%a%d_-]+) (.+)$")
return towny:set_town_flags(nil,name,flag,value) return towny.set_town_flags(nil,name,flag,value)
elseif pr1 == "member" then elseif pr1 == "member" then
local action, user = string.match(pr2, "^([%a%d_-]+) (.+)$") local action, user = string.match(pr2, "^([%a%d_-]+) (.+)$")
if action == "kick" then if action == "kick" then
return towny:kick_member(town,name,pr2) return towny.kick_member(town,name,pr2)
elseif action == "set" then elseif action == "set" then
local target, flag, value = string.match(user, "^([%a%d_-]+) ([%a%d_-]+) (.+)$") local target, flag, value = string.match(user, "^([%a%d_-]+) ([%a%d_-]+) (.+)$")
return towny:set_town_member_flags(nil,name,target,flag,value) return towny.set_town_member_flags(nil,name,target,flag,value)
end end
end end
@ -195,13 +198,13 @@ local function town_command (name, param)
if pr1 == "plot" then if pr1 == "plot" then
local pl1, pl2 = string.match(pr2, "^([%a%d_-]+) (.+)$") local pl1, pl2 = string.match(pr2, "^([%a%d_-]+) (.+)$")
if pr2 == "claim" then if pr2 == "claim" then
return towny:claim_plot(nil,name) return towny.claim_plot(nil,name)
elseif pr2 == "abandon" then elseif pr2 == "abandon" then
return towny:abandon_plot(nil,name) return towny.abandon_plot(nil,name)
elseif pr2 == "delete" then elseif pr2 == "delete" then
return towny:delete_plot(nil,name) return towny.delete_plot(nil,name)
elseif pr2 == "flags" then elseif pr2 == "flags" then
local flags = towny:get_plot_flags(town,nil,name) local flags = towny.get_plot_flags(town,nil,name)
if flags then if flags then
return send_flags(player,flags,"Flags of this plot") return send_flags(player,flags,"Flags of this plot")
else else
@ -209,16 +212,16 @@ local function town_command (name, param)
end end
elseif pl1 == "set" and pl2 then elseif pl1 == "set" and pl2 then
local flag, value = string.match(pl2, "^([%a%d_-]+) (.+)$") local flag, value = string.match(pl2, "^([%a%d_-]+) (.+)$")
return towny:set_plot_flags(nil,name,flag,value) return towny.set_plot_flags(nil,name,flag,value)
elseif pl1 == "member" and pl2 then elseif pl1 == "member" and pl2 then
local action, user = string.match(pl2, "^([%a%d_-]+) (.+)$") local action, user = string.match(pl2, "^([%a%d_-]+) (.+)$")
if action == "add" then if action == "add" then
return towny:plot_member(nil,name,user,1) return towny.plot_member(nil,name,user,1)
elseif action == "remove" or action == "del" or action == "kick" then elseif action == "remove" or action == "del" or action == "kick" then
return towny:plot_member(nil,name,user,0) return towny.plot_member(nil,name,user,0)
elseif action == "set" then elseif action == "set" then
local target, flag, value = string.match(user, "^([%a%d_-]+) ([%a%d_-]+) (.+)$") local target, flag, value = string.match(user, "^([%a%d_-]+) ([%a%d_-]+) (.+)$")
return towny:set_plot_member_flags(nil,name,target,flag,value) return towny.set_plot_member_flags(nil,name,target,flag,value)
end end
end end
elseif pr1 == "invite" and minetest.get_player_by_name(pr2) then elseif pr1 == "invite" and minetest.get_player_by_name(pr2) then

View File

@ -1,9 +1,14 @@
-- A township system for Minetest servers. -- A township system for Minetest servers.
-- The MIT License - 2019 Evert "Diamond" Prants <evert@lunasqu.ee> -- The MIT License - 2019 Evert "Diamond" Prants <evert@lunasqu.ee>
-- TODO: Protection on HUD
-- TODO: Nations
-- TODO: Economy
local modpath = minetest.get_modpath(minetest.get_current_modname()) local modpath = minetest.get_modpath(minetest.get_current_modname())
towny = { towny = {
regions = { modpath = modpath,
regions = {
size = tonumber(minetest.settings:get('towny_claim_size')) or 16, size = tonumber(minetest.settings:get('towny_claim_size')) or 16,
height = tonumber(minetest.settings:get('towny_claim_height')) or 64, height = tonumber(minetest.settings:get('towny_claim_height')) or 64,
maxclaims = tonumber(minetest.settings:get('towny_claim_max')) or 128, maxclaims = tonumber(minetest.settings:get('towny_claim_max')) or 128,
@ -13,7 +18,7 @@ towny = {
memloaded = {}, memloaded = {},
}, },
-- See "Town data structure" -- See "Town data structure"
flatfile = {}, storage = {},
towns = {}, towns = {},
chat = { chat = {
chatmod = (minetest.settings:get('towny_chat') == "true") or true, chatmod = (minetest.settings:get('towny_chat') == "true") or true,
@ -137,7 +142,7 @@ towny = {
} }
]] ]]
dofile(modpath.."/flatfile.lua") dofile(modpath.."/storage/init.lua")
dofile(modpath.."/visualize.lua") dofile(modpath.."/visualize.lua")
dofile(modpath.."/regions.lua") dofile(modpath.."/regions.lua")
dofile(modpath.."/town.lua") dofile(modpath.."/town.lua")

View File

@ -15,7 +15,7 @@ local function region_equal(v1, v2)
end end
-- Test to see if there's already a protected node in a region -- Test to see if there's already a protected node in a region
function towny.regions:already_protected(p1, p2, name) function towny.regions.already_protected(p1, p2, name)
local found = false local found = false
for x = p1.x, p2.x do for x = p1.x, p2.x do
if found then break end if found then break end
@ -32,7 +32,7 @@ function towny.regions:already_protected(p1, p2, name)
return found return found
end end
function towny.regions:build_perms(town, name, plotid) function towny.regions.build_perms(town, name, plotid)
if not towny.towns[town] then return true end -- Can build here, this town doesnt even exist if not towny.towns[town] then return true end -- Can build here, this town doesnt even exist
local towndata = towny.towns[town] local towndata = towny.towns[town]
@ -58,9 +58,9 @@ function towny.regions:build_perms(town, name, plotid)
if name == plot.owner then return true end if name == plot.owner then return true end
if plot.members[name] then if plot.members[name] then
if towndata.flags['plot_member_build'] == false then if towndata.flags['plot_member_build'] == false then
return plot.members[name]['plot_build'] == true return plot.members[name]['plot_build']
else else
return true return plot.members[name]['plot_build'] ~= false
end end
end end
else else
@ -86,7 +86,7 @@ local function single_range(p)
return p1,p2 return p1,p2
end end
function towny.regions:get_town_at(pos) function towny.regions.get_town_at(pos)
local in_town, in_plot, in_claim local in_town, in_plot, in_claim
for town,regions in pairs(towny.regions.memloaded) do for town,regions in pairs(towny.regions.memloaded) do
if in_town ~= nil then break end if in_town ~= nil then break end
@ -107,14 +107,14 @@ function towny.regions:get_town_at(pos)
return in_town,in_plot,in_claim return in_town,in_plot,in_claim
end end
function towny.regions:get_closest_town(pos,name) function towny.regions.get_closest_town(pos,name)
local in_town,block local in_town,block
local last_distance = 0 local last_distance = 0
for town,regions in pairs(towny.regions.memloaded) do for town,regions in pairs(towny.regions.memloaded) do
local count = true local count = true
if name then if name then
count = towny.regions:build_perms(town, name, nil) count = towny.regions.build_perms(town, name, nil)
end end
if count and vector.distance(pos, regions.origin) <= towny.regions.size * towny.regions.maxclaims then if count and vector.distance(pos, regions.origin) <= towny.regions.size * towny.regions.maxclaims then
@ -133,7 +133,7 @@ function towny.regions:get_closest_town(pos,name)
return in_town,block,last_distance return in_town,block,last_distance
end end
function towny.regions:town_claim_exists(town,p1) function towny.regions.town_claim_exists(town,p1)
if not towny.regions.memloaded[town] then return false end if not towny.regions.memloaded[town] then return false end
local blocks = towny.regions.memloaded[town].blocks local blocks = towny.regions.memloaded[town].blocks
for _,pos in pairs(blocks) do for _,pos in pairs(blocks) do
@ -142,8 +142,8 @@ function towny.regions:town_claim_exists(town,p1)
return false return false
end end
function towny.regions:align_new_claim_block(pos,name) function towny.regions.align_new_claim_block(pos,name)
local closest_town,closest_block,distance = towny.regions:get_closest_town(pos,name) local closest_town,closest_block,distance = towny.regions.get_closest_town(pos,name)
if not closest_town then return nil end if not closest_town then return nil end
if distance > (tr + th) then return nil end -- Too far if distance > (tr + th) then return nil end -- Too far
@ -177,7 +177,7 @@ function towny.regions:align_new_claim_block(pos,name)
return new_pos,closest_town return new_pos,closest_town
end end
function towny.regions:remove_claim(p1,town) function towny.regions.remove_claim(p1,town)
local blocks = {} local blocks = {}
if not towny.regions.memloaded[town] then return false, "This town does not exist anymore." end if not towny.regions.memloaded[town] then return false, "This town does not exist anymore." end
for _,pos in pairs(towny.regions.memloaded[town].blocks) do for _,pos in pairs(towny.regions.memloaded[town].blocks) do
@ -194,7 +194,7 @@ function towny.regions:remove_claim(p1,town)
return true return true
end end
function towny.regions:set_plot(pos,town,plot) function towny.regions.set_plot(pos,town,plot)
if not towny.regions.memloaded[town] then return false, "This town does not exist anymore." end if not towny.regions.memloaded[town] then return false, "This town does not exist anymore." end
for _,block in pairs(towny.regions.memloaded[town].blocks) do for _,block in pairs(towny.regions.memloaded[town].blocks) do
if region_equal(block, pos) then if region_equal(block, pos) then
@ -205,24 +205,24 @@ function towny.regions:set_plot(pos,town,plot)
return true return true
end end
function towny.regions:visualize_town(town) function towny.regions.visualize_town(town)
if not towny.regions.memloaded[town] then return end if not towny.regions.memloaded[town] then return end
for _,pos in pairs(towny.regions.memloaded[town].blocks) do for _,pos in pairs(towny.regions.memloaded[town].blocks) do
towny.regions:visualize_radius(vector.subtract(pos, local p1,p2 = single_range(pos)
{x=tr/2,y=th/2,z=tr/2})) towny.regions.visualize_area(p1,p2)
end end
end end
function towny.regions:position_protected_from(pos, name) function towny.regions.position_protected_from(pos, name)
local town,plot = towny.regions:get_town_at(pos) local town,plot = towny.regions.get_town_at(pos)
if not town then return false end if not town then return false end
return not towny.regions:build_perms(town, name, plot) return not towny.regions.build_perms(town, name, plot)
end end
-- Finally, override is_protected -- Finally, override is_protected
function minetest.is_protected(pos, name) function minetest.is_protected(pos, name)
local bt = towny.regions:position_protected_from(pos, name) local bt = towny.regions.position_protected_from(pos, name)
if bt ~= false then if bt ~= false then
return true return true
end end
@ -232,7 +232,7 @@ end
--[[if minetest.settings:get('towny_prevent_protector') == 'true' then --[[if minetest.settings:get('towny_prevent_protector') == 'true' then
minetest.register_on_placenode(function (pos, newnode, placer, oldnode, itemstack, pointed_thing) minetest.register_on_placenode(function (pos, newnode, placer, oldnode, itemstack, pointed_thing)
local town = towny.regions:get_town_at(pos) local town = towny.regions.get_town_at(pos)
if not town return end if not town return end
end) end)
end]] end]]

View File

@ -1,4 +1,11 @@
# General
##########
# Town metadata and region storage engine
# Recommended to keep as modstorage.
towny_storage_engine (Storage engine) enum modstorage modstorage,flatfile
# Claims settings # Claims settings
################## ##################

View File

@ -1,8 +1,10 @@
-- Flatfile storage engine
-- Not recommended
local extension = "lua" local extension = "lua"
local serialize = true local serialize = true
function towny.flatfile:write_meta(town,dir,data) local function write_meta(town,dir,data)
local world = minetest.get_worldpath() local world = minetest.get_worldpath()
local directory = world.."/towny/"..dir local directory = world.."/towny/"..dir
local filepath = town.."."..extension local filepath = town.."."..extension
@ -23,7 +25,7 @@ function towny.flatfile:write_meta(town,dir,data)
minetest.safe_file_write(directory.."/"..filepath, serialized) minetest.safe_file_write(directory.."/"..filepath, serialized)
end end
function towny.flatfile:load_meta(filepath) local function load_meta(filepath)
local file = io.open(filepath) local file = io.open(filepath)
if not file then if not file then
@ -47,12 +49,12 @@ function towny.flatfile:load_meta(filepath)
return data return data
end end
function towny.flatfile:save_town_meta(town) function towny.storage.save_town_meta(town)
local tmeta = towny.towns[town] local tmeta = towny.towns[town]
if tmeta and tmeta.dirty then if tmeta and tmeta.dirty then
towny:get_town_level(town, true) towny.get_town_level(town, true)
minetest.after(0.1, function () minetest.after(0.1, function ()
towny.flatfile:write_meta(town,"meta",tmeta) write_meta(town,"meta",tmeta)
tmeta.dirty = false tmeta.dirty = false
end) end)
end end
@ -60,14 +62,14 @@ function towny.flatfile:save_town_meta(town)
local rmeta = towny.regions.memloaded[town] local rmeta = towny.regions.memloaded[town]
if rmeta and rmeta.dirty then if rmeta and rmeta.dirty then
minetest.after(0.2, function () minetest.after(0.2, function ()
towny.flatfile:write_meta(town,"region",rmeta) write_meta(town,"region",rmeta)
rmeta.dirty = false rmeta.dirty = false
end) end)
end end
end end
local ldirs = { "meta", "region" } local ldirs = { "meta", "region" }
function towny.flatfile:load_all_towns() function towny.storage.load_all_towns()
local world = minetest.get_worldpath() local world = minetest.get_worldpath()
local metadir = world.."/towny/"..ldirs[1] local metadir = world.."/towny/"..ldirs[1]
minetest.mkdir(metadir) minetest.mkdir(metadir)
@ -77,10 +79,10 @@ function towny.flatfile:load_all_towns()
if file:match("."..extension.."$") then if file:match("."..extension.."$") then
local town = file:gsub("."..extension,"") local town = file:gsub("."..extension,"")
minetest.after(0.1, function () minetest.after(0.1, function ()
local towndata = towny.flatfile:load_meta(metadir.."/"..file) local towndata = load_meta(metadir.."/"..file)
if not towndata then return end if not towndata then return end
towny.towns[town] = towndata towny.towns[town] = towndata
towny:get_town_level(town, true) towny.get_town_level(town, true)
end) end)
end end
end end
@ -93,7 +95,7 @@ function towny.flatfile:load_all_towns()
if file:match("."..extension.."$") then if file:match("."..extension.."$") then
local town = file:gsub("."..extension,"") local town = file:gsub("."..extension,"")
minetest.after(0.1, function () minetest.after(0.1, function ()
local regiondata = towny.flatfile:load_meta(regiondir.."/"..file) local regiondata = load_meta(regiondir.."/"..file)
if not regiondata then return end if not regiondata then return end
towny.regions.memloaded[town] = regiondata towny.regions.memloaded[town] = regiondata
end) end)
@ -101,7 +103,7 @@ function towny.flatfile:load_all_towns()
end end
end end
function towny.flatfile:delete_all_meta(town) function towny.storage.delete_all_meta(town)
local world = minetest.get_worldpath() local world = minetest.get_worldpath()
local file = town.."."..extension local file = town.."."..extension
@ -111,32 +113,3 @@ function towny.flatfile:delete_all_meta(town)
minetest.after(0.1, os.remove, path) minetest.after(0.1, os.remove, path)
end end
end end
local clock = 0
local saving = false
local function carrier_tick()
if not towny.dirty or saving then return end
saving = true
for town,data in pairs(towny.towns) do
if data.dirty then
towny.flatfile:save_town_meta(town)
end
end
towny.dirty = false
saving = false
end
-- Register
minetest.register_globalstep(function (dt)
clock = clock + (dt + 1)
if clock >= 60 then
carrier_tick()
clock = 0
end
end)
minetest.after(0.1, function ()
towny.flatfile:load_all_towns()
end)

40
storage/init.lua Normal file
View File

@ -0,0 +1,40 @@
local setting = minetest.settings:get("towny_storage_engine") or "modstorage"
if setting == "modstorage" or setting == "flatfile" then
if setting == "flatfile" then
minetest.log("warning", "Using flatfile for towny storage is discouraged!")
end
dofile(towny.modpath.."/storage/"..setting..".lua")
else
error("Invalid storage engine for towny configured.")
end
local clock = 0
local saving = false
local function carrier_tick()
if not towny.dirty or saving then return end
saving = true
for town,data in pairs(towny.towns) do
if data.dirty then
towny.storage.save_town_meta(town)
end
end
towny.dirty = false
saving = false
end
-- Register
minetest.register_globalstep(function (dt)
clock = clock + (dt + 1)
if clock >= 60 then
carrier_tick()
clock = 0
end
end)
minetest.after(0.1, function ()
towny.storage.load_all_towns()
end)

60
storage/modstorage.lua Normal file
View File

@ -0,0 +1,60 @@
-- Store all data in ModStorage metadata
-- Recommended
local storage = minetest.get_mod_storage()
local function write_meta(town,scope,data)
data.dirty = nil
data.level = nil
local serialized = minetest.serialize(data)
storage:set_string(town.."/"..scope, serialized)
end
function towny.storage.save_town_meta(town)
local tmeta = towny.towns[town]
if tmeta and tmeta.dirty then
towny.get_town_level(town, true)
write_meta(town,"meta",tmeta)
tmeta.dirty = false
end
local rmeta = towny.regions.memloaded[town]
if rmeta and rmeta.dirty then
write_meta(town,"region",rmeta)
rmeta.dirty = false
end
end
-- Ideally only ever called once
function towny.storage.load_all_towns()
local keys = {}
local store = storage:to_table()
if store and store.fields then
store = store.fields
end
for key, data in pairs(store) do
local town, scope = key:match("^([%a%d_-]+)/([%a%d_-]+)")
if town and scope then
local tbl = minetest.deserialize(data)
if scope == "meta" then
towny.towns[town] = tbl
towny.get_town_level(town, true)
elseif scope == "region" then
towny.regions.memloaded[town] = tbl
end
end
end
end
function towny.storage.delete_all_meta(town)
if storage:get_string(town.."/meta") ~= "" then
storage:set_string(town.."/meta", "")
end
if storage:get_string(town.."/region") ~= "" then
storage:set_string(town.."/region", "")
end
end

178
town.lua
View File

@ -51,7 +51,7 @@ local function flag_validity(flag,scope,value,pos)
return true, flag, value return true, flag, value
end end
function towny:get_player_town(name) function towny.get_player_town(name)
for town,data in pairs(towny.towns) do for town,data in pairs(towny.towns) do
if data.mayor == name then if data.mayor == name then
return town return town
@ -62,7 +62,7 @@ function towny:get_player_town(name)
return nil return nil
end end
function towny:get_town_by_name(name) function towny.get_town_by_name(name)
if not name then return nil end if not name then return nil end
for town,data in pairs(towny.towns) do for town,data in pairs(towny.towns) do
if data.name:lower() == name:lower() then if data.name:lower() == name:lower() then
@ -72,7 +72,7 @@ function towny:get_town_by_name(name)
return nil return nil
end end
function towny:mark_dirty(town, areas) function towny.mark_dirty(town, areas)
towny.dirty = true towny.dirty = true
towny.towns[town].dirty = true towny.towns[town].dirty = true
if areas and towny.regions.memloaded[town] then if areas and towny.regions.memloaded[town] then
@ -80,22 +80,22 @@ function towny:mark_dirty(town, areas)
end end
end end
function towny:create_town(pos, player, name) function towny.create_town(pos, player, name)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
if towny:get_player_town(player) then if towny.get_player_town(player) then
return err_msg(player, "You're already in a town! Please leave your current town before founding a new one!") return err_msg(player, "You're already in a town! Please leave your current town before founding a new one!")
end end
local _,__,distance = towny.regions:get_closest_town(pos) local _,__,distance = towny.regions.get_closest_town(pos)
if distance > towny.regions.distance * towny.regions.size and not towny_admin then if distance > towny.regions.distance * towny.regions.size and not towny_admin then
return err_msg(player, "This location is too close to another town!") return err_msg(player, "This location is too close to another town!")
end end
if towny:get_town_by_name(name) and not towny_admin then if towny.get_town_by_name(name) and not towny_admin then
return err_msg(player, "A town by this name already exists!") return err_msg(player, "A town by this name already exists!")
end end
@ -128,24 +128,22 @@ function towny:create_town(pos, player, name)
towny.towns[id] = data towny.towns[id] = data
towny.regions.memloaded[id] = regions towny.regions.memloaded[id] = regions
towny:mark_dirty(id, true) towny.mark_dirty(id, true)
minetest.chat_send_player(player, "Your town has successfully been founded!") minetest.chat_send_player(player, "Your town has successfully been founded!")
minetest.chat_send_all(("%s has started a new town called '%s'!"):format(player,name)) minetest.chat_send_all(("%s has started a new town called '%s'!"):format(player,name))
minetest.set_node(p1,{name="default:wood"}) towny.regions.visualize_area(p1,p2)
towny.regions:visualize_area(p1,p2)
return true return true
end end
function towny:extend_town(pos,player) function towny.extend_town(pos,player)
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town then if not town then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
@ -155,16 +153,16 @@ function towny:extend_town(pos,player)
return err_msg(player, "You do not have permission to spend claim blocks in your town.") return err_msg(player, "You do not have permission to spend claim blocks in your town.")
end end
if towny:get_claims_available(town) < 1 then if towny.get_claims_available(town) < 1 then
return err_msg(player, "You do not have enough remaining claim blocks!") return err_msg(player, "You do not have enough remaining claim blocks!")
end end
local p1,closest_town = towny.regions:align_new_claim_block(pos, player) local p1,closest_town = towny.regions.align_new_claim_block(pos, player)
if not p1 then if not p1 then
return err_msg(player, "You cannot claim this area! Town blocks must be aligned side-by-side.") return err_msg(player, "You cannot claim this area! Town blocks must be aligned side-by-side.")
end end
if towny.regions:town_claim_exists(town,p1) then if towny.regions.town_claim_exists(town,p1) then
return err_msg(player, "This area is already claimed.") return err_msg(player, "This area is already claimed.")
end end
@ -173,20 +171,20 @@ function towny:extend_town(pos,player)
end end
table.insert(towny.regions.memloaded[town].blocks, p1) table.insert(towny.regions.memloaded[town].blocks, p1)
minetest.chat_send_player(player, ("Successfully claimed this block! You have %d claim blocks left!"):format(towny:get_claims_available(town))) minetest.chat_send_player(player, ("Successfully claimed this block! You have %d claim blocks left!"):format(towny.get_claims_available(town)))
towny:mark_dirty(town, true) towny.mark_dirty(town, true)
towny.regions:visualize_radius(vector.subtract(p1, {x=tr/2,y=th/2,z=tr/2})) towny.regions.visualize_radius(vector.subtract(p1, {x=tr/2,y=th/2,z=tr/2}))
return true return true
end end
function towny:abridge_town(pos,player) function towny.abridge_town(pos,player)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
@ -196,25 +194,25 @@ function towny:abridge_town(pos,player)
return err_msg(player, "You do not have permission to delete claim blocks in your town.") return err_msg(player, "You do not have permission to delete claim blocks in your town.")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
local success,message = towny.regions:remove_claim(c[1],t) local success,message = towny.regions.remove_claim(c[1],t)
if not success then if not success then
return err_msg(player, "Failed to abandon claim block: " .. message) return err_msg(player, "Failed to abandon claim block: " .. message)
end end
minetest.chat_send_player(player, ("Successfully abandoned this claim block! You now have %d claim blocks available!") minetest.chat_send_player(player, ("Successfully abandoned this claim block! You now have %d claim blocks available!")
:format(towny:get_claims_available(town))) :format(towny.get_claims_available(town)))
towny:mark_dirty(t, true) towny.mark_dirty(t, true)
return true return true
end end
function towny:leave_town(player,kick) function towny.leave_town(player,kick)
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town then if not town then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
@ -260,12 +258,12 @@ function towny:leave_town(player,kick)
msg = "You were kicked form town." msg = "You were kicked form town."
end end
towny:mark_dirty(town, false) towny.mark_dirty(town, false)
minetest.chat_send_player(player, msg) minetest.chat_send_player(player, msg)
return true return true
end end
function towny:kick_member(town,player,member) function towny.kick_member(town,player,member)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
local data = towny.towns[town] local data = towny.towns[town]
@ -285,21 +283,21 @@ function towny:kick_member(town,player,member)
return err_msg(player, "You cannot kick yourself from town.") return err_msg(player, "You cannot kick yourself from town.")
end end
return towny:leave_town(member,true) return towny.leave_town(member,true)
end end
function towny:delete_town(pos,player) function towny.delete_town(pos,player)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -314,25 +312,25 @@ function towny:delete_town(pos,player)
-- Wipe the town -- Wipe the town
towny.towns[t] = nil towny.towns[t] = nil
towny.regions.memloaded[t] = nil towny.regions.memloaded[t] = nil
towny.flatfile:delete_all_meta(t) towny.storage.delete_all_meta(t)
minetest.chat_send_player(player, "Successfully deleted the town!") minetest.chat_send_player(player, "Successfully deleted the town!")
minetest.chat_send_all(("The town '%s' has fell into ruin."):format(name)) minetest.chat_send_all(("The town '%s' has fell into ruin."):format(name))
return true return true
end end
function towny:delete_plot(pos,player) function towny.delete_plot(pos,player)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town or not towny_admin) then if not t or (t ~= town or not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -343,26 +341,26 @@ function towny:delete_plot(pos,player)
return err_msg(player, "You do not have permission to delete this plot.") return err_msg(player, "You do not have permission to delete this plot.")
end end
towny.regions:set_plot(c[1],t,nil) towny.regions.set_plot(c[1],t,nil)
data.plots[p] = nil data.plots[p] = nil
towny:mark_dirty(t, true) towny.mark_dirty(t, true)
minetest.chat_send_player(player, "Successfully removed the plot.") minetest.chat_send_player(player, "Successfully removed the plot.")
return true return true
end end
function towny:create_plot(pos,player) function towny.create_plot(pos,player)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -378,7 +376,7 @@ function towny:create_plot(pos,player)
local pid = minetest.sha1(minetest.hash_node_position(c[1])) local pid = minetest.sha1(minetest.hash_node_position(c[1]))
local success,message = towny.regions:set_plot(c[1],t,pid) local success,message = towny.regions.set_plot(c[1],t,pid)
if not success then if not success then
minetest.chat_send_player(player, "Failed to create a plot here: " .. message) minetest.chat_send_player(player, "Failed to create a plot here: " .. message)
return false return false
@ -389,24 +387,24 @@ function towny:create_plot(pos,player)
members = {[player] = {}}, members = {[player] = {}},
flags = {}, flags = {},
} }
towny:mark_dirty(t, true) towny.mark_dirty(t, true)
minetest.chat_send_player(player, "Successfully created a plot!") minetest.chat_send_player(player, "Successfully created a plot!")
towny.regions:visualize_radius(vector.subtract(c[1], {x=tr/2,y=th/2,z=tr/2})) towny.regions.visualize_area(c[1], c[2])
return true return true
end end
function towny:claim_plot(pos,player) function towny.claim_plot(pos,player)
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town then if not town then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or t ~= town then if not t or t ~= town then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -426,10 +424,10 @@ function towny:claim_plot(pos,player)
flags = {}, flags = {},
} }
towny:mark_dirty(t, false) towny.mark_dirty(t, false)
minetest.chat_send_player(player, "Successfully claimed the plot!") minetest.chat_send_player(player, "Successfully claimed the plot!")
towny.regions:visualize_radius(vector.subtract(c[1], {x=tr/2,y=th/2,z=tr/2})) towny.regions.visualize_area(c[1], c[2])
return true return true
else else
@ -437,20 +435,20 @@ function towny:claim_plot(pos,player)
end end
end end
return towny:create_plot(pos,player) return towny.create_plot(pos,player)
end end
function towny:abandon_plot(pos,player) function towny.abandon_plot(pos,player)
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town then if not town then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or t ~= town then if not t or t ~= town then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -485,24 +483,24 @@ function towny:abandon_plot(pos,player)
end end
end end
pdata.members = members pdata.members = members
towny:mark_dirty(t, false) towny.mark_dirty(t, false)
minetest.chat_send_player(player, "Successfully abandoned the plot!") minetest.chat_send_player(player, "Successfully abandoned the plot!")
return true return true
end end
function towny:plot_member(pos,player,member,action) function towny.plot_member(pos,player,member,action)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town then if not town then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or t ~= town then if not t or t ~= town then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -548,7 +546,7 @@ function towny:plot_member(pos,player,member,action)
end end
pdata.members = members pdata.members = members
towny:mark_dirty(t, false) towny.mark_dirty(t, false)
minetest.chat_send_player(player, ("Successfully %s plot!"):format(action_desc)) minetest.chat_send_player(player, ("Successfully %s plot!"):format(action_desc))
return true return true
@ -556,19 +554,19 @@ end
-- Set flags -- Set flags
function towny:set_plot_flags(pos,player,flag,value) function towny.set_plot_flags(pos,player,flag,value)
if not flag then return false end if not flag then return false end
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -590,22 +588,22 @@ function towny:set_plot_flags(pos,player,flag,value)
minetest.chat_send_player(player, ("Successfully set the plot flag '%s' to '%s'!"):format(flag, value)) minetest.chat_send_player(player, ("Successfully set the plot flag '%s' to '%s'!"):format(flag, value))
plot_data.flags[flag] = res plot_data.flags[flag] = res
towny:mark_dirty(t, false) towny.mark_dirty(t, false)
end end
function towny:set_plot_member_flags(pos,player,member,flag,value) function towny.set_plot_member_flags(pos,player,member,flag,value)
if not member or not flag then return false end if not member or not flag then return false end
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -632,22 +630,22 @@ function towny:set_plot_member_flags(pos,player,member,flag,value)
minetest.chat_send_player(player, ("Successfully set the plot member %s's flag '%s' to '%s'!") minetest.chat_send_player(player, ("Successfully set the plot member %s's flag '%s' to '%s'!")
:format(member, flag, value)) :format(member, flag, value))
plot_data.members[member][flag] = res plot_data.members[member][flag] = res
towny:mark_dirty(t, false) towny.mark_dirty(t, false)
end end
function towny:set_town_flags(pos,player,flag,value) function towny.set_town_flags(pos,player,flag,value)
if not flag then return false end if not flag then return false end
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -664,22 +662,22 @@ function towny:set_town_flags(pos,player,flag,value)
minetest.chat_send_player(player, ("Successfully set the town flag '%s' to '%s'!"):format(flag,value)) minetest.chat_send_player(player, ("Successfully set the town flag '%s' to '%s'!"):format(flag,value))
data.flags[flag] = res data.flags[flag] = res
towny:mark_dirty(t, false) towny.mark_dirty(t, false)
end end
function towny:set_town_member_flags(pos,player,member,flag,value) function towny.set_town_member_flags(pos,player,member,flag,value)
if not member or not flag then return false end if not member or not flag then return false end
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos then if not pos then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local town = towny:get_player_town(player) local town = towny.get_player_town(player)
if not town and not towny_admin then if not town and not towny_admin then
return err_msg(player, "You're not currently in a town!") return err_msg(player, "You're not currently in a town!")
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can modify.") return err_msg(player, "You are not in any town you can modify.")
end end
@ -701,12 +699,12 @@ function towny:set_town_member_flags(pos,player,member,flag,value)
minetest.chat_send_player(player, ("Successfully set the town member %s's flag '%s' to '%s'!") minetest.chat_send_player(player, ("Successfully set the town member %s's flag '%s' to '%s'!")
:format(member, flag, value)) :format(member, flag, value))
data.members[member][flag] = res data.members[member][flag] = res
towny:mark_dirty(t, false) towny.mark_dirty(t, false)
end end
-- Getters -- Getters
function towny:get_flags(town,plot) function towny.get_flags(town,plot)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if not tdata then return nil end if not tdata then return nil end
if not plot then return tdata.flags end if not plot then return tdata.flags end
@ -714,32 +712,32 @@ function towny:get_flags(town,plot)
return tdata.plots[plot].flags return tdata.plots[plot].flags
end end
function towny:get_plot_flags(town,pos,player) function towny.get_plot_flags(town,pos,player)
local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
if not pos and player then if not pos and player then
pos = minetest.get_player_by_name(player):get_pos() pos = minetest.get_player_by_name(player):get_pos()
end end
local t,p,c = towny.regions:get_town_at(pos) local t,p,c = towny.regions.get_town_at(pos)
if not t or (t ~= town and not towny_admin) then if not t or (t ~= town and not towny_admin) then
return err_msg(player, "You are not in any town you can access.") return err_msg(player, "You are not in any town you can access.")
end end
if not t or not p then return nil end if not t or not p then return nil end
return towny:get_flags(t,p) return towny.get_flags(t,p)
end end
-- Get used claim blocks -- Get used claim blocks
function towny:get_claims_used(town) function towny.get_claims_used(town)
if not towny.regions.memloaded[town] then return 0 end if not towny.regions.memloaded[town] then return 0 end
return #towny.regions.memloaded[town].blocks return #towny.regions.memloaded[town].blocks
end end
-- Get maximum available claim blocks, including bonuses -- Get maximum available claim blocks, including bonuses
function towny:get_claims_max(town) function towny.get_claims_max(town)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if not tdata then return 0 end if not tdata then return 0 end
if not tdata.level then towny:get_town_level(town, true) end if not tdata.level then towny.get_town_level(town, true) end
local bonus = 0 local bonus = 0
if tdata.flags['claim_blocks'] and tdata.flags['claim_blocks'] > 0 then if tdata.flags['claim_blocks'] and tdata.flags['claim_blocks'] > 0 then
bonus = tdata.flags['claim_blocks'] bonus = tdata.flags['claim_blocks']
@ -748,26 +746,26 @@ function towny:get_claims_max(town)
end end
-- Get available claim blocks -- Get available claim blocks
function towny:get_claims_available(town) function towny.get_claims_available(town)
local used = towny:get_claims_used(town) local used = towny.get_claims_used(town)
local max = towny:get_claims_max(town) local max = towny.get_claims_max(town)
return max - used return max - used
end end
function towny:get_member_count(town) function towny.get_member_count(town)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if not tdata then return nil end if not tdata then return nil end
return count(tdata.members) return count(tdata.members)
end end
function towny:get_full_name(town) function towny.get_full_name(town)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if not tdata then return nil end if not tdata then return nil end
if not tdata.level then return tdata.name end if not tdata.level then return tdata.name end
return ("%s (%s)"):format(tdata.name, tdata.level.name_tag) return ("%s (%s)"):format(tdata.name, tdata.level.name_tag)
end end
function towny:get_town_level(town, update) function towny.get_town_level(town, update)
local tdata = towny.towns[town] local tdata = towny.towns[town]
if not tdata then return nil end if not tdata then return nil end
if tdata.level and not update then return tdata.level end if tdata.level and not update then return tdata.level end
@ -782,7 +780,7 @@ function towny:get_town_level(town, update)
end end
minetest.register_on_joinplayer(function (player) minetest.register_on_joinplayer(function (player)
local town = towny:get_player_town(player:get_player_name()) local town = towny.get_player_town(player:get_player_name())
if not town then return end if not town then return end
local tdata = towny.towns[town] local tdata = towny.towns[town]
@ -790,6 +788,6 @@ minetest.register_on_joinplayer(function (player)
if not tdata.flags["greeting"] then return nil end if not tdata.flags["greeting"] then return nil end
minetest.chat_send_player(player:get_player_name(), minetest.chat_send_player(player:get_player_name(),
minetest.colorize("#078e36", ("[%s] "):format(towny:get_full_name(town))) .. minetest.colorize("#078e36", ("[%s] "):format(towny.get_full_name(town))) ..
minetest.colorize("#02aacc", tdata.flags["greeting"])) minetest.colorize("#02aacc", tdata.flags["greeting"]))
end) end)

View File

@ -1,6 +1,7 @@
-- Visualize an area -- Visualize an area
-- TODO: Use particles
local r1 = towny.regions.size + 1 local r1 = towny.regions.size
local r2 = towny.regions.height + 1 local r2 = towny.regions.height + 1
local c_obj_props = { local c_obj_props = {
hp = 1, hp = 1,
@ -29,11 +30,11 @@ minetest.register_entity("towny:region_visual", {
end end
}) })
function towny.regions:visualize_radius(pos) function towny.regions.visualize_radius(pos)
local e = minetest.add_entity(pos, "towny:region_visual") local e = minetest.add_entity(pos, "towny:region_visual")
end end
function towny.regions:visualize_area(p1,p2) function towny.regions.visualize_area(p1,p2)
local center = {x=p2.x + r1/2,y=p2.y + r2/2,z=p2.z + r1/2} local center = {x=p2.x + r1/2,y=p2.y + r2/2,z=p2.z + r1/2}
local e = minetest.add_entity(center, "towny:region_visual") local e = minetest.add_entity(center, "towny:region_visual")
end end