diff --git a/chat.lua b/chat.lua index 02eb0d9..2b15ace 100644 --- a/chat.lua +++ b/chat.lua @@ -1,3 +1,6 @@ +-- Commands and chat modification + +-- TODO: Town names in chat -- Privileges @@ -13,7 +16,7 @@ minetest.register_privilege("towny_admin", { -- API -- 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] if tdata then for member in pairs(tdata.members) do @@ -27,7 +30,7 @@ end -- Commands 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 return false, "You are not in a town." end @@ -36,7 +39,7 @@ local function invite_player(town,player,target) return false, "You can only invite online players to your town." end - local target_town = towny:get_player_town(target) + local target_town = towny.get_player_town(target) if target_town then return false, "This player is already in a town!" end @@ -59,15 +62,15 @@ local function join_town(town,player,from_invite) local tdata = towny.towns[town] 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 - 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)) tdata.members[player] = {} - towny:mark_dirty(town,false) + towny.mark_dirty(town,false) return true end 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 return false, "You are already in a town." end @@ -112,19 +115,19 @@ end 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 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 local town_info = nil 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 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) 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 else return false, "No such town." @@ -146,23 +149,23 @@ local function town_command (name, param) local tdata = towny.towns[town] if param == "extend" or param == "claim" then - return towny:extend_town(nil, name) + return towny.extend_town(nil, name) elseif param == "leave" then - return towny:leave_town(name) + return towny.leave_town(name) elseif param == "unclaim" then - return towny:abridge_town(nil, name) + return towny.abridge_town(nil, name) elseif param == "visualize" then - towny.regions:visualize_town(town) + towny.regions.visualize_town(town) return true elseif param == "flags" then - local flags = towny:get_flags(town) + local flags = towny.get_flags(town) if flags then return send_flags(player,flags,"Flags of your town") end 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 towny.chat['delete_verify_' .. name] = nil - return towny:delete_town(nil, name) + return towny.delete_town(nil, name) else towny.chat['delete_verify_' .. name] = true 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 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"]) elseif pr1 == "kick" then - return towny:kick_member(town,name,pr2) + return towny.kick_member(town,name,pr2) elseif pr1 == "set" then 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 local action, user = string.match(pr2, "^([%a%d_-]+) (.+)$") if action == "kick" then - return towny:kick_member(town,name,pr2) + return towny.kick_member(town,name,pr2) elseif action == "set" then 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 @@ -195,13 +198,13 @@ local function town_command (name, param) if pr1 == "plot" then local pl1, pl2 = string.match(pr2, "^([%a%d_-]+) (.+)$") if pr2 == "claim" then - return towny:claim_plot(nil,name) + return towny.claim_plot(nil,name) elseif pr2 == "abandon" then - return towny:abandon_plot(nil,name) + return towny.abandon_plot(nil,name) elseif pr2 == "delete" then - return towny:delete_plot(nil,name) + return towny.delete_plot(nil,name) 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 return send_flags(player,flags,"Flags of this plot") else @@ -209,16 +212,16 @@ local function town_command (name, param) end elseif pl1 == "set" and pl2 then 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 local action, user = string.match(pl2, "^([%a%d_-]+) (.+)$") 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 - return towny:plot_member(nil,name,user,0) + return towny.plot_member(nil,name,user,0) elseif action == "set" then 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 elseif pr1 == "invite" and minetest.get_player_by_name(pr2) then diff --git a/init.lua b/init.lua index f8e42e4..a69734b 100644 --- a/init.lua +++ b/init.lua @@ -1,9 +1,14 @@ -- A township system for Minetest servers. -- The MIT License - 2019 Evert "Diamond" Prants +-- TODO: Protection on HUD +-- TODO: Nations +-- TODO: Economy + local modpath = minetest.get_modpath(minetest.get_current_modname()) towny = { - regions = { + modpath = modpath, + regions = { size = tonumber(minetest.settings:get('towny_claim_size')) or 16, height = tonumber(minetest.settings:get('towny_claim_height')) or 64, maxclaims = tonumber(minetest.settings:get('towny_claim_max')) or 128, @@ -13,7 +18,7 @@ towny = { memloaded = {}, }, -- See "Town data structure" - flatfile = {}, + storage = {}, towns = {}, chat = { 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.."/regions.lua") dofile(modpath.."/town.lua") diff --git a/regions.lua b/regions.lua index e73dc44..a9f40c6 100644 --- a/regions.lua +++ b/regions.lua @@ -15,7 +15,7 @@ local function region_equal(v1, v2) end -- 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 for x = p1.x, p2.x do if found then break end @@ -32,7 +32,7 @@ function towny.regions:already_protected(p1, p2, name) return found 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 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 plot.members[name] then if towndata.flags['plot_member_build'] == false then - return plot.members[name]['plot_build'] == true + return plot.members[name]['plot_build'] else - return true + return plot.members[name]['plot_build'] ~= false end end else @@ -86,7 +86,7 @@ local function single_range(p) return p1,p2 end -function towny.regions:get_town_at(pos) +function towny.regions.get_town_at(pos) local in_town, in_plot, in_claim for town,regions in pairs(towny.regions.memloaded) do 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 end -function towny.regions:get_closest_town(pos,name) +function towny.regions.get_closest_town(pos,name) local in_town,block local last_distance = 0 for town,regions in pairs(towny.regions.memloaded) do local count = true if name then - count = towny.regions:build_perms(town, name, nil) + count = towny.regions.build_perms(town, name, nil) end 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 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 local blocks = towny.regions.memloaded[town].blocks for _,pos in pairs(blocks) do @@ -142,8 +142,8 @@ function towny.regions:town_claim_exists(town,p1) return false end -function towny.regions:align_new_claim_block(pos,name) - local closest_town,closest_block,distance = towny.regions:get_closest_town(pos,name) +function towny.regions.align_new_claim_block(pos,name) + local closest_town,closest_block,distance = towny.regions.get_closest_town(pos,name) if not closest_town then return nil end 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 end -function towny.regions:remove_claim(p1,town) +function towny.regions.remove_claim(p1,town) local blocks = {} 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 @@ -194,7 +194,7 @@ function towny.regions:remove_claim(p1,town) return true 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 for _,block in pairs(towny.regions.memloaded[town].blocks) do if region_equal(block, pos) then @@ -205,24 +205,24 @@ function towny.regions:set_plot(pos,town,plot) return true end -function towny.regions:visualize_town(town) +function towny.regions.visualize_town(town) if not towny.regions.memloaded[town] then return end for _,pos in pairs(towny.regions.memloaded[town].blocks) do - towny.regions:visualize_radius(vector.subtract(pos, - {x=tr/2,y=th/2,z=tr/2})) + local p1,p2 = single_range(pos) + towny.regions.visualize_area(p1,p2) end end -function towny.regions:position_protected_from(pos, name) - local town,plot = towny.regions:get_town_at(pos) +function towny.regions.position_protected_from(pos, name) + local town,plot = towny.regions.get_town_at(pos) 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 -- Finally, override is_protected 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 return true end @@ -232,7 +232,7 @@ end --[[if minetest.settings:get('towny_prevent_protector') == 'true' then 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 end) end]] diff --git a/settingtypes.txt b/settingtypes.txt index 1bcdb0a..5baa97d 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -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 ################## diff --git a/flatfile.lua b/storage/flatfile.lua similarity index 67% rename from flatfile.lua rename to storage/flatfile.lua index cf1905c..1e8c5c9 100644 --- a/flatfile.lua +++ b/storage/flatfile.lua @@ -1,8 +1,10 @@ +-- Flatfile storage engine +-- Not recommended local extension = "lua" local serialize = true -function towny.flatfile:write_meta(town,dir,data) +local function write_meta(town,dir,data) local world = minetest.get_worldpath() local directory = world.."/towny/"..dir local filepath = town.."."..extension @@ -23,7 +25,7 @@ function towny.flatfile:write_meta(town,dir,data) minetest.safe_file_write(directory.."/"..filepath, serialized) end -function towny.flatfile:load_meta(filepath) +local function load_meta(filepath) local file = io.open(filepath) if not file then @@ -47,12 +49,12 @@ function towny.flatfile:load_meta(filepath) return data end -function towny.flatfile:save_town_meta(town) +function towny.storage.save_town_meta(town) local tmeta = towny.towns[town] if tmeta and tmeta.dirty then - towny:get_town_level(town, true) + towny.get_town_level(town, true) minetest.after(0.1, function () - towny.flatfile:write_meta(town,"meta",tmeta) + write_meta(town,"meta",tmeta) tmeta.dirty = false end) end @@ -60,14 +62,14 @@ function towny.flatfile:save_town_meta(town) local rmeta = towny.regions.memloaded[town] if rmeta and rmeta.dirty then minetest.after(0.2, function () - towny.flatfile:write_meta(town,"region",rmeta) + write_meta(town,"region",rmeta) rmeta.dirty = false end) end end local ldirs = { "meta", "region" } -function towny.flatfile:load_all_towns() +function towny.storage.load_all_towns() local world = minetest.get_worldpath() local metadir = world.."/towny/"..ldirs[1] minetest.mkdir(metadir) @@ -77,10 +79,10 @@ function towny.flatfile:load_all_towns() if file:match("."..extension.."$") then local town = file:gsub("."..extension,"") 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 towny.towns[town] = towndata - towny:get_town_level(town, true) + towny.get_town_level(town, true) end) end end @@ -93,7 +95,7 @@ function towny.flatfile:load_all_towns() if file:match("."..extension.."$") then local town = file:gsub("."..extension,"") 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 towny.regions.memloaded[town] = regiondata end) @@ -101,7 +103,7 @@ function towny.flatfile:load_all_towns() end end -function towny.flatfile:delete_all_meta(town) +function towny.storage.delete_all_meta(town) local world = minetest.get_worldpath() local file = town.."."..extension @@ -111,32 +113,3 @@ function towny.flatfile:delete_all_meta(town) minetest.after(0.1, os.remove, path) 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) diff --git a/storage/init.lua b/storage/init.lua new file mode 100644 index 0000000..e776937 --- /dev/null +++ b/storage/init.lua @@ -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) diff --git a/storage/modstorage.lua b/storage/modstorage.lua new file mode 100644 index 0000000..4071b36 --- /dev/null +++ b/storage/modstorage.lua @@ -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 diff --git a/town.lua b/town.lua index b01b332..5adc6bf 100644 --- a/town.lua +++ b/town.lua @@ -51,7 +51,7 @@ local function flag_validity(flag,scope,value,pos) return true, flag, value end -function towny:get_player_town(name) +function towny.get_player_town(name) for town,data in pairs(towny.towns) do if data.mayor == name then return town @@ -62,7 +62,7 @@ function towny:get_player_town(name) return nil end -function towny:get_town_by_name(name) +function towny.get_town_by_name(name) if not name then return nil end for town,data in pairs(towny.towns) do if data.name:lower() == name:lower() then @@ -72,7 +72,7 @@ function towny:get_town_by_name(name) return nil end -function towny:mark_dirty(town, areas) +function towny.mark_dirty(town, areas) towny.dirty = true towny.towns[town].dirty = true if areas and towny.regions.memloaded[town] then @@ -80,22 +80,22 @@ function towny:mark_dirty(town, areas) 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 }) if not pos then pos = minetest.get_player_by_name(player):get_pos() 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!") 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 return err_msg(player, "This location is too close to another town!") 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!") end @@ -128,24 +128,22 @@ function towny:create_town(pos, player, name) towny.towns[id] = data 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_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 end -function towny:extend_town(pos,player) +function towny.extend_town(pos,player) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town then return err_msg(player, "You're not currently in a town!") 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.") 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!") 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 return err_msg(player, "You cannot claim this area! Town blocks must be aligned side-by-side.") 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.") end @@ -173,20 +171,20 @@ function towny:extend_town(pos,player) end 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))) - towny:mark_dirty(town, true) + 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.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 end -function towny:abridge_town(pos,player) +function towny.abridge_town(pos,player) local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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.") 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 return err_msg(player, "You are not in any town you can modify.") 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 return err_msg(player, "Failed to abandon claim block: " .. message) end minetest.chat_send_player(player, ("Successfully abandoned this claim block! You now have %d claim blocks available!") - :format(towny:get_claims_available(town))) - towny:mark_dirty(t, true) + :format(towny.get_claims_available(town))) + towny.mark_dirty(t, true) return true end -function towny:leave_town(player,kick) - local town = towny:get_player_town(player) +function towny.leave_town(player,kick) + local town = towny.get_player_town(player) if not town then return err_msg(player, "You're not currently in a town!") end @@ -260,12 +258,12 @@ function towny:leave_town(player,kick) msg = "You were kicked form town." end - towny:mark_dirty(town, false) + towny.mark_dirty(town, false) minetest.chat_send_player(player, msg) return true 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 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.") end - return towny:leave_town(member,true) + return towny.leave_town(member,true) end -function towny:delete_town(pos,player) +function towny.delete_town(pos,player) local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") end @@ -314,25 +312,25 @@ function towny:delete_town(pos,player) -- Wipe the town towny.towns[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_all(("The town '%s' has fell into ruin."):format(name)) return true end -function towny:delete_plot(pos,player) +function towny.delete_plot(pos,player) local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") end @@ -343,26 +341,26 @@ function towny:delete_plot(pos,player) return err_msg(player, "You do not have permission to delete this plot.") end - towny.regions:set_plot(c[1],t,nil) + towny.regions.set_plot(c[1],t,nil) data.plots[p] = nil - towny:mark_dirty(t, true) + towny.mark_dirty(t, true) minetest.chat_send_player(player, "Successfully removed the plot.") return true end -function towny:create_plot(pos,player) +function towny.create_plot(pos,player) local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") end @@ -378,7 +376,7 @@ function towny:create_plot(pos,player) 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 minetest.chat_send_player(player, "Failed to create a plot here: " .. message) return false @@ -389,24 +387,24 @@ function towny:create_plot(pos,player) members = {[player] = {}}, flags = {}, } - towny:mark_dirty(t, true) + towny.mark_dirty(t, true) 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 end -function towny:claim_plot(pos,player) +function towny.claim_plot(pos,player) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") end @@ -426,10 +424,10 @@ function towny:claim_plot(pos,player) flags = {}, } - towny:mark_dirty(t, false) + towny.mark_dirty(t, false) 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 else @@ -437,20 +435,20 @@ function towny:claim_plot(pos,player) end end - return towny:create_plot(pos,player) + return towny.create_plot(pos,player) end -function towny:abandon_plot(pos,player) +function towny.abandon_plot(pos,player) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") end @@ -485,24 +483,24 @@ function towny:abandon_plot(pos,player) end end pdata.members = members - towny:mark_dirty(t, false) + towny.mark_dirty(t, false) minetest.chat_send_player(player, "Successfully abandoned the plot!") return true 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 }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") end @@ -548,7 +546,7 @@ function towny:plot_member(pos,player,member,action) end pdata.members = members - towny:mark_dirty(t, false) + towny.mark_dirty(t, false) minetest.chat_send_player(player, ("Successfully %s plot!"):format(action_desc)) return true @@ -556,19 +554,19 @@ end -- 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 local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") 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)) plot_data.flags[flag] = res - towny:mark_dirty(t, false) + towny.mark_dirty(t, false) 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 local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") 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'!") :format(member, flag, value)) plot_data.members[member][flag] = res - towny:mark_dirty(t, false) + towny.mark_dirty(t, false) 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 local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") 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)) data.flags[flag] = res - towny:mark_dirty(t, false) + towny.mark_dirty(t, false) 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 local towny_admin = minetest.check_player_privs(player, { towny_admin = true }) if not pos then pos = minetest.get_player_by_name(player):get_pos() end - local town = towny:get_player_town(player) + local town = towny.get_player_town(player) if not town and not towny_admin then return err_msg(player, "You're not currently in a town!") 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 return err_msg(player, "You are not in any town you can modify.") 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'!") :format(member, flag, value)) data.members[member][flag] = res - towny:mark_dirty(t, false) + towny.mark_dirty(t, false) end -- Getters -function towny:get_flags(town,plot) +function towny.get_flags(town,plot) local tdata = towny.towns[town] if not tdata then return nil end if not plot then return tdata.flags end @@ -714,32 +712,32 @@ function towny:get_flags(town,plot) return tdata.plots[plot].flags 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 }) if not pos and player then pos = minetest.get_player_by_name(player):get_pos() 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 return err_msg(player, "You are not in any town you can access.") end if not t or not p then return nil end - return towny:get_flags(t,p) + return towny.get_flags(t,p) end -- 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 return #towny.regions.memloaded[town].blocks end -- Get maximum available claim blocks, including bonuses -function towny:get_claims_max(town) +function towny.get_claims_max(town) local tdata = towny.towns[town] 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 if tdata.flags['claim_blocks'] and tdata.flags['claim_blocks'] > 0 then bonus = tdata.flags['claim_blocks'] @@ -748,26 +746,26 @@ function towny:get_claims_max(town) end -- Get available claim blocks -function towny:get_claims_available(town) - local used = towny:get_claims_used(town) - local max = towny:get_claims_max(town) +function towny.get_claims_available(town) + local used = towny.get_claims_used(town) + local max = towny.get_claims_max(town) return max - used end -function towny:get_member_count(town) +function towny.get_member_count(town) local tdata = towny.towns[town] if not tdata then return nil end return count(tdata.members) end -function towny:get_full_name(town) +function towny.get_full_name(town) local tdata = towny.towns[town] if not tdata then return nil end if not tdata.level then return tdata.name end return ("%s (%s)"):format(tdata.name, tdata.level.name_tag) end -function towny:get_town_level(town, update) +function towny.get_town_level(town, update) local tdata = towny.towns[town] if not tdata then return nil end if tdata.level and not update then return tdata.level end @@ -782,7 +780,7 @@ function towny:get_town_level(town, update) end 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 local tdata = towny.towns[town] @@ -790,6 +788,6 @@ minetest.register_on_joinplayer(function (player) if not tdata.flags["greeting"] then return nil end 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"])) end) diff --git a/visualize.lua b/visualize.lua index ffb9e89..4eb2c62 100644 --- a/visualize.lua +++ b/visualize.lua @@ -1,6 +1,7 @@ -- Visualize an area +-- TODO: Use particles -local r1 = towny.regions.size + 1 +local r1 = towny.regions.size local r2 = towny.regions.height + 1 local c_obj_props = { hp = 1, @@ -29,11 +30,11 @@ minetest.register_entity("towny:region_visual", { end }) -function towny.regions:visualize_radius(pos) +function towny.regions.visualize_radius(pos) local e = minetest.add_entity(pos, "towny:region_visual") 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 e = minetest.add_entity(center, "towny:region_visual") end