diff --git a/chatcommands.lua b/chatcommands.lua index 7cc8136..e69de29 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -1,619 +0,0 @@ -------------------------------------------------------------------------------- --- factions Mod by Sapier --- --- License WTFPL --- ---! @file chatcommnd.lua ---! @brief factions chat interface ---! @copyright Sapier, agrecascino, shamoanjac ---! @author Sapier, agrecascino, shamoanjac ---! @date 2016-08-12 --- --- Contact sapier a t gmx net -------------------------------------------------------------------------------- - -local send_error = function(player, message) - minetest.chat_send_player(player, message) -end - -factions_chat = {} - -factions.commands = {} - -factions.register_command = function(cmd_name, cmd) - factions.commands[cmd_name] = { -- default command - name = cmd_name, - faction_permissions = {}, - global_privileges = {}, - format = {}, - infaction = true, - description = "This command has no description.", - run = function(self, player, argv) - if self.global_privileges then - local tmp = {} - for i in ipairs(self.global_privileges) do - tmp[self.global_privileges[i]] = true - end - local bool, missing_privs = minetest.check_player_privs(player, tmp) - if not bool then - send_error(player, "Unauthorized.") - end - end - -- checks argument formats - local args = { - factions = {}, - players = {}, - strings = {}, - other = {} - } - if #argv < #(self.format) then - send_error(player, "Not enough parameters.") - return false - end - for i in ipairs(self.format) do - local argtype = self.format[i] - local arg = argv[i] - if argtype == "faction" then - local fac = factions.factions[arg] - if not fac then - send_error(player, "Specified faction "..arg.." does not exist") - return false - else - table.insert(args.factions, fac) - end - elseif argtype == "player" then - local pl = minetest.get_player_by_name(arg) - if not pl then - send_error(player, "Player is not online.") - --TODO: track existing players for offsync invites and the like - return false - else - table.insert(args.players, pl) - end - elseif argtype == "string" then - table.insert(args.strings, arg) - else - minetest.log("error", "Bad format definition for function "..self.name) - send_error(player, "Internal server error") - return false - end - end - for i=#self.format, #argv, 1 do - table.insert(args.other, argv[i]) - end - - -- checks permissions - local player_faction = factions.players[player] - if self.infaction and not player_faction then - minetest.chat_send_player(player, "This command is only available within a faction.") - return false - end - player_faction = factions.factions[player_faction] - if self.faction_permissions then - for i in ipairs(self.faction_permissions) do - if not player_faction:has_permission(player, self.faction_permissions[i]) then - send_error(player, "You don't have permissions to do that.") - return false - end - end - end - - -- get some more data - local pos = minetest.get_player_by_name(player):getpos() - local chunkpos = factions.get_chunk_pos(pos) - return self.on_success(player, player_faction, pos, chunkpos, args) - end, - on_success = function(player, faction, pos, chunkpos, args) - minetest.chat_send_player(player, "Not implemented yet!") - end - } - -- override defaults - for k, v in pairs(cmd) do - factions.commands[cmd_name][k] = v - end -end - - -local init_commands -init_commands = function() - - minetest.register_privilege("faction_user", - { - description = "this user is allowed to interact with faction mod", - give_to_singleplayer = true, - } - ) - - minetest.register_privilege("faction_admin", - { - description = "this user is allowed to create or delete factions", - give_to_singleplayer = true, - } - ) - - minetest.register_chatcommand("factions", - { - params = " .. ", - description = "faction administration functions", - privs = { interact=true }, - func = factions_chat.cmdhandler, - } - ) - - - minetest.register_chatcommand("f", - { - params = " parameters", - description = "Factions commands. Type /f help for available commands.", - privs = { interact=true}, - func = factions_chat.cmdhandler, - } - ) -end - - -------------------------------------------- --- R E G I S T E R E D C O M M A N D S | -------------------------------------------- - -factions.register_command ("claim", { - faction_permissions = {"claim"}, - description = "Claim the plot of land you're on.", - on_success = function(player, faction, pos, chunkpos, args) - local can_claim = faction:can_claim_chunk(chunkpos) - if can_claim then - minetest.chat_send_player(player, "Claming chunk "..chunkpos) - faction:claim_chunk(chunkpos) - return true - else - local chunk = factions.chunks[chunkpos] - if not chunk then - send_error(player, "You faction cannot claim any (more) chunk(s).") - return false - elseif chunk == faction.name then - send_error(player, "This chunk already belongs to your faction.") - return false - else - send_error(player, "This chunk belongs to another faction.") - return false - end - end - end -}) - -factions.register_command("unclaim", { - faction_permissions = {"claim"}, - description = "Unclaim the plot of land you're on.", - on_success = function(player, faction, pos, chunkpos, args) - local chunk = factions.chunks[chunkpos] - if chunk ~= faction.name then - send_error(player, "This chunk does not belong to you.") - return false - else - faction:unclaim_chunk(chunkpos) - return true - end - end -}) - ---list all known factions -factions.register_command("list", { - description = "List all registered factions.", - infaction = false, - on_success = function(player, faction, pos, chunkpos, args) - local list = factions.get_faction_list() - local tosend = "Existing factions:" - - for i,v in ipairs(list) do - if i ~= #list then - tosend = tosend .. " " .. v .. "," - else - tosend = tosend .. " " .. v - end - end - minetest.chat_send_player(player, tosend, false) - return true - end -}) - ---show factions mod version -factions.register_command("version", { - description = "Displays mod version.", - on_success = function(player, faction, pos, chunkpos, args) - minetest.chat_send_player(player, "factions: version " .. factions_version , false) - end -}) - ---show description of faction -factions.register_command("info", { - format = {"faction"}, - description = "Shows a faction's description.", - on_success = function(player, faction, pos, chunkpos, args) - minetest.chat_send_player(player, - "factions: " .. args.factions[1].name .. ": " .. - args.factions[1].description, false) - return true - end -}) - -factions.register_command("leave", { - description = "Leave your faction.", - on_success = function(player, faction, pos, chunkpos, args) - faction:remove_player(player) - return true - end -}) - -factions.register_command("kick", { - faction_permissions = {"playerslist"}, - format = {"player"}, - description = "Kick a player from your faction.", - on_success = function(player, faction, pos, chunkpos, args) - local victim = args.players[1] - if factions.players[victim.name] == faction.name - and victim.name ~= faction.leader then -- can't kick da king - faction:remove_player(player) - return true - else - send_error(player, "Cannot kick player "..victim.name) - return false - end - end -}) - ---create new faction -factions.register_command("create", { - format = {"string"}, - infaction = false, - description = "Create a new faction.", - on_success = function(player, faction, pos, chunkpos, args) - if faction then - send_error(player, "You are already in a faction.") - return false - end - local factionname = args.strings[1] - if factions.can_create_faction(factionname) then - new_faction = factions.new_faction(factionname, nil) - new_faction:add_player(player, new_faction.default_leader_rank) - return true - else - send_error(player, "Faction cannot be created.") - return false - end - end -}) - -factions.register_command("join", { - format = {"faction"}, - description = "Join a faction.", - infaction = false, - on_success = function(player, faction, pos, chunkpos, args) - local new_faction = args.factions[1] - if new_faction:can_join(player) then - if faction then -- leave old faction - faction:remove_player(player) - end - new_faction:add_player(player) - else - send_error(player, "You cannot join this faction.") - return false - end - return true - end -}) - -factions.register_command("disband", { - faction_permissions = {"disband"}, - description = "Disband your faction.", - on_success = function(player, faction, pos, chunkpos, args) - faction:disband() - return true - end -}) - -factions.register_command("close", { - faction_permissions = {"playerslist"}, - description = "Make your faction invite-only.", - on_success = function(player, faction, pos, chunkpos, args) - faction:toggle_join_free(false) - --TODO: message - return true - end -}) - -factions.register_command("open", { - faction_permissions = {"playerslist"}, - description = "Allow any player to join your faction.", - on_success = function(player, faction, pos, chunkpos, args) - faction:toggle_join_free(true) - --TODO: message - return true - end -}) - -factions.register_command("description", { - faction_permissions = {"description"}, - description = "Set your faction's description", - on_success = function(player, faction, pos, chunkpos, args) - faction:set_description(table.concat(args.other," ")) - --TODO: message - return true - end -}) - -factions.register_command("invite", { - format = {"player"}, - faction_permissions = {"playerslist"}, - description = "Invite a player to your faction.", - on_success = function(player, faction, pos, chunkpos, args) - faction:invite_player(args.players[1]:get_player_name()) - --TODO: message - return true - end -}) - -factions.register_command("uninvite", { - format = {"player"}, - faction_permissions = {"playerslist"}, - description = "Revoke a player's invite.", - on_success = function(player, faction, pos, chunkpos, args) - faction:revoke_invite(args.players[1]:get_player_name()) - --TODO: message - return true - end -}) - -factions.register_command("delete", { - global_privileges = {"faction_admin"}, - format = {"faction"}, - infaction = false, - description = "Delete a faction.", - on_success = function(player, faction, pos, chunkpos, args) - args.factions[1]:disband() - --TODO: message - return true - end -}) - -factions.register_command("ranks", { - description = "List ranks within your faction", - on_success = function(player, faction, pos, chunkpos, args) - for rank, permissions in pairs(faction.ranks) do - minetest.chat_send_player(player, rank..": "..table.concat(permissions, " ")) - end - return true - end -}) - -factions.register_command("who", { - description = "List players in your faction, and their ranks.", - on_success = function(player, faction, pos, chunkpos, args) - if not faction.players then - minetest.chat_send_player(player, "There is nobody in this faction ("..faction.name..")") - return true - end - minetest.chat_send_player(player, "Players in faction "..faction.name..": ") - for player, rank in pairs(faction.players) do - minetest.chat_send_player(player, player.." ("..rank..")") - end - return true - end -}) - -factions.register_command("newrank", { - description = "Add a new rank.", - format = {"string"}, - faction_permissions = {"ranks"}, - on_success = function(player, faction, pos, chunkpos, args) - local rank = args.strings[1] - if faction.ranks[rank] then - --TODO: rank already exists - return false - end - faction:add_rank(rank, args.other) - return true - end -}) - -factions.register_command("delrank", { - description = "Replace and delete a rank.", - format = {"string", "string"}, - faction_permissions = {"ranks"}, - on_success = function(player, faction, pos, chunkpos, args) - local rank = args.strings[1] - local newrank = args.strings[2] - if not faction.ranks[rank] or not faction.ranks[rank] then - --TODO: error (one of either ranks do not exist) - return false - end - faction:delete_rank(rank, newrank) - return true - end -}) - -factions.register_command("setspawn", { - description = "Set the faction's spawn", - faction_permissions = {"spawn"}, - on_success = function(player, faction, pos, chunkpos, args) - faction:set_spawn(pos) - return true - end -}) - -factions.register_command("where", { - description = "See whose chunk you stand on.", - infaction = false, - on_success = function(player, faction, pos, chunkpos, args) - local chunk = factions.chunks[chunkpos] - minetest.chat_send_player(player, "You are standing on chunk "..chunkpos..", part of "..(chunk or "Wilderness")) - return true - end -}) - -factions.register_command("help", { - description = "Shows help for commands.", - infaction = false, - on_success = function(player, faction, pos, chunkpos, args) - factions_chat.show_help(player) - return true - end -}) - -factions.register_command("spawn", { - description = "Shows your faction's spawn", - on_success = function(player, faction, pos, chunkpos, args) - if faction.spawn then - minetest.chat_send_player(player, "Spawn is at ("..table.concat(faction.spawn, ", ")..")") - return true - else - minetest.chat_send_player(player, "Your faction has no spawn set.") - return false - end - end -}) - -factions.register_command("promote", { - description = "Promotes a player to a rank", - format = {"player", "string"}, - faction_permissions = {"promote"}, - on_success = function(player, faction, pos, chunkpos, args) - local rank = args.strings[1] - if faction.ranks[rank] then - faction:promote(args.players[1], rank) - return true - else - send_error(player, "The specified rank does not exist.") - return false - end - end -}) - -factions.register_command("power", { - description = "Display your faction's power", - on_success = function(player, faction, pos, chunkpos, args) - minetest.chat_send_player(player, "Power: "..faction.power) - return true - end -}) - -factions.register_command("setbanner", { - description = "Sets the banner you're on as the faction's banner.", - faction_permissions = {"banner"}, - on_success = function(player, faction, pos, chunkpos, args) - local meta = minetest.get_meta({x = pos.x, y = pos.y - 1, z = pos.z}) - local banner = meta:get_string("banner") - if not banner then - minetest.chat_send_player(player, "No banner found.") - return false - end - faction:set_banner(banner) - end -}) - -factions.register_command("convert", { - description = "Load factions in the old format", - infaction = false, - global_privileges = {"faction_admin"}, - format = {"string"}, - on_success = function(player, faction, pos, chunkpos, args) - if factions.convert(args.strings[1]) then - minetest.chat_send_player(player, "Factions successfully converted.") - else - minetest.chat_send_player(player, "Error.") - end - return true - end -}) - -factions.register_command("free", { - description = "Forcefully frees a chunk", - infaction = false, - global_privileges = {"faction_admin"}, - on_success = function(player, faction, pos, chunkpos, args) - local fac = factions.chunks[chunkpos] - if not fac then - send_error(player, "No claim at this position") - return false - end - faction:unclaim_chunk(chunkpos) - return true - end -}) - -factions.register_command("chat", { - description = "Send a message to your faction's members", - on_success = function(player, faction, pos, chunkpos, args) - local msg = table.concat(args.other, " ") - faction:broadcast(msg, player) - end -}) - -------------------------------------------------------------------------------- --- name: cmdhandler(playername,parameter) --- ---! @brief chat command handler ---! @memberof factions_chat ---! @private --- ---! @param playername name ---! @param parameter data supplied to command -------------------------------------------------------------------------------- -factions_chat.cmdhandler = function (playername,parameter) - - local player = minetest.env:get_player_by_name(playername) - local params = parameter:split(" ") - local player_faction = factions.players[playername] - - if parameter == nil or - parameter == "" then - if player_faction then - minetest.chat_send_player(playername, "You are in faction "..player_faction..". Type /f help for a list of commands.") - else - minetest.chat_send_player(playername, "You are part of no faction") - end - return - end - - local cmd = factions.commands[params[1]] - if not cmd then - send_error(playername, "Unknown command.") - return false - end - - local argv = {} - for i=2, #params, 1 do - table.insert(argv, params[i]) - end - - cmd:run(playername, argv) - -end - -------------------------------------------------------------------------------- --- name: show_help(playername,parameter) --- ---! @brief send help message to player ---! @memberof factions_chat ---! @private --- ---! @param playername name -------------------------------------------------------------------------------- -function factions_chat.show_help(playername) - - local MSG = function(text) - minetest.chat_send_player(playername,text,false) - end - - MSG("factions mod") - MSG("Usage:") - for k, v in pairs(factions.commands) do - local args = {} - for i in ipairs(v.format) do - table.insert(args, v.format[i]) - end - MSG("\t/factions "..k.." <"..table.concat(args, "> <").."> : "..v.description) - end -end - -init_commands() - diff --git a/factions.lua b/factions.lua index 4656f75..e69de29 100644 --- a/factions.lua +++ b/factions.lua @@ -1,609 +0,0 @@ -------------------------------------------------------------------------------- --- factions Mod by Sapier --- --- License WTFPL --- ---! @file factions.lua ---! @brief factions core file ---! @copyright Sapier, agrecascino, shamoanjac ---! @author Sapier, agrecascino, shamoanjac ---! @date 2016-08-12 --- --- Contact sapier a t gmx net -------------------------------------------------------------------------------- - ---read some basic information -local factions_worldid = minetest.get_worldpath() - ---! @class factions ---! @brief main class for factions -factions = {} - ---! @brief runtime data -factions.factions = {} -factions.chunks = {} -factions.players = {} - - -factions.factions = {} ---- settings -factions.lower_laimable_height = -512 -factions.power_per_chunk = .5 - ---------------------- ---! @brief returns whether a faction can be created or not (allows for implementation of blacklists and the like) ---! @param name String containing the faction's name -factions.can_create_faction = function(name) - if factions.factions[name] then - return false - else - return true - end -end - - -factions.Faction = { -} - -util = { - coords3D_string = function(coords) - return coords.x..", "..coords.y..", "..coords.z - end -} - -factions.Faction.__index = factions.Faction - - --- Faction permissions: --- --- disband: disband the faction --- claim: (un)claim chunks --- playerslist: invite/kick players and open/close the faction --- build: dig and place nodes --- description: set the faction's description --- ranks: create and delete ranks --- spawn: set the faction's spawn --- banner: set the faction's banner --- promote: set a player's rank - -function factions.Faction:new(faction) - faction = { - --! @brief power of a faction (needed for chunk claiming) - power = 0., - --! @brief maximum power of a faction - maxpower = 0., - --! @brief list of player names - players = {}, - --! @brief table of ranks/permissions - ranks = {["leader"] = {"disband", "claim", "playerslist", "build", "description", "ranks", "spawn", "banner", "promote"}, - ["moderator"] = {"claim", "playerslist", "build", "spawn"}, - ["member"] = {"build"} - }, - --! @brief name of the leader - leader = nil, - --! @brief default joining rank for new members - default_rank = "member", - --! @brief default rank assigned to the leader - default_leader_rank = "leader", - --! @brief faction's description string - description = "Default faction description.", - --! @brief list of players currently invited (can join with /f join) - invited_players = {}, - --! @brief table of claimed chunks (keys are chunkpos strings) - land = {}, - --! @brief table of allies - allies = {}, - --! @brief table of enemies - enemies = {}, - --! @brief table of chunks/factions that are under attack - attacked_chunks = {}, - --! @brief whether faction is closed or open (boolean) - join_free = false, - --! @brief banner texture string - banner = "bg_white.png", - } or faction - setmetatable(faction, self) - return faction -end - - ---! @brief create a new empty faction -factions.new_faction = function(name) - local faction = factions.Faction:new(nil) - faction.name = name - factions.factions[name] = faction - factions.save() - return faction -end - -function factions.Faction.increase_power(self, power) - self.power = self.power + power - factions.save() -end - -function factions.Faction.decrease_power(self, power) - self.power = self.power - power - factions.save() -end - -function factions.Faction.add_player(self, player, rank) - self:on_player_join(player) - self.players[player] = rank or self.default_rank - factions.players[player] = self.name - self.invited_players[player] = nil - factions.save() -end - -function factions.Faction.remove_player(self, player) - self.players[player] = nil - factions.players[player] = nil - self:on_player_leave(player) - factions.save() -end - ---! @param chunkpos position of the wanted chunk ---! @return whether this faction can claim a chunkpos -function factions.Faction.can_claim_chunk(self, chunkpos) - local fac = factions.chunks[chunkpos] - if fac then - if factions.factions[fac].power < 0. and self.power >= factions.power_per_chunk then - return true - else - return false - end - elseif self.power < factions.power_per_chunk then - return false - end - return true -end - ---! @brief claim a chunk, update power and update global chunks table -function factions.Faction.claim_chunk(self, chunkpos) - -- check if claiming over other faction's territory - local otherfac = factions.chunks[chunkpos] - if otherfac then - local faction = factions.factions[otherfac] - faction:unclaim_chunk(chunkpos) - end - factions.chunks[chunkpos] = self.name - self.land[chunkpos] = true - self:decrease_power(factions.power_per_chunk) - self:on_claim_chunk(chunkpos) - factions.save() -end - ---! @brief claim a chunk, update power and update global chunks table -function factions.Faction.unclaim_chunk(self, chunkpos) - factions.chunks[chunkpos] = nil - self.land[chunkpos] = nil - self:increase_power(factions.power_per_chunk) - self:on_unclaim_chunk(chunkpos) - factions.save() -end - ---! @brief disband faction, updates global players and chunks table -function factions.Faction.disband(self) - for k, _ in pairs(self.players) do -- remove players affiliation - factions.players[k] = nil - end - for k, v in pairs(self.land) do -- remove chunk claims - factions.chunks[k] = nil - end - self:on_disband() - factions.factions[self.name] = nil - factions.save() -end - ---! @brief change the faction leader -function factions.Faction.set_leader(self, player) - self.leader = player - self.players[player] = self.default_leader_rank - self:on_new_leader() - factions.save() -end - ---! @brief check permissions for a given player ---! @return boolean indicating permissions. Players not in faction always receive false -function factions.Faction.has_permission(self, player, permission) - local p = self.players[player] - if not p then - return false - end - local perms = self.ranks[p] - for i in ipairs(perms) do - if perms[i] == permission then - return true - end - end - return false -end -function factions.Faction.set_description(self, new) - self.description = new - self:on_change_description() - factions.save() -end - ---! @brief places player in invite list -function factions.Faction.invite_player(self, player) - self.invited_players[player] = true - self:on_player_invited(player) - factions.save() -end - ---! @brief removes player from invite list (can no longer join via /f join) -function factions.Faction.revoke_invite(self, player) - self.invited_players[player] = nil - self:on_revoke_invite(player) - factions.save() -end ---! @brief set faction openness -function factions.Faction.toggle_join_free(self, bool) - self.join_free = bool - self:on_toggle_join_free() - factions.save() -end - ---! @return true if a player can use /f join, false otherwise -function factions.Faction.can_join(self, player) - return self.join_free or self.invited_players[player] -end - -function factions.Faction.new_alliance(self, faction) - self.allies[faction] = true - self:on_new_alliance(faction) - if self.enemies[faction] then - self:end_enemy(faction) - end - factions.save() -end -function factions.Faction.end_alliance(self, faction) - self.allies[faction] = nil - self:on_end_alliance(faction) - factions.save() -end -function factions.Faction.new_enemy(self, faction) - self.enemies[faction] = true - self:on_new_enemy(faction) - if self.allies[faction] then - self:end_alliance(faction) - end - factions.save() -end -function factions.Faction.end_enemy(self, faction) - self.enemies[faction] = nil - self:on_end_enemy(faction) - factions.save() -end - ---! @brief faction's member will now spawn in a new place -function factions.Faction.set_spawn(self, pos) - self.spawn = {x=pos.x, y=pos.y, z=pos.z} - self:on_set_spawn(pos) - factions.save() -end - ---! @brief create a new rank with permissions ---! @param rank the name of the new rank ---! @param rank a list with the permissions of the new rank -function factions.Faction.add_rank(self, rank, perms) - self.ranks[rank] = perms - self:on_add_rank(rank) - factions.save() -end - ---! @brief delete a rank and replace it ---! @param rank the name of the rank to be deleted ---! @param newrank the rank given to players who were previously "rank" -function factions.Faction.delete_rank(self, rank, newrank) - for player, r in pairs(self.players) do - if r == rank then - self.players[player] = newrank - end - end - self.ranks[rank] = nil - self:on_delete_rank(rank, newrank) - factions.save() -end - ---! @param newbanner texture string of the new banner -function factions.Faction.set_banner(self, newbanner) - self.banner = newbanner - self:on_new_banner() -end - ---! @brief set a player's rank -function factions.Faction.promote(self, member, rank) - self.players[member] = rank - self:on_promote(member) -end - ---! @brief send a message to all members -function factions.Faction.broadcast(self, msg, sender) - local message = self.name.."> "..msg - if sender then - message = sender.."@"..message - end - message = "Faction<"..message - for k, _ in pairs(self.players) do - minetest.chat_send_player(k, message) - end -end - --------------------------- --- callbacks for events -- -function factions.Faction.on_create(self) --! @brief called when the faction is added to the global faction list - minetest.chat_send_all("Faction "..self.name.." has been created.") -end - -function factions.Faction.on_player_leave(self, player) - self:broadcast(player.." has left this faction.") -end - -function factions.Faction.on_player_join(self, player) - self:broadcast(player.." has joined this faction.") -end - -function factions.Faction.on_claim_chunk(self, pos) - self:broadcast("Chunk ("..pos..") has been claimed.") -end - -function factions.Faction.on_unclaim_chunk(self, pos) - self:broadcast("Chunk ("..pos..") has been unclaimed.") -end - -function factions.Faction.on_disband(self, pos) - minetest.chat_send_all("Faction "..self.name.." has been disbanded.") -end - -function factions.Faction.on_new_leader(self) - self:broadcast(self.leader.." is now the leader of this faction.") -end - -function factions.Faction.on_change_description(self) - self:broadcast("Faction description has been modified to: "..self.description) -end - -function factions.Faction.on_player_invited(self, player) - minetest.chat_send_player(player, "You have been invited to faction "..self.name) -end - -function factions.Faction.on_toggle_join_free(self, player) - self:broadcast("This faction is now invite-free.") -end - -function factions.Faction.on_new_alliance(self, faction) - self:broadcast("This faction is now allied with "..faction) -end - -function factions.Faction.on_end_alliance(self, faction) - self:broadcast("This faction is no longer allied with "..faction.."!") -end - -function factions.Faction.on_set_spawn(self) - self:broadcast("The faction spawn has been set to ("..util.coords3D_string(pos)..").") -end - -function factions.Faction.on_add_rank(self, rank) - self:broadcast("The rank "..rank.." has been created with privileges: "..table.concat(self.ranks[rank], ", ")) -end - -function factions.Faction.on_delete_rank(self, rank, newrank) - self:broadcast("The rank "..rank.." has been deleted and replaced by "..newrank) -end - -function factions.Faction.on_new_banner(self) - self:broadcast("A new banner has been set.") -end - -function factions.Faction.on_promote(self, member) - minetest.chat_send_player(player, "You have been promoted to "..self.players[member]) -end - -function factions.Faction.on_revoke_invite(self, player) - minetest.chat_send_player(player, "You are no longer invited to faction "..self.name) -end - ---?????????????? - -function factions.get_chunk_pos(pos) - return math.floor(pos.x / 16.)..","..math.floor(pos.z / 16.) -end - - -------------------------------------------------------------------------------- --- name: add_faction(name) --- ---! @brief add a faction ---! @memberof factions ---! @public --- ---! @param name of faction to add ---! ---! @return faction object/false (succesfully added faction or not) -------------------------------------------------------------------------------- -function factions.add_faction(name) - if factions.can_create_faction(name) then - local fac = factions.new_faction(name) - fac:on_create() - return fac - else - return nil - end -end - -------------------------------------------------------------------------------- --- name: get_faction_list() --- ---! @brief get list of factions ---! @memberof factions ---! @public ---! ---! @return list of factions -------------------------------------------------------------------------------- -function factions.get_faction_list() - - local retval = {} - - for key,value in pairs(factions.factions) do - table.insert(retval,key) - end - - return retval -end - -------------------------------------------------------------------------------- --- name: save() --- ---! @brief save data to file ---! @memberof factions ---! @private -------------------------------------------------------------------------------- -function factions.save() - - --saving is done much more often than reading data to avoid delay - --due to figuring out which data to save and which is temporary only - --all data is saved here - --this implies data needs to be cleant up on load - - local file,error = io.open(factions_worldid .. "/" .. "factions.conf","w") - - if file ~= nil then - file:write(minetest.serialize(factions.factions)) - file:close() - else - minetest.log("error","MOD factions: unable to save factions world specific data!: " .. error) - end - -end - -------------------------------------------------------------------------------- --- name: load() --- ---! @brief load data from file ---! @memberof factions ---! @private --- ---! @return true/false -------------------------------------------------------------------------------- -function factions.load() - local file,error = io.open(factions_worldid .. "/" .. "factions.conf","r") - - if file ~= nil then - local raw_data = file:read("*a") - factions.factions = minetest.deserialize(raw_data) - for facname, faction in pairs(factions.factions) do - minetest.log("action", facname..","..faction.name) - for player, rank in pairs(faction.players) do - minetest.log("action", player..","..rank) - factions.players[player] = facname - end - for chunkpos, val in pairs(faction.land) do - factions.chunks[chunkpos] = facname - end - setmetatable(faction, factions.Faction) - end - file:close() - end -end - -function factions.convert(filename) - local file, error = io.open(factions_worldid .. "/" .. filename, "r") - if not file then - minetest.chat_send_all("Cannot load file "..filename..". "..error) - return false - end - local raw_data = file:read("*a") - local data = minetest.deserialize(raw_data) - local factionsmod = data.factionsmod - local objects = data.objects - for faction, attrs in pairs(factionsmod) do - local newfac = factions.new_faction(faction) - newfac:add_player(attrs.owner, "leader") - for player, _ in pairs(attrs.adminlist) do - if not newfac.players[player] then - newfac:add_player(player, "moderator") - end - end - for player, _ in pairs(attrs.invitations) do - newfac:invite_player(player) - end - for i in ipairs(attrs.chunk) do - local chunkpos = table.concat(attrs.chunk[i],",") - newfac:claim_chunk(chunkpos) - end - end - for player, attrs in pairs(objects) do - local facname = attrs.factionsmod - local faction = factions.factions[facname] - if faction then - faction:add_player(player) - end - end - return true -end - -minetest.register_on_dieplayer( - function(player) - end -) - -local lastUpdate = 0. - -minetest.register_globalstep( - function(dtime) - lastUpdate = lastUpdate + dtime - if lastUpdate > .5 then - local playerslist = minetest.get_connected_players() - for i in pairs(playerslist) do - local player = playerslist[i] - local chunkpos = factions.get_chunk_pos(player:getpos()) - local faction = factions.chunks[chunkpos] - player:hud_remove("factionLand") - player:hud_add({ - hud_elem_type = "text", - name = "factionLand", - number = 0xFFFFFF, - position = {x=0.1, y = .98}, - text = faction or "Wilderness", - scale = {x=1, y=1}, - alignment = {x=0, y=0}, - }) - end - end - end -) -minetest.register_on_joinplayer( - function(player) - end -) -minetest.register_on_respawnplayer( - function(player) - local playername = player:get_player_name() - local faction = factions.players[playername] - if not faction then - return false - else - faction = factions.factions[faction] - if not faction.spawn then - return false - else - player:setpos(faction.spawn) - return true - end - end - end -) - - -local default_is_protected = minetest.is_protected -minetest.is_protected = function(pos, player) - local chunkpos = factions.get_chunk_pos(pos) - local faction = factions.chunks[chunkpos] - if not faction then - return default_is_protected(pos, player) - else - faction = factions.factions[faction] - return not faction:has_permission(player, "build") - end -end -