diff --git a/chatcommands.lua b/chatcommands.lua index 0d18c44..e481860 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -87,19 +87,19 @@ factions.register_command = function(cmd_name, cmd, ignore_param_count,or_perm) end -- checks permissions - local player_faction = factions.get_player_faction(player) + local player_faction, facname = factions.get_player_faction(player) if self.infaction and not player_faction then - minetest.chat_send_player(player, "This command is only available within a faction.") + minetest.chat_send_player(player, "This command is only available within a faction") return false end local one_p = false if self.faction_permissions then for i in ipairs(self.faction_permissions) do local perm = self.faction_permissions[i] - if not or_perm and not player_faction:has_permission(player, perm) then - send_error(player, "You do not have the faction permission "..perm) + if not or_perm and not factions.has_permission(facname, player, perm) then + send_error(player, "You do not have the faction permission " .. perm) return false - elseif or_perm and player_faction:has_permission(player, perm) then + elseif or_perm and factions.has_permission(facname, player, perm) then one_p = true break end @@ -196,7 +196,7 @@ factions.register_command ("set_name", { on_success = function(player, faction, pos, parcelpos, args) local factionname = args.strings[1] if factions.can_create_faction(factionname) then - faction:set_name(factionname) + factions.set_name(faction.name, factionname) return true else send_error(player, "Faction cannot be renamed.") @@ -210,18 +210,20 @@ factions.register_command ("claim", { description = "Claim the plot of land you're on.", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - local can_claim = faction:can_claim_parcel(parcelpos) + local p = parcelpos + local can_claim = factions.can_claim_parcel(faction.name, p) + if can_claim then - minetest.chat_send_player(player, "Claming parcel "..parcelpos) - faction:claim_parcel(parcelpos) + minetest.chat_send_player(player, "Claming parcel " .. p) + factions.claim_parcel(faction.name, p) return true else - local parcel_faction = factions.get_parcel_faction(parcelpos) - if parcel_faction and parcel_faction.name == faction.name then - send_error(player, "This parcel already belongs to your faction.") + local parcel_faction = factions.get_parcel_faction(p) + if parcel_faction and parcel_name == faction.name then + send_error(player, "This parcel already belongs to your faction") return false - elseif parcel_faction and parcel_faction.name ~= faction.name then - send_error(player, "This parcel belongs to another faction.") + elseif parcel_faction and parcel_name ~= faction.name then + send_error(player, "This parcel belongs to another faction") return false elseif faction.power <= factions_config.power_per_parcel then send_error(player, "Not enough power.") @@ -244,11 +246,11 @@ factions.register_command("unclaim", { send_error(player, "This parcel does not exist.") return false end - if parcel_faction.name ~= faction.name then + if parcel_name ~= name then send_error(player, "This parcel does not belong to you.") return false else - faction:unclaim_parcel(parcelpos) + factions.unclaim_parcel(faction.name, parcelpos) return true end end @@ -269,7 +271,8 @@ factions.register_command("list", { else tosend = tosend .. " " .. v end - end + end + minetest.chat_send_player(player, tosend, false) return true end @@ -278,8 +281,9 @@ factions.register_command("list", { --show factions mod version factions.register_command("version", { description = "Displays mod version.", + infaction = false, on_success = function(player, faction, pos, parcelpos, args) - minetest.chat_send_player(player, "factions: version " .. misc_mod_data.data.factions_version , false) + minetest.chat_send_player(player, "factions: version 0.8.4", false) end },false) @@ -287,6 +291,7 @@ factions.register_command("version", { factions.register_command("info", { format = {"faction"}, description = "Shows a faction's description.", + infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) minetest.chat_send_player(player, @@ -297,10 +302,10 @@ factions.register_command("info", { },false) factions.register_command("leave", { - description = "Leave your faction.", + description = "Leave your faction", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:remove_player(player) + factions.remove_player(faction.name, player) return true end },false) @@ -308,19 +313,24 @@ factions.register_command("leave", { factions.register_command("kick", { faction_permissions = {"kick"}, format = {"player"}, - description = "Kick a player from your faction.", + description = "Kick a player from your faction", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local victim = args.players[1] - local victim_faction = factions.get_player_faction(victim:get_player_name()) - if victim_faction and victim:get_player_name() ~= faction.leader then -- can't kick da king - faction:remove_player(victim:get_player_name()) + local name = victim:get_player_name() + + local victim_faction, facname = factions.get_player_faction(name) + + local kicker_faction, kicker_facname = factions.get_player_faction(player) + + if victim_faction and kicker_facname == facname and name ~= victim_faction.leader then -- can't kick da king + factions.remove_player(facname, name) return true - elseif not victim_faction then - send_error(player, victim:get_player_name().." is not in your faction.") + elseif not victim_faction or kicker_facname ~= facname then + send_error(player, name .. " is not in your faction") return false else - send_error(player, victim:get_player_name().." cannot be kicked from your faction.") + send_error(player, name .. " cannot be kicked from your faction") return false end end @@ -330,18 +340,21 @@ factions.register_command("kick", { factions.register_command("create", { format = {"string"}, infaction = false, - description = "Create a new faction.", + description = "Create a new faction", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if faction then - send_error(player, "You are already in a faction.") + 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) - factions.start_diplomacy(factionname,new_faction) + local new_faction = factions.new_faction(factionname) + factions.add_player(factionname, player, new_faction.default_leader_rank) + new_faction.leader = player + factions.start_diplomacy(factionname, new_faction) return true else send_error(player, "Faction cannot be created.") @@ -352,30 +365,37 @@ factions.register_command("create", { factions.register_command("join", { format = {"faction"}, - description = "Join a faction.", + description = "Join a faction", infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - local new_faction = args.factions[1] - if new_faction:can_join(player) then - if faction then -- leave old faction - faction:remove_player(player) - end - new_faction:add_player(player) - else - send_error(player, "You cannot join this faction.") + if faction ~= nil or faction then + send_error(player, "You need to leave your current faction in order to join this one.") + return false + end + + local new_faction = args.factions[1] + + if new_faction and factions.can_join(new_faction.name, player) then + factions.add_player(new_faction.name, player) + elseif new_faction then + send_error(player, "You cannot join this faction") + return false + else + send_error(player, "Enter the right faction name.") return false end + return true end },false) factions.register_command("disband", { faction_permissions = {"disband"}, - description = "Disband your faction.", + description = "Disband your faction", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:disband() + factions.disband(faction.name) return true end },false) @@ -387,7 +407,7 @@ factions.register_command("flag", { format = {"string"}, on_success = function(player, faction, pos, parcelpos, args) --"Make your faction invite-only." - --"Allow any player to join your faction." + --"Allow any player to join your " --faction:toggle_join_free(false) local flag_name = args.strings[1] local bool = args.strings[2] @@ -408,7 +428,7 @@ factions.register_command("flag", { return false end if flag_name == "open" then - faction:toggle_join_free(yes) + factions.toggle_join_free(faction.name, yes) elseif flag_name == "monsters" then elseif flag_name == "tax_kick" then elseif flag_name == "animals" then @@ -426,7 +446,7 @@ factions.register_command("description", { description = "Set your faction's description", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:set_description(table.concat(args.strings," ")) + factions.set_description(faction.name, table.concat(args.strings," ")) return true end },true) @@ -434,10 +454,12 @@ factions.register_command("description", { factions.register_command("invite", { format = {"player"}, faction_permissions = {"invite"}, - description = "Invite a player to your faction.", + description = "Invite a player to your faction", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:invite_player(args.players[1]:get_player_name()) + if args.players and args.players[1] then + factions.invite_player(faction.name, args.players[1]:get_player_name()) + end return true end },false) @@ -448,7 +470,7 @@ factions.register_command("uninvite", { description = "Revoke a player's invite.", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:revoke_invite(args.players[1]:get_player_name()) + factions.revoke_invite(faction.name, args.players[1]:get_player_name()) return true end },false) @@ -457,9 +479,9 @@ factions.register_command("delete", { global_privileges = {"faction_admin"}, format = {"faction"}, infaction = false, - description = "Delete a faction.", + description = "Delete a faction", on_success = function(player, faction, pos, parcelpos, args) - args.factions[1]:disband() + factions.disband(args.factions[1].name) return true end },false) @@ -469,7 +491,7 @@ factions.register_command("ranks", { global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) for rank, permissions in pairs(faction.ranks) do - minetest.chat_send_player(player, rank..": "..table.concat(permissions, " ")) + minetest.chat_send_player(player, rank .. ": " .. table.concat(permissions, " ")) end return true end @@ -478,6 +500,7 @@ factions.register_command("ranks", { factions.register_command("rank_privileges", { description = "List available rank privileges.", global_privileges = def_global_privileges, + infaction = false, on_success = function(player, faction, pos, parcelpos, args) minetest.chat_send_player(player, "Privileges available:\n") for i, k in pairs(factions.permissions) do @@ -497,108 +520,131 @@ factions.register_command("set_message_of_the_day", { for i,l in pairs(args.strings) do s = s .. l .. " " end - faction:set_message_of_the_day("Message of the day: " .. s) + factions.set_message_of_the_day(faction.name, "Message of the day: " .. s) return true end },true) if factions_config.faction_diplomacy == true then factions.register_command("send_alliance", { - description = "Send an alliance request to another faction.", + description = "Send an alliance request to another faction", global_privileges = def_global_privileges, format = {"string"}, - faction_permissions = {"alliance"}, + faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) - if factions.factions[args.strings[1]] then - if not factions.factions[args.strings[1]].request_inbox[faction.name] then - if faction.allies[args.strings[1]] then + local target_name = args.strings[1] + local target_faction = factions.factions.get(target_name) + + if target_faction then + if not target_faction.request_inbox[faction.name] then + if faction.allies[target_name] then send_error(player, "You are already allys.") return false end - if faction.enemies[args.strings[1]] then + + if faction.enemies[target_name] then send_error(player, "You need to be neutral in-order to send an alliance request.") return false end - if args.strings[1] == faction.name then - send_error(player, "You can not send an alliance to your own faction.") + + if target_name == faction.name then + send_error(player, "You can not send an alliance to your own faction") return false end - if faction.request_inbox[args.strings[1]] then - send_error(player, "Faction " .. args.strings[1] .. "has already sent a request to you.") + + if faction.request_inbox[target_name] then + send_error(player, "Faction " .. target_name .. "has already sent a request to you.") return false end - factions.factions[args.strings[1]].request_inbox[faction.name] = "alliance" - factions.factions[args.strings[1]]:broadcast("An alliance request from faction " .. faction.name .. " has been sent to you.") - faction:broadcast("An alliance request was sent to faction " .. args.strings[1]) - factions.bulk_save() + + target_faction.request_inbox[faction.name] = "alliance" + factions.broadcast(target_faction.name, "An alliance request from faction " .. faction.name .. " has been sent to you.") + factions.broadcast(faction.name, "An alliance request was sent to faction " .. target_name) + + factions.factions.set(target_name, target_faction) else send_error(player, "You have already sent a request.") end else - send_error(player, args.strings[1] .. " is not a name of a faction.") + send_error(player, target_name .. " is not a name of a faction") end end },false) factions.register_command("send_neutral", { - description = "Send neutral to another faction.", + description = "Send neutral to another faction", global_privileges = def_global_privileges, format = {"string"}, - faction_permissions = {"neutral"}, + faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) - if factions.factions[args.strings[1]] then - if not factions.factions[args.strings[1]].request_inbox[faction.name] then - if faction.allies[args.strings[1]] then - send_error(player, "You are allys.") + local target_name = args.strings[1] + local target_faction = factions.factions.get(target_name) + + if target_faction then + if not target_faction.request_inbox[faction.name] then + if faction.allies[target_name] then + send_error(player, "You are already allys.") return false end - if faction.neutral[args.strings[1]] then - send_error(player, "You are already neutral with this faction.") + + if faction.neutral[target_name] then + send_error(player, "You are already neutral with this faction") return false end - if args.strings[1] == faction.name then - send_error(player, "You can not send a neutral request to your own faction.") + + if target_name == faction.name then + send_error(player, "You can not send a neutral request to your own faction") return false end - if faction.request_inbox[args.strings[1]] then - send_error(player, "Faction " .. args.strings[1] .. "has already sent a request to you.") + + if faction.request_inbox[target_name] then + send_error(player, "Faction " .. target_name .. "has already sent a request to you.") return false end - factions.factions[args.strings[1]].request_inbox[faction.name] = "neutral" - factions.factions[args.strings[1]]:broadcast("A neutral request from faction " .. faction.name .. " has been sent to you.") - faction:broadcast("A neutral request was sent to faction " .. args.strings[1]) - factions.bulk_save() + + target_faction.request_inbox[faction.name] = "neutral" + factions.broadcast(target_faction.name, "A neutral request from faction " .. faction.name .. " has been sent to you.") + factions.broadcast(faction.name, "A neutral request was sent to faction " .. target_name) + + factions.factions.set(target_name, target_faction) else send_error(player, "You have already sent a request.") end else - send_error(player, args.strings[1] .. " is not a name of a faction.") + send_error(player, target_name .. " is not a name of a faction") end end },false) factions.register_command("accept", { - description = "accept an request from another faction.", + description = "accept an request from another faction", global_privileges = def_global_privileges, format = {"string"}, - faction_permissions = {"accept_treaty"}, + faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) - if faction.request_inbox[args.strings[1]] then - if args.strings[1] == faction.name then - send_error(player, "You can not accept an request from own faction.") + local target_name = args.strings[1] + local target_faction = factions.factions.get(target_name) + + if faction.request_inbox[target_name] then + if target_name == faction.name then + send_error(player, "You can not accept an request from own faction") return false end - if faction.request_inbox[args.strings[1]] == "alliance" then - faction:new_alliance(args.strings[1]) - factions.factions[args.strings[1]]:new_alliance(faction.name) + + if faction.request_inbox[target_name] == "alliance" then + factions.new_alliance(faction.name, target_name) + factions.new_alliance(target_name, faction.name) else - if faction.request_inbox[args.strings[1]] == "neutral" then - faction:new_neutral(args.strings[1]) - factions.factions[args.strings[1]]:new_neutral(faction.name) + if faction.request_inbox[target_name] == "neutral" then + factions.new_neutral(faction.name, target_name) + factions.new_neutral(target_name, faction.name) + end end - end - faction.request_inbox[args.strings[1]] = nil - factions.bulk_save() + + faction.request_inbox[target_name] = nil + + factions.factions.set(faction.name, faction) + else send_error(player, "No request was sent to you.") end @@ -606,48 +652,59 @@ if factions_config.faction_diplomacy == true then },false) factions.register_command("refuse", { - description = "refuse an request from another faction.", + description = "refuse an request from another faction", global_privileges = def_global_privileges, format = {"string"}, - faction_permissions = {"refuse_treaty"}, + faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) - if faction.request_inbox[args.strings[1]] then - if args.strings[1] == faction.name then - send_error(player, "You can not refuse an request from your own faction.") + local target_name = args.strings[1] + local target_faction = factions.factions.get(target_name) + + if faction.request_inbox[target_name] then + if target_name == faction.name then + send_error(player, "You can not refuse an request from your own faction") return false end - faction.request_inbox[args.strings[1]] = nil - factions.factions[args.strings[1]]:broadcast("Faction " .. faction.name .. " refuse to be your ally.") - faction:broadcast("Refused an request from faction " .. args.strings[1]) - factions.bulk_save() + + faction.request_inbox[target_name] = nil + factions.broadcast(target_name, "Faction " .. faction.name .. " refuse to be your ally.") + factions.broadcast(faction.name, "Refused an request from faction " .. target_name) + factions.factions.set(faction.name, faction) + else send_error(player, "No request was sent to you.") end end },false) - factions.register_command("delcare_war", { - description = "Delcare war on a faction.", + factions.register_command("declare_war", { + description = "Declare war on a faction", global_privileges = def_global_privileges, format = {"string"}, - faction_permissions = {"declare_war"}, + faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) - if not faction.enemies[args.strings[1]] then - if args.strings[1] == faction.name then - send_error(player, "You can not delcare war on your own faction.") + local target_name = args.strings[1] + local target_faction = factions.factions.get(target_name) + + if not faction.enemies[target_name] then + if target_name == faction.name then + send_error(player, "You can not declare war on your own faction") return false end - if faction.allies[args.strings[1]] then - faction:end_alliance(args.strings[1]) - factions.factions[args.strings[1]]:end_alliance(faction.name) + + if faction.allies[target_name] then + factions.end_alliance(faction.name, target_name) + factions.end_alliance(target_name, faction.name) end - if faction.neutral[args.strings[1]] then - faction:end_neutral(args.strings[1]) - factions.factions[args.strings[1]]:end_neutral(faction.name) + + if faction.neutral[target_name] then + factions.end_neutral(faction.name, target_name) + factions.end_neutral(target_name, faction.name) end - faction:new_enemy(args.strings[1]) - factions.factions[args.strings[1]]:new_enemy(faction.name) - factions.bulk_save() + + factions.new_enemy(faction.name, target_name) + factions.new_enemy(target_name, faction.name) + else send_error(player, "You are already at war.") end @@ -658,18 +715,22 @@ if factions_config.faction_diplomacy == true then description = "Break an alliance.", global_privileges = def_global_privileges, format = {"string"}, - faction_permissions = {"alliance"}, + faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) - if faction.allies[args.strings[1]] then - if args.strings[1] == faction.name then - send_error(player, "You can not break an alliance from your own faction.") + local target_name = args.strings[1] + local target_faction = factions.factions.get(target_name) + + if faction.allies[target_name] then + if target_name == faction.name then + send_error(player, "You can not break an alliance from your own faction") return false end - faction:end_alliance(args.strings[1]) - factions.factions[args.strings[1]]:end_alliance(faction.name) - faction:new_neutral(args.strings[1]) - factions.factions[args.strings[1]]:new_neutral(faction.name) - factions.bulk_save() + + factions.end_alliance(faction.name, target_name) + factions.end_alliance(target_name, faction.name) + factions.new_neutral(faction.name, target_name) + factions.new_neutral(target_name, faction.name) + else send_error(player, "You where not allies to begin with.") end @@ -679,21 +740,24 @@ if factions_config.faction_diplomacy == true then factions.register_command("inbox", { description = "Check your diplomacy request inbox.", global_privileges = def_global_privileges, - faction_permissions = {"accept_treaty","refuse_treaty","alliance","neutral","declare_war"}, + faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) local empty = true - for i,k in pairs(faction.request_inbox) do + + for i, k in pairs(faction.request_inbox) do if k == "alliance" then - minetest.chat_send_player(player,"Alliance request from faction " .. i .. "\n") + minetest.chat_send_player(player, "Alliance request from faction " .. i .. "\n") else - if k == "neutral" then - minetest.chat_send_player(player,"neutral request from faction " .. i .. "\n") - end + if k == "neutral" then + minetest.chat_send_player(player, "neutral request from faction " .. i .. "\n") + end end + empty = false end + if empty then - minetest.chat_send_player(player,"none:") + minetest.chat_send_player(player, "none:") end end },false,true) @@ -703,12 +767,14 @@ if factions_config.faction_diplomacy == true then global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local empty = true - for i,k in pairs(faction.allies) do - minetest.chat_send_player(player,i .. "\n") + + for i, k in pairs(faction.allies) do + minetest.chat_send_player(player, i .. "\n") empty = false end + if empty then - minetest.chat_send_player(player,"none:") + minetest.chat_send_player(player, "none:") end end },false) @@ -718,27 +784,31 @@ if factions_config.faction_diplomacy == true then global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local empty = true - for i,k in pairs(faction.neutral) do - minetest.chat_send_player(player,i .. "\n") + + for i, k in pairs(faction.neutral) do + minetest.chat_send_player(player, i .. "\n") empty = false end + if empty then - minetest.chat_send_player(player,"none:") + minetest.chat_send_player(player, "none:") end end },false) factions.register_command("enemies", { - description = "Shows enemies of your faction.", + description = "Shows enemies of your faction", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local empty = true - for i,k in pairs(faction.enemies) do - minetest.chat_send_player(player,i .. "\n") + + for i, k in pairs(faction.enemies) do + minetest.chat_send_player(player, i .. "\n") empty = false end + if empty then - minetest.chat_send_player(player,"none:") + minetest.chat_send_player(player, "none:") end end },false) @@ -749,13 +819,16 @@ factions.register_command("who", { global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if not faction.players then - minetest.chat_send_player(player, "There is nobody in this faction ("..faction.name..")") + 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..": ") + + minetest.chat_send_player(player, "Players in faction " .. faction.name .. ": ") + for p, rank in pairs(faction.players) do - minetest.chat_send_player(player, p.." ("..rank..")") + minetest.chat_send_player(player, p .." (" .. rank .. ")") end + return true end },false) @@ -765,16 +838,19 @@ local parcel_size_center = factions_config.parcel_size / 2 factions.register_command("show_parcel", { description = "Shows parcel for six seconds.", global_privileges = def_global_privileges, + infaction = false, on_success = function(player, faction, pos, parcelpos, args) local parcel_faction = factions.get_parcel_faction(parcelpos) + if not parcel_faction then send_error(player, "There is no claim here") return false end + local psc = parcel_size_center local fps = factions_config.parcel_size - local ppos = {x = (math.floor(pos.x / fps)*fps)+psc,y = (math.floor(pos.y / fps)*fps)+psc,z = (math.floor(pos.z / fps)*fps)+psc} + local ppos = {x = (math.floor(pos.x / fps) * fps) + psc, y = (math.floor(pos.y / fps) * fps) + psc, z = (math.floor(pos.z / fps) * fps) + psc} minetest.add_entity(ppos, "factions:display") return true end @@ -783,7 +859,7 @@ factions.register_command("show_parcel", { factions.register_command("new_rank", { description = "Add a new rank.", format = {"string"}, - faction_permissions = {"create_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if args.strings[1] then @@ -800,6 +876,8 @@ factions.register_command("new_rank", { if f == r then success = true break + else + success = false end end if not success and _ ~= 1 then @@ -816,7 +894,7 @@ factions.register_command("new_rank", { end return false end - faction:add_rank(rank, args.other) + factions.add_rank(faction.name, rank, args.other) return true end send_error(player, "No rank was given.") @@ -827,7 +905,7 @@ factions.register_command("new_rank", { factions.register_command("replace_privs", { description = "Deletes current permissions and replaces them with the ones given.", format = {"string"}, - faction_permissions = {"edit_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if args.strings[1] then @@ -844,6 +922,8 @@ factions.register_command("replace_privs", { if f == r then success = true break + else + success = false end end if not success and _ ~= 1 then @@ -860,7 +940,7 @@ factions.register_command("replace_privs", { end return false end - faction:replace_privs(rank, args.other) + factions.replace_privs(faction.name, rank, args.other) return true end send_error(player, "No rank was given.") @@ -871,7 +951,7 @@ factions.register_command("replace_privs", { factions.register_command("remove_privs", { description = "Remove permissions from a rank.", format = {"string"}, - faction_permissions = {"edit_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if args.strings[1] then @@ -888,6 +968,8 @@ factions.register_command("remove_privs", { if f == r then success = true break + else + success = false end end if not success and _ ~= 1 then @@ -904,7 +986,7 @@ factions.register_command("remove_privs", { end return false end - faction:remove_privs(rank, args.other) + factions.remove_privs(faction.name, rank, args.other) return true end send_error(player, "No rank was given.") @@ -915,7 +997,7 @@ factions.register_command("remove_privs", { factions.register_command("add_privs", { description = "add permissions to a rank.", format = {"string"}, - faction_permissions = {"edit_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if args.strings[1] then @@ -932,6 +1014,8 @@ factions.register_command("add_privs", { if f == r then success = true break + else + success = false end end if not success and _ ~= 1 then @@ -948,7 +1032,7 @@ factions.register_command("add_privs", { end return false end - faction:add_privs(rank, args.other) + factions.add_privs(faction.name, rank, args.other) return true end send_error(player, "No rank was given.") @@ -959,7 +1043,7 @@ factions.register_command("add_privs", { factions.register_command("set_rank_name", { description = "Change the name of given rank.", format = {"string","string"}, - faction_permissions = {"edit_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local rank = args.strings[1] @@ -972,7 +1056,7 @@ factions.register_command("set_rank_name", { send_error(player, "This rank name was already taken.") return false end - faction:set_rank_name(rank, newrank) + factions.set_rank_name(faction.name, rank, newrank) return true end },false) @@ -980,7 +1064,7 @@ factions.register_command("set_rank_name", { factions.register_command("del_rank", { description = "Replace and delete a rank.", format = {"string", "string"}, - faction_permissions = {"delete_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local rank = args.strings[1] @@ -989,15 +1073,15 @@ factions.register_command("del_rank", { send_error(player, "One of the specified ranks does not exist.") return false end - faction:delete_rank(rank, newrank) + factions.delete_rank(faction.name, rank, newrank) return true end },false) factions.register_command("set_def_rank", { - description = "Change the default rank given to new players and also replace rankless players in this faction.", + description = "Change the default rank given to new players and also replace rankless players in this faction", format = {"string"}, - faction_permissions = {"set_def_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local rank = args.strings[1] @@ -1005,7 +1089,7 @@ factions.register_command("set_def_rank", { send_error(player, "This rank does not exist.") return false end - faction:set_def_rank(rank) + factions.set_def_rank(faction.name, rank) return true end },false) @@ -1013,51 +1097,66 @@ factions.register_command("set_def_rank", { factions.register_command("reset_ranks", { description = "Reset's all of the factions rankings back to the default ones.", format = {}, - faction_permissions = {"reset_ranks"}, + faction_permissions = {"ranks"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:reset_ranks() + factions.reset_ranks(faction.name) return true end },false) factions.register_command("set_spawn", { description = "Set the faction's spawn", - faction_permissions = {"set_spawn"}, + faction_permissions = {"spawn"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:set_spawn(pos) + factions.set_spawn(faction.name, pos) return true end },false) factions.register_command("del_spawn", { description = "Set the faction's spawn to zero", - faction_permissions = {"unset_spawn"}, + faction_permissions = {"spawn"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - faction:set_spawn({x=0,y=0,z=0}) + factions.set_spawn(faction.name, {x = 0, y = 0, z = 0}) return true end },false) if factions_config.spawn_teleport == true then + + local tip = {} + factions.register_command("tp_spawn", { description = "Teleport to the faction's spawn", - faction_permissions = {"spawn"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if player then + if tip[player] then + minetest.chat_send_player(player, "Your already being teleported!") + return false + end minetest.chat_send_player(player, "Teleporting in five seconds.") minetest.after(5, - function(faction,player) - faction:tp_spawn(player) - end,faction,player) + function(faction, player) + factions.tp_spawn(faction.name, player) + tip[player] = nil + end, faction, player) + tip[player] = true return true end return false end },false) + + minetest.register_on_leaveplayer( + function(player) + local name = player:get_player_name() + tip[name] = nil + end +) end factions.register_command("where", { @@ -1065,9 +1164,9 @@ factions.register_command("where", { infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - local parcel_faction = factions.get_parcel_faction(parcelpos) - local place_name = (parcel_faction and parcel_faction.name) or "Wilderness" - minetest.chat_send_player(player, "You are standing on parcel "..parcelpos..", part of "..place_name) + local parcel_faction, facname = factions.get_parcel_faction(parcelpos) + local place_name = facname or "Wilderness" + minetest.chat_send_player(player, "You are standing on parcel " .. parcelpos .. ", part of " .. place_name) return true end },false) @@ -1088,8 +1187,7 @@ factions.register_command("get_spawn", { on_success = function(player, faction, pos, parcelpos, args) local spawn = faction.spawn if spawn then - local spawn = {spawn.x, spawn.y, spawn.z} - minetest.chat_send_player(player, "Spawn is at ("..table.concat(spawn, ", ")..")") + minetest.chat_send_player(player, "Spawn is at (" .. spawn.x .. ", " .. spawn.y .. ", " .. spawn.z .. ")") return true else minetest.chat_send_player(player, "Your faction has no spawn set.") @@ -1106,8 +1204,23 @@ factions.register_command("promote", { on_success = function(player, faction, pos, parcelpos, args) local rank = args.strings[1] if faction.ranks[rank] then - faction:promote(args.players[1]:get_player_name(), rank) - return true + local player_to_promote = args.players[1] + local name = player_to_promote:get_player_name() + + local player_faction, facname = factions.get_player_faction(name) + + local promoter_faction, promoter_facname = factions.get_player_faction(player) + + if player_faction and promoter_facname == facname then + factions.promote(faction.name, name, rank) + return true + elseif not player_faction or promoter_facname ~= facname then + send_error(player, name .. " is not in your faction") + return false + else + send_error(player, name .. " cannot be promoted from your faction") + return false + end else send_error(player, "The specified rank does not exist.") return false @@ -1121,29 +1234,17 @@ factions.register_command("power", { on_success = function(player, faction, pos, parcelpos, args) local pps = 0 if factions_config.enable_power_per_player then - local t = faction.onlineplayers + if factions.onlineplayers[faction.name] == nil then + factions.onlineplayers[faction.name] = {} + end + local t = factions.onlineplayers[faction.name] local count = 0 for _ in pairs(t) do count = count + 1 end pps = factions_config.power_per_player * count else - fpps = factions_config.power_per_tick + pps = factions_config.power_per_tick end - minetest.chat_send_player(player, "Power: "..faction.power.." / "..faction.maxpower - faction.usedpower.."\nPower per "..factions_config.tick_time.." seconds: "..pps.."\nPower per death: -"..factions_config.power_per_death) - return true - end -},false) - -factions.register_command("convert", { - description = "Load factions in the old format", - infaction = false, - global_privileges = {"faction_admin"}, - format = {"string"}, - on_success = function(player, faction, pos, parcelpos, args) - if factions.convert(args.strings[1]) then - minetest.chat_send_player(player, "Factions successfully converted.") - else - minetest.chat_send_player(player, "Error.") - end + minetest.chat_send_player(player, "Power: " .. faction.power .. " / " .. faction.maxpower - faction.usedpower .. "\nPower per " .. factions_config.tick_time .. " seconds: " .. pps .. "\nPower per death: -" .. factions_config.power_per_death) return true end },false) @@ -1158,7 +1259,7 @@ factions.register_command("free", { send_error(player, "No claim at this position") return false else - parcel_faction:unclaim_parcel(parcelpos) + factions.unclaim_parcel(parcel_faction.name, parcelpos) return true end end @@ -1170,7 +1271,7 @@ factions.register_command("chat", { global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local msg = table.concat(args.strings, " ") - faction:broadcast(msg, player) + factions.broadcast(faction.name, msg, player) end },true) @@ -1189,12 +1290,12 @@ factions.register_command("which", { global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local playername = args.strings[1] - local faction = factions.get_player_faction(playername) - if not faction then - send_error(player, "Player "..playername.." does not belong to any faction") + local faction1, facname = factions.get_player_faction(playername) + if not faction1 then + send_error(player, "Player " .. playername .. " does not belong to any faction") return false else - minetest.chat_send_player(player, "player "..playername.." belongs to faction "..faction.name) + minetest.chat_send_player(player, "player " .. playername .. " belongs to faction " .. faction1.name) return true end end @@ -1207,13 +1308,13 @@ factions.register_command("set_leader", { format = {"faction", "player"}, on_success = function(player, faction, pos, parcelpos, args) local playername = args.players[1]:get_player_name() - local playerfaction = factions.get_player_faction(playername) + local playerfaction, facname = factions.get_player_faction(playername) local targetfaction = args.factions[1] - if playerfaction.name ~= targetfaction.name then - send_error(player, "Player "..playername.." is not in faction "..targetfaction.name..".") + if playername ~= targetname then + send_error(player, "Player " .. playername .. " is not in faction " .. targetname .. ".") return false end - targetfaction:set_leader(playername) + factions.set_leader(targetfaction.name, playername) return true end },false) @@ -1227,10 +1328,13 @@ factions.register_command("set_admin", { if not args.factions[1].is_admin then minetest.chat_send_player(player,"faction " .. args.factions[1].name .. " is now an admin faction it can not be disband.") else - minetest.chat_send_player(player,"faction " .. args.factions[1].name .. " is already an admin faction.") + minetest.chat_send_player(player,"faction " .. args.factions[1].name .. " is already an admin ") end + args.factions[1].is_admin = true - factions.bulk_save() + + factions.factions.set(args.factions[1].name, args.factions[1]) + return true end },false) @@ -1247,7 +1351,9 @@ factions.register_command("remove_admin", { minetest.chat_send_player(player,"faction " .. args.factions[1].name .. " is not an admin faction to begin with.") end args.factions[1].is_admin = false - factions.bulk_save() + + factions.factions.set(args.factions[1].name, args.factions[1]) + return true end },false) @@ -1259,6 +1365,9 @@ factions.register_command("reset_power", { format = {"faction"}, on_success = function(player, faction, pos, parcelpos, args) args.factions[1].power = 0 + + factions.factions.set(args.factions[1].name, args.factions[1]) + return true end },false) @@ -1269,8 +1378,8 @@ factions.register_command("obliterate", { infaction = false, global_privileges = {"faction_admin"}, on_success = function(player, faction, pos, parcelpos, args) - for _, f in pairs(factions.factions) do - f:disband("obliterated") + for i, facname in pairs(factions.get_faction_list()) do + factions.disband(facname, "obliterated") end return true end @@ -1284,7 +1393,7 @@ factions.register_command("get_factions_spawn", { on_success = function(player, faction, pos, parcelpos, args) local spawn = args.factions[1].spawn if spawn then - minetest.chat_send_player(player, spawn.x..","..spawn.y..","..spawn.z) + minetest.chat_send_player(player, spawn.x .. "," .. spawn.y .. "," .. spawn.z) return true else send_error(player, "Faction has no spawn set.") @@ -1294,7 +1403,7 @@ factions.register_command("get_factions_spawn", { },false) factions.register_command("whoin", { - description = "Get all members of a faction.", + description = "Get all members of a faction", infaction = false, global_privileges = def_global_privileges, format = {"faction"}, @@ -1309,7 +1418,7 @@ factions.register_command("whoin", { },false) factions.register_command("stats", { - description = "Get stats of a faction.", + description = "Get stats of a faction", infaction = false, global_privileges = def_global_privileges, format = {"faction"}, @@ -1317,14 +1426,17 @@ factions.register_command("stats", { local f = args.factions[1] local pps = 0 if factions_config.enable_power_per_player then - local t = f.onlineplayers + if factions.onlineplayers[faction.name] == nil then + factions.onlineplayers[faction.name] = {} + end + local t = factions.onlineplayers[faction.name] local count = 0 for _ in pairs(t) do count = count + 1 end pps = factions_config.power_per_player * count else - fpps = factions_config.power_per_tick + pps = factions_config.power_per_tick end - minetest.chat_send_player(player, "Power: "..f.power.." / "..f.maxpower - f.usedpower.."\nPower per "..factions_config.tick_time.." seconds: "..pps.."\nPower per death: -"..factions_config.power_per_death) + minetest.chat_send_player(player, "Power: " .. f.power .. " / " .. f.maxpower - f.usedpower .. "\nPower per " .. factions_config.tick_time .. " seconds: " .. pps .. "\nPower per death: -" .. factions_config.power_per_death) return true end },false) @@ -1341,8 +1453,8 @@ factions.register_command("seen", { local minutes = math.floor(time / 60) local hours = math.floor(minutes / 60) local days = math.floor(hours / 24) - minetest.chat_send_player(player, "Last seen "..days.." day(s), ".. - hours % 24 .." hour(s), "..minutes % 60 .." minutes, "..time % 60 .." second(s) ago.") + minetest.chat_send_player(player, "Last seen " .. days .. " day(s), " .. + hours % 24 .. " hour(s), " .. minutes % 60 .. " minutes, " .. time % 60 .. " second(s) ago.") return true end },false) @@ -1361,12 +1473,12 @@ factions_chat.cmdhandler = function (playername,parameter) local player = minetest.env:get_player_by_name(playername) local params = parameter:split(" ") - local player_faction = factions.get_player_faction(playername) + local player_faction, facname = factions.get_player_faction(playername) if parameter == nil or parameter == "" then if player_faction then - minetest.chat_send_player(playername, "You are in faction "..player_faction.name..". Type /f help for a list of commands.") + minetest.chat_send_player(playername, "You are in faction "..player_name..". Type /f help for a list of commands.") else minetest.chat_send_player(playername, "You are part of no faction") end @@ -1429,4 +1541,3 @@ function factions_chat.show_help(playername) end init_commands() - diff --git a/convert.lua b/convert.lua new file mode 100644 index 0000000..25f53f2 --- /dev/null +++ b/convert.lua @@ -0,0 +1,45 @@ +function ip_convert() + local path = minetest.get_worldpath() .. "/factions_iplist.txt" + local file, error = io.open(path, "r") + + if file ~= nil then + local raw_data = file:read("*a") + local ips = minetest.deserialize(raw_data) + file:close() + + for i, k in pairs(ips) do + factions.player_ips.set(i, k) + end + + os.rename(path, minetest.get_worldpath() .. "/factions_iplist_old.txt") + end +end + +function faction_convert() + local path = minetest.get_worldpath() .. "/factions.conf" + local file, error = io.open(path, "r") + + if file ~= nil then + local raw_data = file:read("*a") + local tabledata = minetest.deserialize(raw_data) + file:close() + + if tabledata then + for facname, faction in pairs(tabledata) do + factions.factions.set(facname, faction) + + for player, rank in pairs(faction.players) do + factions.players.set(player, facname) + end + + for parcelpos, val in pairs(faction.land) do + factions.parcels.set(parcelpos, facname) + end + end + os.rename(path, minetest.get_worldpath() .. "/factions_old.conf") + end + end +end + +ip_convert() +faction_convert() diff --git a/depends.txt b/depends.txt index ff6f9a8..5867cba 100644 --- a/depends.txt +++ b/depends.txt @@ -1,2 +1,4 @@ default? -doors? \ No newline at end of file +doors? +xdecor? +colddb diff --git a/factions.lua b/factions.lua index bb34901..5f159d9 100644 --- a/factions.lua +++ b/factions.lua @@ -1,14 +1,15 @@ ---read some basic information -local factions_worldid = minetest.get_worldpath() - --! @class factions --! @brief main class for factions factions = {} ---! @brief runtime data -factions.factions = {} -factions.parcels = {} -factions.players = {} +-- Create cold databases. +factions.factions = colddb.Colddb("factions/factions") +factions.parcels = colddb.Colddb("factions/parcels") +factions.players = colddb.Colddb("factions/players") +factions.player_ips = colddb.Colddb("factions/ips") + +-- Memory only storage. +factions.onlineplayers = {} --------------------- --! @brief returns whether a faction can be created or not (allows for implementation of blacklists and the like) @@ -16,7 +17,7 @@ factions.players = {} factions.can_create_faction = function(name) if #name > factions_config.faction_name_max_length then return false - elseif factions.factions[name] then + elseif factions.factions.get(name) ~= nil then return false else return true @@ -24,21 +25,16 @@ factions.can_create_faction = function(name) end -factions.Faction = { -} - util = { coords3D_string = function(coords) return coords.x..", "..coords.y..", "..coords.z end } -factions.Faction.__index = factions.Faction - -starting_ranks = {["leader"] = {"build","door","container","name","description","motd","invite","kick" - ,"player_title","set_spawn","unset_spawn","with_draw","territory","claim","access","disband","flags","create_ranks","edit_ranks","delete_ranks","set_def_ranks","reset_ranks","promote"}, - ["moderator"] = {"claim","door","build","set_spawn","invite","kick","promote"}, - ["member"] = {"build","container","door"} +starting_ranks = {["leader"] = {"build", "door", "container", "name", "description", "motd", "invite", "kick" + , "player_title", "spawn", "with_draw", "territory", "claim", "access", "disband", "flags", "ranks", "promote"}, + ["moderator"] = {"claim", "door", "build", "spawn", "invite", "kick", "promote"}, + ["member"] = {"build", "container", "door"} } -- Faction permissions: @@ -53,76 +49,43 @@ starting_ranks = {["leader"] = {"build","door","container","name","description", -- invite: (un)invite players to join the faction -- kick: kick players off the faction -- player_title: set player titles --- set_spawn: set the faction's spawn --- unset_spawn: delete the faction's spawn +-- spawn: set the faction's spawn -- with_draw: withdraw money from the faction's bank --- spawn: be able to teleport to the faction's spawn -- territory: claim or unclaim territory -- claim: (un)claim parcels of land -- access: manage access to territory and parcels of land to players or factions -- disband: disband the faction -- flags: manage faction's flags --- create_ranks: create new ranks --- edit_ranks: edit rank name and permissions --- delete_ranks: delete ranks --- set_def_ranks: set the default rank given to new players --- reset_ranks: reset the ranks back to the default ones +-- ranks: create, edit, and delete ranks -- promote: set a player's rank --- declare_war: be able to declare war with another faction --- neutral: be able to send a neutral request to another faction --- alliance: be able to send a alliance request to another faction and break alliance treaties too --- accept_treaty: be able to accept a treaty request from another faction --- refuse_treaty: be able to refuse a treaty request from another faction +-- diplomacy: be able to control the faction's diplomacy -factions.permissions = {"build","pain_build","door","container","name","description","motd","invite","kick" - ,"player_title","set_spawn","unset_spawn","with_draw","territory","claim","access","disband","flags","create_ranks","edit_ranks","delete_ranks","set_def_ranks","reset_ranks","promote"} -factions.permissions_desc = {"dig and place nodes","dig and place nodes but take damage doing so","open/close or dig","be able to use containers like chest","set the faction's name" - ,"Set the faction description","set the faction's message of the day","(un)invite players to join the faction","kick players off the faction","set player titles","set the faction's spawn" - ,"delete the faction's spawn","withdraw money from the faction's bank","claim or unclaim territory","(un)claim parcels of land","manage access to territory and parcels of land to players or factions" - ,"disband the faction","manage faction's flags","create new ranks","edit rank permissions","delete ranks","set the default rank given to new players","reset the ranks back to the default ones","set a player's rank"} +factions.permissions = {"build", "pain_build", "door", "container", "name", "description", "motd", "invite", "kick" + , "player_title", "spawn", "with_draw", "territory", "claim", "access", "disband", "flags", "ranks", "promote"} +factions.permissions_desc = {"dig and place nodes", "dig and place nodes but take damage doing so", "open/close or dig faction doors", "be able to use containers like chest", "set the faction's name" + , "Set the faction description", "set the faction's message of the day", "(un)invite players to join the faction", "kick players off the faction", "set player titles", "set the faction's spawn" + , "withdraw money from the faction's bank", "claim or unclaim territory", "(un)claim parcels of land", "manage access to territory and parcels of land to players or factions" + , "disband the faction", "manage faction's flags", "create, edit, and delete ranks", "set a player's rank"} -- open: can the faction be joined without an invite? -- monsters: can monsters spawn on your land? -- tax_kick: will players be kicked for not paying tax? -- animals: can animals spawn on your land? -factions.flags = {"open","monsters","tax_kick","animals"} -factions.flags_desc = {"can the faction be joined without an invite?","can monsters spawn on your land?(unused)","will players be kicked for not paying tax?(unused)","can animals spawn on your land?(unused)"} +factions.flags = {"open", "monsters", "tax_kick", "animals"} +factions.flags_desc = {"can the faction be joined without an invite?", "can monsters spawn on your land?(unused)", "will players be kicked for not paying tax?(unused)", "can animals spawn on your land?(unused)"} if factions_config.faction_diplomacy == true then - table.insert(factions.permissions,"declare_war") - table.insert(factions.permissions,"neutral") - table.insert(factions.permissions,"alliance") - table.insert(factions.permissions,"accept_treaty") - table.insert(factions.permissions,"refuse_treaty") + table.insert(factions.permissions, "diplomacy") - table.insert(factions.permissions_desc,"be able to declare war with another faction") - table.insert(factions.permissions_desc,"be able to send a neutral request to another faction") - table.insert(factions.permissions_desc,"be able to send a alliance request to another faction and break alliance treaties too") - table.insert(factions.permissions_desc,"be able to accept a treaty request from another faction") - table.insert(factions.permissions_desc,"be able to refuse a treaty request from another faction") + table.insert(factions.permissions_desc, "be able to control the faction's diplomacy") local lt = starting_ranks["leader"] - table.insert(lt,"declare_war") - table.insert(lt,"neutral") - table.insert(lt,"alliance") - table.insert(lt,"accept_treaty") - table.insert(lt,"refuse_treaty") + table.insert(lt, "diplomacy") starting_ranks["leader"] = lt end -if factions_config.spawn_teleport == true then - table.insert(factions.permissions,"spawn") - - table.insert(factions.permissions_desc,"be able to teleport to the faction's spawn") - - table.insert(starting_ranks["leader"],"spawn") - table.insert(starting_ranks["moderator"],"spawn") - table.insert(starting_ranks["member"],"spawn") - -end - -function factions.Faction:new(faction) - faction = { +function factions.new() + return { name = "", --! @brief power of a faction (needed for parcel claiming) power = factions_config.power, @@ -132,10 +95,6 @@ function factions.Faction:new(faction) usedpower = 0., --! @brief list of player names players = {}, - --! @brief list of player names online - onlineplayers = {}, - --! @brief list of player names offline - offlineplayers = {}, --! @brief table of ranks/permissions ranks = starting_ranks, --! @brief name of the leader @@ -168,355 +127,450 @@ function factions.Faction:new(faction) join_free = false, --! @brief gives certain privileges is_admin = false, - --! @brief if a player on the faction has a nil rank - rankless = false, --! @brief last time anyone logged on last_logon = os.time(), --! @brief how long this has been without parcels no_parcel = os.time(), - } or faction - setmetatable(faction, self) - return faction + } end --! @brief create a new empty faction -function factions.new_faction(name,do_not_save) - local faction = factions.Faction:new(nil) +function factions.new_faction(name) + local faction = factions.new() + faction.name = name - factions.factions[name] = faction - faction:on_create() + factions.factions.set(name, faction) + factions.on_create(name) minetest.after(1, - function(f) - f:on_no_parcel() - end,faction) - if not do_not_save then - factions.bulk_save() - end - return faction + function(name) + factions.on_no_parcel(name) + end, name) + + factions.onlineplayers[name] = {} + + return faction end -function factions.start_diplomacy(name,faction) - for i,fac in pairs(factions.factions) do +function factions.start_diplomacy(name, faction) + for l, i in pairs(factions.get_faction_list()) do + local fac = factions.factions.get(i) if i ~= name and not (faction.neutral[i] or faction.allies[i] or faction.enemies[i]) then - faction:new_enemy(i) - fac:new_enemy(name) + if factions_config.faction_diplomacy == true then + factions.new_neutral(name, i) + factions.new_neutral(i, name) + else + factions.new_enemy(name, i) + factions.new_enemy(i, name) + end end end end -function factions.Faction.set_name(self, name) - local oldname = self.name - local oldfaction = factions.factions[oldname] - self.name = name - for i,fac in pairs(factions.factions) do - if i ~= oldname then +function factions.set_name(oldname, name) + local faction = factions.factions.get(oldname) + faction.name = name + + for i, v in pairs(factions.get_faction_list()) do + if v ~= oldname then + local fac = factions.factions.get(v) + if fac.neutral[oldname] then fac.neutral[oldname] = nil fac.neutral[name] = true end + if fac.allies[oldname] then fac.allies[oldname] = nil fac.allies[name] = true end + if fac.enemies[oldname] then fac.enemies[oldname] = nil fac.enemies[name] = true end + + if fac.request_inbox[oldname] then + local value = fac.request_inbox[oldname] + fac.request_inbox[oldname] = nil + fac.request_inbox[name] = value + end + + factions.factions.set(v, fac) end end - for parcel in pairs(self.land) do - factions.parcels[parcel] = self.name + + for parcel in pairs(faction.land) do + factions.parcels.set(parcel, name) end - for playername in pairs(self.players) do - factions.players[playername] = self.name + + for playername in pairs(faction.players) do + factions.players.set(playername, name) end - factions.factions[oldname] = nil - factions.factions[name] = oldfaction - factions.factions[name].name = name - for playername in pairs(self.onlineplayers) do - updateFactionName(playername,name) + + for playername in pairs(factions.onlineplayers[oldname]) do + updateFactionName(playername, name) end - self:on_set_name(oldname) - factions.bulk_save() + + factions.onlineplayers[name] = factions.onlineplayers[oldname] + factions.onlineplayers[oldname] = nil + + factions.factions.remove(oldname) + + factions.factions.set(name, faction) + factions.on_set_name(name, oldname) + end -function factions.Faction.increase_power(self, power) - self.power = self.power + power - if self.power > self.maxpower - self.usedpower then - self.power = self.maxpower - self.usedpower +function factions.increase_power(name, power) + local faction = factions.factions.get(name) + + faction.power = faction.power + power + + if faction.power > faction.maxpower - faction.usedpower then + faction.power = faction.maxpower - faction.usedpower end - for i in pairs(self.onlineplayers) do - updateHudPower(minetest.get_player_by_name(i),self) + + for i in pairs(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) end - factions.bulk_save() + + factions.factions.set(name, faction) end -function factions.Faction.decrease_power(self, power) - self.power = self.power - power - for i in pairs(self.onlineplayers) do - updateHudPower(minetest.get_player_by_name(i),self) +function factions.decrease_power(name, power) + local faction = factions.factions.get(name) + + faction.power = faction.power - power + + for i in pairs(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) end - factions.bulk_save() + + factions.factions.set(name, faction) end -function factions.Faction.increase_maxpower(self, power) - self.maxpower = self.maxpower + power - for i in pairs(self.onlineplayers) do - updateHudPower(minetest.get_player_by_name(i),self) +function factions.increase_maxpower(name, power) + local faction = factions.factions.get(name) + + faction.maxpower = faction.maxpower + power + + for i in pairs(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) end - factions.bulk_save() + + factions.factions.set(name, faction) end -function factions.Faction.decrease_maxpower(self, power) - self.maxpower = self.maxpower - power - if self.maxpower < 0. then -- should not happen - self.maxpower = 0. +function factions.decrease_maxpower(name, power) + local faction = factions.factions.get(name) + + faction.maxpower = faction.maxpower - power + + if faction.maxpower < 0. then -- should not happen + faction.maxpower = 0. end - for i in pairs(self.onlineplayers) do - updateHudPower(minetest.get_player_by_name(i),self) + + for i in pairs(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) end + + factions.factions.set(name, faction) end -function factions.Faction.increase_usedpower(self, power) - self.usedpower = self.usedpower + power - for i in pairs(self.onlineplayers) do - updateHudPower(minetest.get_player_by_name(i),self) +function factions.increase_usedpower(name, power) + local faction = factions.factions.get(name) + + faction.usedpower = faction.usedpower + power + + for i in pairs(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) end + + factions.factions.set(name, faction) end -function factions.Faction.decrease_usedpower(self, power) - self.usedpower = self.usedpower - power - if self.usedpower < 0. then - self.usedpower = 0. +function factions.decrease_usedpower(name, power) + local faction = factions.factions.get(name) + + faction.usedpower = faction.usedpower - power + if faction.usedpower < 0. then + faction.usedpower = 0. end - for i in pairs(self.onlineplayers) do - updateHudPower(minetest.get_player_by_name(i),self) - end -end --- power-per-players only. -function factions.Faction.check_power(self) - if factions_config.enable_power_per_player then - for player,unused in pairs(self.players) do - local ip = factions_ip.player_ips[player] - local notsame = true - for i,k in pairs(self.players) do - local other_ip = factions_ip.player_ips[i] - if other_ip == ip then - notsame = false - break - end - end - if notsame then - self:increase_maxpower(factions_config.powermax_per_player) - end - end + for i in pairs(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) end + + factions.factions.set(name, faction) end -function factions.Faction.count_land(self) +function factions.count_land(name) local count = 0. - for k, v in pairs(self.land) do + for k, v in pairs(factions.factions.get(name).land) do count = count + 1 end return count end minetest.register_on_prejoinplayer(function(name, ip) - factions_ip.player_ips[name] = ip + factions.player_ips.set(name, ip) end) -function factions.Faction.add_player(self, player, rank) - self:on_player_join(player) +function factions.add_player(name, player, rank) + local faction = factions.factions.get(name) + + if factions.onlineplayers[name] == nil then + factions.onlineplayers[name] = {} + end + + factions.onlineplayers[name][player] = true + + factions.on_player_join(name, player) + if factions_config.enable_power_per_player then - local ip = factions_ip.player_ips[player] + local ip = factions.player_ips.get(player) local notsame = true - for i,k in pairs(self.players) do - local other_ip = factions_ip.player_ips[i] + for i, k in pairs(faction.players) do + local other_ip = factions.player_ips.get(i) if other_ip == ip then notsame = false break end end if notsame then - self:increase_maxpower(factions_config.powermax_per_player) + factions.increase_maxpower(name, factions_config.powermax_per_player) end end - self.players[player] = rank or self.default_rank - factions.players[player] = self.name - self.invited_players[player] = nil + + faction.players[player] = rank or faction.default_rank + factions.players.set(player, name) + faction.invited_players[player] = nil local pdata = minetest.get_player_by_name(player) local ipc = pdata:is_player_connected(player) if ipc then - createHudFactionName(pdata,self.name) - createHudPower(pdata,self) - self.offlineplayers[player] = nil - self.onlineplayers[player] = 1 - else - self.offlineplayers[player] = 1 - self.onlineplayers[player] = nil + createHudFactionName(pdata, name) + createHudPower(pdata, faction) end - factions.bulk_save() + + factions.factions.set(name, faction) end -function factions.Faction.check_players_in_faction(self) - for i,k in pairs(self.players) do +function factions.check_players_in_faction(name) + for i, k in pairs(factions.factions.get(name).players) do return true end - self:disband("Zero players on faction.") + factions.disband(name, "Zero players on faction.") return false end -function factions.Faction.remove_player(self, player) - self.players[player] = nil - factions.players[player] = nil - self:on_player_leave(player) - self:check_players_in_faction(self) +function factions.remove_player(name, player) + local faction = factions.factions.get(name) + + if factions.onlineplayers[name] == nil then + factions.onlineplayers[name] = {} + end + + factions.onlineplayers[name][player] = nil + + faction.players[player] = nil + + factions.factions.set(name, faction) + + factions.players.remove(player) + factions.on_player_leave(name, player) + if factions_config.enable_power_per_player then - local ip = factions_ip.player_ips[player] + local ip = factions.player_ips.get(player) local notsame = true - for i,k in pairs(self.players) do - local other_ip = factions_ip.player_ips[i] + for i,k in pairs(faction.players) do + local other_ip = factions.player_ips.get(i) if other_ip == ip then notsame = false break end end if notsame then - self:decrease_maxpower(factions_config.powermax_per_player) + factions.decrease_maxpower(name, factions_config.powermax_per_player) end end + local pdata = minetest.get_player_by_name(player) local ipc = pdata:is_player_connected(player) + if ipc then removeHud(pdata,"factionName") removeHud(pdata,"powerWatch") end - self.offlineplayers[player] = nil - self.onlineplayers[player] = nil - factions.bulk_save() + + factions.check_players_in_faction(name) end +local parcel_size = factions_config.parcel_size + --! @param parcelpos position of the wanted parcel --! @return whether this faction can claim a parcelpos -function factions.Faction.can_claim_parcel(self, parcelpos) - local fac = factions.parcels[parcelpos] - if fac then - if factions.factions[fac].power < 0. and self.power >= factions_config.power_per_parcel and not self.allies[factions.factions[fac].name] and not self.neutral[factions.factions[fac].name] then +function factions.can_claim_parcel(name, parcelpos) + local fn = factions.parcels.get(parcelpos) + + if fn == nil then + return true + end + + local faction = factions.factions.get(name) + + if fn then + local fac = factions.factions.get(fn) + + if fac.power < 0. and faction.power >= factions_config.power_per_parcel and not faction.allies[fn] and not faction.neutral[fn] then return true else return false end - elseif self.power < factions_config.power_per_parcel then + elseif faction.power < factions_config.power_per_parcel then return false end + return true end --! @brief claim a parcel, update power and update global parcels table -function factions.Faction.claim_parcel(self, parcelpos) +function factions.claim_parcel(name, parcelpos) -- check if claiming over other faction's territory - local otherfac = factions.parcels[parcelpos] + local otherfac = factions.parcels.get(parcelpos) if otherfac then - local faction = factions.factions[otherfac] - faction:unclaim_parcel(parcelpos) - faction:parcelless_check() + factions.unclaim_parcel(otherfac, parcelpos) + factions.parcelless_check(otherfac) end - factions.parcels[parcelpos] = self.name - self.land[parcelpos] = true - self:decrease_power(factions_config.power_per_parcel) - self:increase_usedpower(factions_config.power_per_parcel) - self:on_claim_parcel(parcelpos) - self:parcelless_check() - factions.bulk_save() + factions.parcels.set(parcelpos, name) + + local faction = factions.factions.get(name) + + faction.land[parcelpos] = true + + factions.factions.set(name, faction) + + factions.decrease_power(name, factions_config.power_per_parcel) + factions.increase_usedpower(name, factions_config.power_per_parcel) + factions.on_claim_parcel(name, parcelpos) + factions.parcelless_check(name) end --! @brief claim a parcel, update power and update global parcels table -function factions.Faction.unclaim_parcel(self, parcelpos) - factions.parcels[parcelpos] = nil - self.land[parcelpos] = nil - self:increase_power(factions_config.power_per_parcel) - self:decrease_usedpower(factions_config.power_per_parcel) - self:on_unclaim_parcel(parcelpos) - self:parcelless_check() - factions.bulk_save() +function factions.unclaim_parcel(name, parcelpos) + factions.parcels.remove(parcelpos) + + local faction = factions.factions.get(name) + + faction.land[parcelpos] = nil + + factions.factions.set(name, faction) + + factions.increase_power(name, factions_config.power_per_parcel) + factions.decrease_usedpower(name, factions_config.power_per_parcel) + factions.on_unclaim_parcel(name, parcelpos) + factions.parcelless_check(name) end -function factions.Faction.parcelless_check(self) - if self.land then +function factions.parcelless_check(name) + local faction = factions.factions.get(name) + + if faction.land then local count = 0 - for index, value in pairs(self.land) do + for index, value in pairs(faction.land) do count = count + 1 break end if count > 0 then - if self.no_parcel ~= -1 then - self:broadcast("Faction " .. self.name .. " will not be disbanded because it now has parcels.") + if faction.no_parcel ~= -1 then + factions.broadcast(name, "Faction " .. name .. " will not be disbanded because it now has parcels.") end - self.no_parcel = -1 + faction.no_parcel = -1 else - self.no_parcel = os.time() - self:on_no_parcel() + faction.no_parcel = os.time() + factions.on_no_parcel(name) end + factions.factions.set(name, faction) end end --! @brief disband faction, updates global players and parcels table -function factions.Faction.disband(self, reason) - if not self.is_admin then - for i,v in pairs(factions.factions) do - if v.name ~= self.name then - if v.enemies[self.name] then - v:end_enemy(self.name) +function factions.disband(name, reason) + local faction = factions.factions.get(name) + + if not faction.is_admin then + for i, v in pairs(factions.get_faction_list()) do + local fac = factions.factions.get(v) + if fac ~= nil and fac.name ~= name then + if fac.enemies[name] then + factions.end_enemy(fac.name, name) end - if v.allies[self.name] then - v:end_alliance(self.name) + + if fac.allies[name] then + factions.end_alliance(fac.name, name) end - if v.neutral[self.name] then - v:end_neutral(self.name) + + if fac.neutral[name] then + factions.end_neutral(fac.name, name) + end + + if fac.request_inbox[name] then + fac.request_inbox[name] = nil end end + factions.factions.set(v, fac) end - for k, _ in pairs(self.players) do -- remove players affiliation - factions.players[k] = nil + + for k, _ in pairs(faction.players) do -- remove players affiliation + factions.players.remove(k) end - for k, v in pairs(self.land) do -- remove parcel claims - factions.parcels[k] = nil + + for k, v in pairs(faction.land) do -- remove parcel claims + factions.parcels.remove(k) end - self:on_disband(reason) - for i,l in pairs(self.onlineplayers) do - removeHud(i,"factionName") - removeHud(i,"powerWatch") + + factions.on_disband(name, reason) + + for i, l in pairs(factions.onlineplayers[name]) do + removeHud(i, "factionName") + removeHud(i, "powerWatch") end - factions.factions[self.name] = nil - factions.bulk_save() + + factions.onlineplayers[name] = nil + + factions.factions.remove(name) end end --! @brief change the faction leader -function factions.Faction.set_leader(self, player) - if self.leader then - self.players[self.leader] = self.default_rank +function factions.set_leader(name, player) + local faction = factions.factions.get(name) + + if faction.leader then + faction.players[faction.leader] = faction.default_rank end - self.leader = player - self.players[player] = self.default_leader_rank - self:on_new_leader() - factions.bulk_save() + faction.leader = player + faction.players[player] = faction.default_leader_rank + factions.on_new_leader() + + factions.factions.set(name, faction) end -function factions.Faction.set_message_of_the_day(self,text) - self.message_of_the_day = text - factions.bulk_save() +function factions.set_message_of_the_day(name, text) + local faction = factions.factions.get(name) + faction.message_of_the_day = text + factions.factions.set(name, faction) 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] +function factions.has_permission(name, player, permission) + local faction = factions.factions.get(name) + + local p = faction.players[player] if not p then return false end - local perms = self.ranks[p] + local perms = faction.ranks[p] if perms then for i in ipairs(perms) do if perms[i] == permission then @@ -524,464 +578,515 @@ function factions.Faction.has_permission(self, player, permission) end end else - if not self.rankless then - self.rankless = true - factions.bulk_save() - end + return false end - return false end -function factions.Faction.set_description(self, new) - self.description = new - self:on_change_description() - factions.bulk_save() +function factions.set_description(name, new) + local faction = factions.factions.get(name) + + faction.description = new + factions.on_change_description(name) + + factions.factions.set(name, faction) 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.bulk_save() +function factions.invite_player(name, player) + local faction = factions.factions.get(name) + + faction.invited_players[player] = true + factions.on_player_invited(name, player) + + factions.factions.set(name, faction) 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.bulk_save() +function factions.revoke_invite(name, player) + local faction = factions.factions.get(name) + + faction.invited_players[player] = nil + factions.on_revoke_invite(name, player) + + factions.factions.set(name, faction) end --! @brief set faction openness -function factions.Faction.toggle_join_free(self, bool) - self.join_free = bool - self:on_toggle_join_free() - factions.bulk_save() +function factions.toggle_join_free(name, bool) + local faction = factions.factions.get(name) + + faction.join_free = bool + factions.on_toggle_join_free(name) + + factions.factions.set(name, faction) 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] +function factions.can_join(name, player) + local faction = factions.factions.get(name) + return faction.join_free or faction.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) +function factions.new_alliance(name, faction) + local bfaction = factions.factions.get(name) + + bfaction.allies[faction] = true + factions.on_new_alliance(name, faction) + if bfaction.enemies[faction] then + factions.end_enemy(name, faction) end - if self.neutral[faction] then - self:end_neutral(faction) + if bfaction.neutral[faction] then + factions.end_neutral(name, faction) end - factions.bulk_save() + + factions.factions.set(name, bfaction) end -function factions.Faction.end_alliance(self, faction) - self.allies[faction] = nil - self:on_end_alliance(faction) - factions.bulk_save() +function factions.end_alliance(name, faction) + local bfaction = factions.factions.get(name) + + bfaction.allies[faction] = nil + factions.on_end_alliance(name, faction) + + factions.factions.set(name, bfaction) end -function factions.Faction.new_neutral(self, faction) - self.neutral[faction] = true - self:on_new_neutral(faction) - if self.allies[faction] then - self:end_alliance(faction) +function factions.new_neutral(name, faction) + local bfaction = factions.factions.get(name) + + bfaction.neutral[faction] = true + + factions.on_new_neutral(name, faction) + if bfaction.allies[faction] then + factions.end_alliance(name, faction) end - if self.enemies[faction] then - self:end_enemy(faction) + if bfaction.enemies[faction] then + factions.end_enemy(name, faction) end - factions.bulk_save() + + factions.factions.set(name, bfaction) end -function factions.Faction.end_neutral(self, faction) - self.neutral[faction] = nil - self:on_end_neutral(faction) - factions.bulk_save() +function factions.end_neutral(name, faction) + local bfaction = factions.factions.get(name) + + bfaction.neutral[faction] = nil + factions.on_end_neutral(name, faction) + + factions.factions.set(name, bfaction) 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) +function factions.new_enemy(name, faction) + local bfaction = factions.factions.get(name) + + bfaction.enemies[faction] = true + factions.on_new_enemy(name, faction) + + if bfaction.allies[faction] then + factions.end_alliance(name, faction) end - if self.neutral[faction] then - self:end_neutral(faction) + + if bfaction.neutral[faction] then + factions.end_neutral(name, faction) end - factions.bulk_save() + + factions.factions.set(name, bfaction) end -function factions.Faction.end_enemy(self, faction) - self.enemies[faction] = nil - self:on_end_enemy(faction) - factions.bulk_save() +function factions.end_enemy(name, faction) + local bfaction = factions.factions.get(name) + + bfaction.enemies[faction] = nil + factions.on_end_enemy(name, faction) + + factions.factions.set(name, bfaction) 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() - factions.bulk_save() +function factions.set_spawn(name, pos) + local faction = factions.factions.get(name) + + faction.spawn = {x = pos.x, y = pos.y, z = pos.z} + factions.on_set_spawn(name) + + factions.factions.set(name, faction) end -function factions.Faction.tp_spawn(self, playername) +function factions.tp_spawn(name, playername) + local faction = factions.factions.get(name) + player = minetest.get_player_by_name(playername) + if player then - player:moveto(self.spawn, false) + player:set_pos(faction.spawn) end 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.bulk_save() +function factions.add_rank(name, rank, perms) + local faction = factions.factions.get(name) + + faction.ranks[rank] = perms + factions.on_add_rank(name, rank) + + factions.factions.set(name, faction) end --! @brief replace an rank's permissions --! @param rank the name of the rank to edit --! @param add or remove permissions to the rank -function factions.Faction.replace_privs(self, rank, perms) - self.ranks[rank] = perms - self:on_replace_privs(rank) - factions.bulk_save() +function factions.replace_privs(name, rank, perms) + local faction = factions.factions.get(name) + + faction.ranks[rank] = perms + factions.on_replace_privs(name, rank) + + factions.factions.set(name, faction) end -function factions.Faction.remove_privs(self, rank, perms) +function factions.remove_privs(name, rank, perms) + local faction = factions.factions.get(name) + local revoked = false - local p = self.ranks[rank] + local p = faction.ranks[rank] + for index, perm in pairs(p) do - if table_Contains(perms,perm) then + if table_Contains(perms, perm) then revoked = true - table.remove(p,index) + table.remove(p, index) end end - self.ranks[rank] = p + + faction.ranks[rank] = p + if revoked then - self:on_remove_privs(rank,perms) + factions.on_remove_privs(name, rank, perms) else - self:broadcast("No privilege was revoked from rank "..rank..".") + factions.broadcast(name, "No privilege was revoked from rank " .. rank .. ".") end - factions.bulk_save() + + factions.factions.set(name, faction) end -function factions.Faction.add_privs(self, rank, perms) +function factions.add_privs(name, rank, perms) + local faction = factions.factions.get(name) + local added = false - local p = self.ranks[rank] + local p = faction.ranks[rank] + for index, perm in pairs(perms) do - if not table_Contains(p,perm) then + if not table_Contains(p, perm) then added = true - table.insert(p,perm) + table.insert(p, perm) end end - self.ranks[rank] = p + + faction.ranks[rank] = p + if added then - self:on_add_privs(rank,perms) + factions.on_add_privs(name, rank, perms) else - self:broadcast("The rank "..rank.." already has these privileges.") + factions.broadcast(name, "The rank " .. rank .. " already has these privileges.") end - factions.bulk_save() + + factions.factions.set(name, faction) end -function factions.Faction.set_rank_name(self, oldrank, newrank) - local copyrank = self.ranks[oldrank] - self.ranks[newrank] = copyrank - self.ranks[oldrank] = nil - for player, r in pairs(self.players) do +function factions.set_rank_name(name, oldrank, newrank) + local faction = factions.factions.get(name) + + local copyrank = faction.ranks[oldrank] + + faction.ranks[newrank] = copyrank + faction.ranks[oldrank] = nil + + for player, r in pairs(faction.players) do if r == oldrank then - self.players[player] = newrank + faction.players[player] = newrank end end - if oldrank == self.default_leader_rank then - self.default_leader_rank = newrank - self:broadcast("The default leader rank has been set to "..newrank) + + if oldrank == faction.default_leader_rank then + faction.default_leader_rank = newrank + factions.broadcast(name, "The default leader rank has been set to " .. newrank) end - if oldrank == self.default_rank then - self.default_rank = newrank - self:broadcast("The default rank given to new players is set to "..newrank) + + if oldrank == faction.default_rank then + faction.default_rank = newrank + factions.broadcast(name, "The default rank given to new players is set to " .. newrank) end - self:on_set_rank_name(oldrank, newrank) - factions.bulk_save() + + factions.on_set_rank_name(name, oldrank, newrank) + + factions.factions.set(name, faction) end -function factions.Faction.set_def_rank(self, rank) - for player, r in pairs(self.players) do - if r == rank or r == nil or not self.ranks[r] then - self.players[player] = rank +function factions.set_def_rank(name, rank) + local faction = factions.factions.get(name) + + for player, r in pairs(faction.players) do + if r == rank or r == nil or not faction.ranks[r] then + faction.players[player] = rank end end - self.default_rank = rank - self:on_set_def_rank(rank) - self.rankless = false - factions.bulk_save() + + faction.default_rank = rank + factions.on_set_def_rank(name, rank) + + factions.factions.set(name, faction) end -function factions.Faction.reset_ranks(self) - self.ranks = starting_ranks - self.default_rank = "member" - self.default_leader_rank_rank = "leader" - for player, r in pairs(self.players) do - if not player == leader and (r == nil or not self.ranks[r]) then - self.players[player] = self.default_rank +function factions.reset_ranks(name) + local faction = factions.factions.get(name) + + faction.ranks = starting_ranks + faction.default_rank = "member" + faction.default_leader_rank_rank = "leader" + for player, r in pairs(faction.players) do + if not player == leader and (r == nil or not faction.ranks[r]) then + faction.players[player] = faction.default_rank elseif player == leader then - self.players[player] = self.default_leader_rank_rank + faction.players[player] = faction.default_leader_rank_rank end end - self:on_reset_ranks() - self.rankless = false - factions.bulk_save() + factions.on_reset_ranks(name) + + factions.factions.set(name, faction) 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 +function factions.delete_rank(name, rank, newrank) + local faction = factions.factions.get(name) + + for player, r in pairs(faction.players) do if r == rank then - self.players[player] = newrank + faction.players[player] = newrank end end - self.ranks[rank] = nil - self:on_delete_rank(rank, newrank) - if rank == self.default_leader_rank then - self.default_leader_rank = newrank - self:broadcast("The default leader rank has been set to "..newrank) + faction.ranks[rank] = nil + factions.on_delete_rank(name, rank, newrank) + if rank == faction.default_leader_rank then + faction.default_leader_rank = newrank + factions.broadcast(name, "The default leader rank has been set to "..newrank) end - if rank == self.default_rank then - self.default_rank = newrank - self:broadcast("The default rank given to new players is set to "..newrank) + if rank == faction.default_rank then + faction.default_rank = newrank + factions.broadcast(name, "The default rank given to new players is set to "..newrank) end - factions.bulk_save() + + factions.factions.set(name, faction) end --! @brief set a player's rank -function factions.Faction.promote(self, member, rank) - self.players[member] = rank - self:on_promote(member) +function factions.promote(name, member, rank) + local faction = factions.factions.get(name) + + faction.players[member] = rank + factions.on_promote(name, member) + + factions.factions.set(name, faction) end --! @brief send a message to all members -function factions.Faction.broadcast(self, msg, sender) - local message = self.name.."> "..msg +function factions.broadcast(name, msg, sender) + if factions.onlineplayers[name] == nil then + factions.onlineplayers[name] = {} + end + + local message = name .. "> ".. msg + if sender then - message = sender.."@"..message + message = sender .. "@" .. message end - message = "Faction<"..message - for k, _ in pairs(self.onlineplayers) do + + message = "Faction<" .. message + for k, _ in pairs(factions.onlineplayers[name]) do minetest.chat_send_player(k, message) end end --! @brief checks whether a faction has at least one connected player -function factions.Faction.is_online(self) - for playername, _ in pairs(self.onlineplayers) do +function factions.is_online(name) + if factions.onlineplayers[name] == nil then + factions.onlineplayers[name] = {} + end + for playername, _ in pairs(factions.onlineplayers[name]) do return true end return false end -function factions.Faction.attack_parcel(self, parcelpos) - if factions_config.attack_parcel then - local attacked_faction = factions.get_parcel_faction(parcelpos) - if attacked_faction then - if not self.allies[attacked_faction.name] then - self.power = self.power - factions_config.power_per_attack - if attacked_faction.attacked_parcels[parcelpos] then - attacked_faction.attacked_parcels[parcelpos][self.name] = true - else - attacked_faction.attacked_parcels[parcelpos] = {[self.name] = true} - end - attacked_faction:broadcast("Parcel ("..parcelpos..") is being attacked by "..self.name.."!!") - if self.power < 0. then -- punish memers - minetest.chat_send_all("Faction "..self.name.." has attacked too much and has now negative power!") - end - factions.bulk_save() - else - self:broadcast("You can not attack that parcel because it belongs to an ally.") - end - end - end -end - -function factions.Faction.stop_attack(self, parcelpos) - local attacked_faction = factions.parcels[parcelpos] - if attacked_faction then - attacked_faction = factions.factions[attacked_faction] - if attacked_faction.attacked_parcels[parcelpos] then - attacked_faction.attacked_parcels[parcelpos][self.name] = nil - attacked_faction:broadcast("Parcel ("..parcelpos..") is no longer under attack from "..self.name..".") - self:broadcast("Parcel ("..parcelpos..") has been reconquered by "..attacked_faction.name..".") - end - factions.bulk_save() - end -end - -function factions.Faction.parcel_is_attacked_by(self, parcelpos, faction) - if self.attacked_parcels[parcelpos] then - return self.attacked_parcels[parcelpos][faction.name] - else - return false - 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.") + +function factions.on_create(name) --! @brief called when the faction is added to the global faction list + minetest.chat_send_all("Faction " .. name .. " has been created.") end -function factions.Faction.on_set_name(self,oldname) - minetest.chat_send_all("Faction "..oldname.." has been changed its name to "..self.name..".") +function factions.on_set_name(name, oldname) + minetest.chat_send_all("Faction " .. oldname .. " has been changed its name to ".. name ..".") end -function factions.Faction.on_no_parcel(self) - local now = os.time() - self.no_parcel +function factions.on_no_parcel(name) + local faction = factions.factions.get(name) + + local now = os.time() - faction.no_parcel local l = factions_config.maximum_parcelless_faction_time - self:broadcast("This faction will disband in "..l-now.." seconds, because it has no parcels.") + + factions.broadcast(name, "This faction will disband in " .. l - now .. " seconds, because it has no parcels.") end -function factions.Faction.on_player_leave(self, player) - self:broadcast(player.." has left this faction.") +function factions.on_player_leave(name, player) + factions.broadcast(name, player .. " has left this faction") end -function factions.Faction.on_player_join(self, player) - self:broadcast(player.." has joined this faction.") +function factions.on_player_join(name, player) + factions.broadcast(name, player .. " has joined this faction") end -function factions.Faction.on_claim_parcel(self, pos) - self:broadcast("Parcel ("..pos..") has been claimed.") +function factions.on_claim_parcel(name, pos) + factions.broadcast(name, "Parcel (" .. pos .. ") has been claimed.") end -function factions.Faction.on_unclaim_parcel(self, pos) - self:broadcast("Parcel ("..pos..") has been unclaimed.") +function factions.on_unclaim_parcel(name, pos) + factions.broadcast(name, "Parcel ("..pos..") has been unclaimed.") end -function factions.Faction.on_disband(self, reason) - local msg = "Faction "..self.name.." has been disbanded." +function factions.on_disband(name, reason) + local msg = "Faction " .. name .. " has been disbanded." if reason then - msg = msg.." ("..reason..")" + msg = msg .. " (" .. reason .. ")" end minetest.chat_send_all(msg) end -function factions.Faction.on_new_leader(self) - self:broadcast(self.leader.." is now the leader of this faction.") +function factions.on_new_leader(name) + local faction = factions.factions.get(name) + factions.broadcast(name, faction.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) +function factions.on_change_description(name) + local faction = factions.factions.get(name) + factions.broadcast(name, "Faction description has been modified to: " .. faction.description) end -function factions.Faction.on_player_invited(self, player) - minetest.chat_send_player(player, "You have been invited to faction "..self.name) +function factions.on_player_invited(name, player) + local faction = factions.factions.get(name) + minetest.chat_send_player(player, "You have been invited to faction " .. faction.name) end -function factions.Faction.on_toggle_join_free(self, player) - if self.join_free then - self:broadcast("This faction is now invite-free.") +function factions.on_toggle_join_free(name, player) + local faction = factions.factions.get(name) + if faction.join_free then + factions.broadcast(name, "This faction is now invite-free.") else - self:broadcast("This faction is no longer invite-free.") + factions.broadcast(name, "This faction is no longer invite-free.") end end -function factions.Faction.on_new_alliance(self, faction) - self:broadcast("This faction is now allied with "..faction) +function factions.on_new_alliance(name, faction) + factions.broadcast(name, "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.."!") +function factions.on_end_alliance(name, faction) + factions.broadcast(name, "This faction is no longer allied with " .. faction .. "!") end -function factions.Faction.on_new_neutral(self, faction) - self:broadcast("This faction is now neutral with "..faction) +function factions.on_new_neutral(name, faction) + factions.broadcast(name, "This faction is now neutral with ".. faction) end -function factions.Faction.on_end_neutral(self, faction) - self:broadcast("This faction is no longer neutral with "..faction.."!") +function factions.on_end_neutral(name, faction) + factions.broadcast(name, "This faction is no longer neutral with " .. faction .. "!") end -function factions.Faction.on_new_enemy(self, faction) - self:broadcast("This faction is now at war with "..faction) +function factions.on_new_enemy(name, faction) + factions.broadcast(name, "This faction is now at war with " .. faction) end -function factions.Faction.on_end_enemy(self, faction) - self:broadcast("This faction is no longer at war with "..faction.."!") +function factions.on_end_enemy(name, faction) + factions.broadcast(name, "This faction is no longer at war with " .. faction .. "!") end -function factions.Faction.on_set_spawn(self) - self:broadcast("The faction spawn has been set to ("..util.coords3D_string(self.spawn)..").") +function factions.on_set_spawn(name) + local faction = factions.factions.get(name) + factions.broadcast(name, "The faction spawn has been set to (" .. util.coords3D_string(faction.spawn) .. ").") end -function factions.Faction.on_add_rank(self, rank) - self:broadcast("The rank "..rank.." has been created with privileges: "..table.concat(self.ranks[rank], ", ")) +function factions.on_add_rank(name, rank) + local faction = factions.factions.get(name) + factions.broadcast(name, "The rank " .. rank .. " has been created with privileges: " .. table.concat(faction.ranks[rank], ", ")) end -function factions.Faction.on_replace_privs(self, rank) - self:broadcast("The privileges in rank "..rank.." have been delete and changed to: "..table.concat(self.ranks[rank], ", ")) +function factions.on_replace_privs(name, rank) + local faction = factions.factions.get(name) + factions.broadcast(name, "The privileges in rank " .. rank .. " have been delete and changed to: " .. table.concat(faction.ranks[rank], ", ")) end -function factions.Faction.on_remove_privs(self, rank,privs) - self:broadcast("The privileges in rank "..rank.." have been revoked: "..table.concat(privs, ", ")) +function factions.on_remove_privs(name, rank, privs) + factions.broadcast(name, "The privileges in rank " .. rank .. " have been revoked: " .. table.concat(privs, ", ")) end -function factions.Faction.on_add_privs(self, rank,privs) - self:broadcast("The privileges in rank "..rank.." have been added: "..table.concat(privs, ", ")) +function factions.on_add_privs(name, rank, privs) + factions.broadcast(name, "The privileges in rank " .. rank .. " have been added: " .. table.concat(privs, ", ")) end -function factions.Faction.on_set_rank_name(self, rank,newrank) - self:broadcast("The name of rank "..rank.." has been changed to "..newrank) +function factions.on_set_rank_name(name, rank,newrank) + factions.broadcast(name, "The name of rank " .. rank .. " has been changed to " .. newrank) end -function factions.Faction.on_delete_rank(self, rank, newrank) - self:broadcast("The rank "..rank.." has been deleted and replaced by "..newrank) +function factions.on_delete_rank(name, rank, newrank) + factions.broadcast(name, "The rank " .. rank .. " has been deleted and replaced by " .. newrank) end -function factions.Faction.on_set_def_rank(self, rank) - self:broadcast("The default rank given to new players has been changed to "..rank) +function factions.on_set_def_rank(name, rank) + factions.broadcast(name, "The default rank given to new players has been changed to " .. rank) end -function factions.Faction.on_reset_ranks(self) - self:broadcast("All of the faction's ranks have been reset to the default ones.") +function factions.on_reset_ranks(name) + factions.broadcast(name, "All of the faction's ranks have been reset to the default ones.") end -function factions.Faction.on_promote(self, member) - minetest.chat_send_player(member, "You have been promoted to "..self.players[member]) +function factions.on_promote(name, member) + local faction = factions.factions.get(name) + minetest.chat_send_player(member, "You have been promoted to " .. faction.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) +function factions.on_revoke_invite(name, player) + minetest.chat_send_player(player, "You are no longer invited to faction " .. name) end function factions.get_parcel_pos(pos) if factions_config.protection_style == "2d" then - return math.floor(pos.x / factions_config.parcel_size)..","..math.floor(pos.z / factions_config.parcel_size) + return math.floor(pos.x / parcel_size) * parcel_size .. "," .. math.floor(pos.z / parcel_size) * parcel_size elseif factions_config.protection_style == "3d" then - return math.floor(pos.x / factions_config.parcel_size)..","..math.floor(pos.y / factions_config.parcel_size)..","..math.floor(pos.z / factions_config.parcel_size) + return math.floor(pos.x / parcel_size) * parcel_size .. "," .. math.floor(pos.y / parcel_size) * parcel_size .. "," .. math.floor(pos.z / parcel_size) * parcel_size end end function factions.get_player_faction(playername) - local facname = factions.players[playername] + local facname = factions.players.get(playername) if facname then - local faction = factions.factions[facname] - return faction + local faction = factions.factions.get(facname) + return faction, facname end return nil end function factions.get_parcel_faction(parcelpos) - local facname = factions.parcels[parcelpos] + local facname = factions.parcels.get(parcelpos) if facname then - local faction = factions.factions[facname] - return faction + local faction = factions.factions.get(facname) + return faction, facname end return nil end function factions.get_faction(facname) - return factions.factions[facname] + return factions.factions.get(facname) end function factions.get_faction_at(pos) @@ -993,360 +1098,105 @@ function factions.get_faction_at(pos) return factions.get_parcel_faction(parcelpos) 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 - -local saving = false - -------------------------------------------------------------------------------- --- 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 - factions_ip.save() - saving = false -end - -function factions.bulk_save() - if saving == false then - saving = true - minetest.after(5,function() factions.save() end) + local names = {} + local directory = string.format("%s/factions/factions", minetest.get_worldpath()) + local nameslist = minetest.get_dir_list(directory) + for k, v in pairs(nameslist) do + names[#names + 1] = v:sub(0, v:len() - 5) end -end -------------------------------------------------------------------------------- --- name: load() --- ---! @brief load data from file ---! @memberof factions ---! @private --- ---! @return true/false -------------------------------------------------------------------------------- -function factions.load() - local filename = "factions.conf" - local file,error = io.open(factions_worldid .. "/" .. filename,"r") - - if file ~= nil then - local raw_data = file:read("*a") - local current_version = misc_mod_data.data.factions_version - misc_mod_data.load() - local old_version = misc_mod_data.data.factions_version - local tabledata = minetest.deserialize(raw_data) - file:close() - if tabledata then - factions.factions = tabledata - if current_version ~= old_version or factions.is_old_file(tabledata) then - if factions.convert(filename) then - minetest.after(5, - function() - minetest.chat_send_all("Factions successfully converted.") - end) - end - end - 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 parcelpos, val in pairs(faction.land) do - factions.parcels[parcelpos] = facname - end - setmetatable(faction, factions.Faction) - if not faction.maxpower or faction.maxpower <= 0. then - faction.maxpower = faction.power - if faction.power < 0. then - faction.maxpower = 0. - end - end - if not faction.attacked_parcels then - faction.attacked_parcels = {} - end - if not faction.usedpower then - faction.usedpower = faction:count_land() * factions_config.power_per_parcel - end - if #faction.name > factions_config.faction_name_max_length then - faction:disband() - end - if not faction.last_logon then - faction.last_logon = os.time() - end - if faction.no_parcel ~= -1 then - faction.no_parcel = os.time() - end - if faction:count_land() > 0 then - faction.no_parcel = -1 - end - faction.onlineplayers = {} - faction.offlineplayers = {} - if faction.players then - for i, _ in pairs(faction.players) do - faction.offlineplayers[i] = _ - end - end - end - misc_mod_data.data.factions_version = current_version - misc_mod_data.save() - factions.save() - else - minetest.after(5, - function() - minetest.chat_send_all("Failed to deserialize saved file.") - end) - end - end - factions_ip.load() -end - -function factions.is_old_file(oldfactions) - local tempfaction = factions.Faction:new(nil) - local pass = false - for facname, faction in pairs(oldfactions) do - for ni, nl in pairs(tempfaction) do - pass = false - for key, value in pairs(faction) do - if key == ni then - pass = true - break - end - end - if not pass then - tempfaction = nil - return true - end - end - -- Only check one faction to save time. - if not pass then - tempfaction = nil - return true - else - tempfaction = nil - return false - end - end - tempfaction = nil - return false -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") - file:close() - - local data = minetest.deserialize(raw_data) - local old_permissions = {"disband", "claim", "playerslist", "build", "description", "ranks", "spawn", "promote","diplomacy"} - - for facname,faction in pairs(data) do - local newfac = factions.new_faction(facname,true) - for oi, ol in pairs(faction) do - if newfac[oi] then - newfac[oi] = ol - end - end - if faction.players then - newfac.players = faction.players - end - if faction.land then - newfac.land = faction.land - end - if faction.ranks then - newfac.ranks = faction.ranks - end - if faction.rankless then - newfac.rankless = faction.rankless - else - newfac.rankless = false - end - for rank,perm in pairs(faction.ranks) do - for index,value in pairs(perm) do - if value == "playerslist" then - table.remove(faction.ranks[rank],index) - table.insert(faction.ranks[rank],"kick") - table.insert(faction.ranks[rank],"invite") - elseif value == "ranks" then - table.remove(faction.ranks[rank],index) - table.insert(faction.ranks[rank],"create_ranks") - table.insert(faction.ranks[rank],"edit_ranks") - table.insert(faction.ranks[rank],"delete_ranks") - table.insert(faction.ranks[rank],"set_def_ranks") - table.insert(faction.ranks[rank],"reset_ranks") - elseif value == "diplomacy" then - table.remove(faction.ranks[rank],index) - table.insert(faction.ranks[rank],"declare_war") - table.insert(faction.ranks[rank],"neutral") - table.insert(faction.ranks[rank],"alliance") - table.insert(faction.ranks[rank],"accept_treaty") - table.insert(faction.ranks[rank],"refuse_treaty") - elseif value == "spawn" then - if not factions_config.spawn_teleport == true then - table.remove(faction.ranks[rank],index) - end - table.insert(faction.ranks[rank],"set_spawn") - table.insert(faction.ranks[rank],"unset_spawn") - end - end - end - factions.start_diplomacy(facname,newfac) - newfac:check_power() - end - -- Create runtime data. - for facname,faction in pairs(factions.factions) do - if faction.players then - for player, unused in pairs(faction.players) do - factions.players[player] = faction.name - end - end - if faction.land then - for l, unused in pairs(faction.land) do - factions.parcels[l] = facname - end - end - end - return true + return names end minetest.register_on_dieplayer( function(player) - local faction = factions.get_player_faction(player:get_player_name()) + local faction, name = factions.get_player_faction(player:get_player_name()) if not faction then return true end - faction:decrease_power(factions_config.power_per_death) + factions.decrease_power(name, factions_config.power_per_death) return true end ) function factions.faction_tick() local now = os.time() - for facname, faction in pairs(factions.factions) do - if faction:is_online() then - if factions_config.enable_power_per_player then - local t = faction.onlineplayers - local count = 0 - for _ in pairs(t) do count = count + 1 end - faction:increase_power(factions_config.power_per_player*count) - else - faction:increase_power(factions_config.power_per_tick) + for i, facname in pairs(factions.get_faction_list()) do + local faction = factions.factions.get(facname) + + if faction ~= nil then + if factions.is_online(facname) then + if factions_config.enable_power_per_player then + local count = 0 + for _ in pairs(factions.onlineplayers[facname]) do count = count + 1 end + factions.increase_power(facname, factions_config.power_per_player * count) + else + factions.increase_power(facname, factions_config.power_per_tick) + end end - end - if now - faction.last_logon > factions_config.maximum_faction_inactivity or (faction.no_parcel ~= -1 and now - faction.no_parcel > factions_config.maximum_parcelless_faction_time) then - faction:disband() - end + if now - faction.last_logon > factions_config.maximum_faction_inactivity or (faction.no_parcel ~= -1 and now - faction.no_parcel > factions_config.maximum_parcelless_faction_time) then + local r = "" + if now - faction.last_logon > factions_config.maximum_faction_inactivity then + r = "inactivity" + else + r = "no parcel claims" + end + factions.disband(facname, r) + end + end end end -local player_count = 0 - minetest.register_on_joinplayer( function(player) - player_count = player_count + 1 local name = player:get_player_name() - minetest.after(5,createHudfactionLand,player) - local faction = factions.get_player_faction(name) + minetest.after(5, createHudfactionLand, player) + local faction, facname = factions.get_player_faction(name) if faction then + if factions.onlineplayers[facname] == nil then + factions.onlineplayers[facname] = {} + end + + factions.onlineplayers[facname][name] = true faction.last_logon = os.time() - minetest.after(5,createHudFactionName,player,faction.name) - minetest.after(5,createHudPower,player,faction) - faction.offlineplayers[name] = nil - faction.onlineplayers[name] = 1 + + factions.factions.set(facname, faction) + + minetest.after(5, createHudFactionName, player, facname) + minetest.after(5, createHudPower, player, faction) + if faction.no_parcel ~= -1 then local now = os.time() - faction.no_parcel local l = factions_config.maximum_parcelless_faction_time - minetest.chat_send_player(name,"This faction will disband in "..l-now.." seconds, because it has no parcels.") + minetest.chat_send_player(name, "This faction will disband in " .. l - now .. " seconds, because it has no parcels.") end - if faction:has_permission(name, "accept_treaty") or faction:has_permission(name, "refuse_treaty") then - for _ in pairs(faction.request_inbox) do minetest.chat_send_player(name,"You have diplomatic requests in the inbox.") break end - end - if faction.rankless then - local p1 = faction:has_permission(name, "reset_ranks") - local p2 = faction:has_permission(name, "set_def_ranks") - if p1 and p2 then - minetest.chat_send_player(name,"You need to reset the default rank because there are rankless players in this faction. reset all the ranks back to default using /f reset_ranks (You will lose all of your custom ranks) or use /f set_def_rank") - elseif p1 then - minetest.chat_send_player(name,"You need to reset the default rank because there are rankless players in this faction. reset all the ranks back to default using /f reset_ranks (You will lose all of your custom ranks)") - elseif p2 then - minetest.chat_send_player(name,"You need to reset the default rank because there are rankless players in this faction. reset all the ranks back to default using /f set_def_rank") - end + + if factions.has_permission(facname, name, "diplomacy") then + for _ in pairs(faction.request_inbox) do minetest.chat_send_player(name, "You have diplomatic requests in the inbox.") break end end + if faction.message_of_the_day and (faction.message_of_the_day ~= "" or faction.message_of_the_day ~= " ") then - minetest.chat_send_player(name,faction.message_of_the_day) + minetest.chat_send_player(name, faction.message_of_the_day) end end - factions.bulk_save() + end ) minetest.register_on_leaveplayer( function(player) - player_count = player_count - 1 local name = player:get_player_name() - local faction = factions.get_player_faction(name) + local faction, facname = factions.get_player_faction(name) local id_name1 = name .. "factionLand" + if hud_ids[id_name1] then hud_ids[id_name1] = nil end + if faction then + factions.onlineplayers[facname][name] = nil local id_name2 = name .. "factionName" local id_name3 = name .. "powerWatch" if hud_ids[id_name2] then @@ -1355,63 +1205,57 @@ minetest.register_on_leaveplayer( if hud_ids[id_name3] then hud_ids[id_name3] = nil end - faction.offlineplayers[name] = 1 - faction.onlineplayers[name] = nil - end - if player_count > 0 then - factions.bulk_save() - else - factions.save() end end ) minetest.register_on_respawnplayer( function(player) - local faction = factions.get_player_faction(player:get_player_name()) - if not faction then + local faction, facname = factions.get_player_faction(player:get_player_name()) + + if not faction then return false else if not faction.spawn then return false else - player:setpos(faction.spawn) + player:set_pos(faction.spawn) return true end end end ) - - local default_is_protected = minetest.is_protected minetest.is_protected = function(pos, player) local y = pos.y + if factions_config.protection_depth_height_limit and (pos.y < factions_config.protection_max_depth or pos.y > factions_config.protection_max_height) then return false end local parcelpos = factions.get_parcel_pos(pos) - local parcel_faction = factions.get_parcel_faction(parcelpos) - local player_faction = factions.get_player_faction(player) + local parcel_faction, parcel_fac_name = factions.get_parcel_faction(parcelpos) + local player_faction, player_fac_name = factions.get_player_faction(player) + -- no faction if not parcel_faction then return default_is_protected(pos, player) elseif player_faction then - if parcel_faction.name == player_faction.name then - if parcel_faction:has_permission(player, "pain_build") then + if parcel_name == player_name then + if factions.has_permission(parcel_fac_name, player, "pain_build") then local p = minetest.get_player_by_name(player) p:set_hp(p:get_hp() - 0.5) end - return not (parcel_faction:has_permission(player, "build") or parcel_faction:has_permission(player, "pain_build")) - elseif parcel_faction.allies[player_faction.name] then - if player_faction:has_permission(player, "pain_build") then + return not (factions.has_permission(parcel_fac_name, player, "build") or factions.has_permission(parcel_fac_name, player, "pain_build")) + elseif parcel_allies[player_name] then + if factions.has_permission(player_fac_name, player, "pain_build") then local p = minetest.get_player_by_name(player) p:set_hp(p:get_hp() - 0.5) end - return not (player_faction:has_permission(player, "build") or player_faction:has_permission(player, "pain_build")) + return not (factions.has_permission(player_fac_name, player, "build") or factions.has_permission(player_fac_name, player, "pain_build")) else - return not parcel_faction:parcel_is_attacked_by(parcelpos, player_faction) + return true end else return true @@ -1420,5 +1264,5 @@ end function factionUpdate() factions.faction_tick() - minetest.after(factions_config.tick_time,factionUpdate) -end \ No newline at end of file + minetest.after(factions_config.tick_time, factionUpdate) +end diff --git a/hud.lua b/hud.lua index 8689c80..8feb527 100644 --- a/hud.lua +++ b/hud.lua @@ -4,13 +4,14 @@ function createHudfactionLand(player) if player then local name = player:get_player_name() local id_name = name .. "factionLand" + if not hud_ids[id_name] then hud_ids[id_name] = player:hud_add({ hud_elem_type = "text", name = "factionLand", number = 0xFFFFFF, position = {x=0.1, y = .98}, - text = "Wilderness", + text = "Parcel:", scale = {x=1, y=1}, alignment = {x=0, y=0}, }) @@ -18,17 +19,18 @@ function createHudfactionLand(player) end end -function createHudFactionName(player,factionname) +function createHudFactionName(player, factionname) if player and factionname then local name = player:get_player_name() local id_name = name .. "factionName" + if not hud_ids[id_name] then hud_ids[id_name] = player:hud_add({ hud_elem_type = "text", name = "factionName", number = 0xFFFFFF, position = {x=1, y = 0}, - text = "Faction "..factionname, + text = "Faction " .. factionname, scale = {x=1, y=1}, alignment = {x=-1, y=0}, offset = {x = -20, y = 20} @@ -37,17 +39,18 @@ function createHudFactionName(player,factionname) end end -function createHudPower(player,faction) +function createHudPower(player, faction) if player and faction then local name = player:get_player_name() local id_name = name .. "powerWatch" + if not hud_ids[id_name] then hud_ids[id_name] = player:hud_add({ hud_elem_type = "text", name = "powerWatch", number = 0xFFFFFF, position = {x=0.9, y = .98}, - text = "Power: "..faction.power.." / ".. faction.maxpower - faction.usedpower, + text = "Power: " .. faction.power .. " / " .. faction.maxpower - faction.usedpower, scale = {x=1, y=1}, alignment = {x=-1, y=0}, offset = {x = 0, y = 0} @@ -56,9 +59,10 @@ function createHudPower(player,faction) end end -function removeHud(player,hudname) +function removeHud(player, hudname) local name = "" local p = {} + if type(player) ~= "string" then name = player:get_player_name() p = player @@ -66,24 +70,28 @@ function removeHud(player,hudname) name = player p = minetest.get_player_by_name(player) end + local id_name = name .. hudname + if hud_ids[id_name] then p:hud_remove(hud_ids[id_name]) hud_ids[id_name] = nil end end -function updateHudPower(player,faction) +function updateHudPower(player, faction) local name = player:get_player_name() local id_name = name .. "powerWatch" + if hud_ids[id_name] then - player:hud_change(hud_ids[id_name],"text","Power: "..faction.power.." / ".. faction.maxpower - faction.usedpower) + player:hud_change(hud_ids[id_name], "text", "Power: " .. faction.power .. " / " .. faction.maxpower - faction.usedpower) end end -function updateFactionName(player,factionname) +function updateFactionName(player, factionname) local name = "" local p = {} + if type(player) ~= "string" then name = player:get_player_name() p = player @@ -91,9 +99,11 @@ function updateFactionName(player,factionname) name = player p = minetest.get_player_by_name(player) end + local id_name = name .. "factionName" + if hud_ids[id_name] then - p:hud_change(hud_ids[id_name],"text","Faction "..factionname) + p:hud_change(hud_ids[id_name], "text", "Faction " .. factionname) end end @@ -102,11 +112,16 @@ function hudUpdateClaimInfo() for i in pairs(playerslist) do local player = playerslist[i] local name = player:get_player_name() - local faction = factions.get_faction_at(player:getpos()) + local faction, facname = factions.get_faction_at(player:getpos()) local id_name = name .. "factionLand" + if hud_ids[id_name] then - player:hud_change(hud_ids[id_name],"text",(faction and faction.name) or "Wilderness") + local display = "Parcel:" + if facname then + display = display .. facname + end + player:hud_change(hud_ids[id_name], "text", display) end end - minetest.after(3,hudUpdateClaimInfo) + minetest.after(3, hudUpdateClaimInfo) end \ No newline at end of file diff --git a/init.lua b/init.lua index cc7946c..b9a3ce6 100644 --- a/init.lua +++ b/init.lua @@ -2,17 +2,13 @@ factions_modpath = minetest.get_modpath("factions") dofile (factions_modpath .. "/config.lua") -dofile (factions_modpath .. "/misc_mod_data.lua") dofile (factions_modpath .. "/hud.lua") -dofile (factions_modpath .. "/ip.lua") dofile (factions_modpath .. "/factions.lua") dofile (factions_modpath .. "/chatcommands.lua") dofile (factions_modpath .. "/nodes.lua") +dofile (factions_modpath .. "/convert.lua") -factions.load() -misc_mod_data.check_file() - -minetest.after(1,hudUpdateClaimInfo) -minetest.after(1,factionUpdate) +minetest.after(1, hudUpdateClaimInfo) +minetest.after(factions_config.tick_time, factionUpdate) minetest.log("action", "[factions] loaded.") diff --git a/ip.lua b/ip.lua deleted file mode 100644 index 29dd8bf..0000000 --- a/ip.lua +++ /dev/null @@ -1,28 +0,0 @@ -factions_ip = {} -factions_ip.player_ips = {} - ---read some basic information -local factions_worldid = minetest.get_worldpath() - -function factions_ip.save() - local file,error = io.open(factions_worldid .. "/" .. "factions_iplist.txt","w") - - if file ~= nil then - file:write(minetest.serialize(factions_ip.player_ips)) - file:close() - else - minetest.log("error","MOD factions: unable to save faction player ips!: " .. error) - end -end - -function factions_ip.load() - local file,error = io.open(factions_worldid .. "/" .. "factions_iplist.txt","r") - - if file ~= nil then - local raw_data = file:read("*a") - factions_ip.player_ips = minetest.deserialize(raw_data) - file:close() - else - factions_ip.save() - end -end \ No newline at end of file diff --git a/misc_mod_data.lua b/misc_mod_data.lua deleted file mode 100644 index 8c959e2..0000000 --- a/misc_mod_data.lua +++ /dev/null @@ -1,38 +0,0 @@ -misc_mod_data = {} -misc_mod_data.data = {factions_version = "0.8.1",config = factions_config} - ---read some basic information -local factions_worldid = minetest.get_worldpath() - -function misc_mod_data.save() - local file,error = io.open(factions_worldid .. "/" .. "factions_misc_mod_data.txt","w") - - if file ~= nil then - file:write(minetest.serialize(misc_mod_data.data)) - file:close() - else - minetest.log("error","MOD factions: unable to save factions misc mod data!: " .. error) - end -end - -function misc_mod_data.load() - local file,error = io.open(factions_worldid .. "/" .. "factions_misc_mod_data.txt","r") - - if file ~= nil then - local raw_data = file:read("*a") - misc_mod_data.data = minetest.deserialize(raw_data) - file:close() - else - misc_mod_data.save() - end -end - -function misc_mod_data.check_file() - local file,error = io.open(factions_worldid .. "/" .. "factions_misc_mod_data.txt","r") - - if file ~= nil then - file:close() - else - misc_mod_data.save() - end -end \ No newline at end of file diff --git a/mod.conf b/mod.conf index c953f47..fc2cf80 100644 --- a/mod.conf +++ b/mod.conf @@ -1 +1 @@ -name = factions \ No newline at end of file +name = factions diff --git a/nodes.lua b/nodes.lua index 1e018de..e48fd5c 100644 --- a/nodes.lua +++ b/nodes.lua @@ -1,4 +1,4 @@ -function factions.can_use_node(pos, player,permission) +function factions.can_use_node(pos, player, permission) if not player then return false end @@ -6,11 +6,12 @@ function factions.can_use_node(pos, player,permission) if not parcel_faction then return true end - local player_faction = factions.get_player_faction(player) - if player_faction and (parcel_faction.name == player_faction.name or parcel_faction.allies[player_faction.name]) and player_faction:has_permission(player, permission) then + local player_faction, facname = factions.get_player_faction(player) + if player_faction and (parcel_faction.name == facname or parcel_faction.allies[facname]) and factions.has_permission(facname, player, permission) then return true end end + -- Make default chest the faction chest. if minetest.registered_nodes["default:chest"] then minetest.register_lbm({ @@ -18,84 +19,132 @@ if minetest.registered_nodes["default:chest"] then name = "factions:replace_factions_chest", nodenames = {"factions:chest"}, action = function(pos, node) - minetest.swap_node(pos, {name="default:chest"}) + minetest.swap_node(pos, {name = "default:chest"}) local parcel_faction = factions.get_faction_at(pos) if parcel_faction then local meta = minetest.get_meta(pos) - meta:set_string("faction", parcel_faction.name or "") + local name = parcel_faction.name + meta:set_string("faction", name) meta:set_string("infotext", "Faction Chest (owned by faction " .. - meta:get_string("faction") .. ")") + name .. ")") end end }) local dc = minetest.registered_nodes["default:chest"] local def_on_rightclick = dc.on_rightclick - local clonenode = {} - for k,v in pairs(minetest.registered_nodes["default:chest"]) do clonenode[k] = v end - clonenode.after_place_node = function(pos, placer) + + local after_place_node = function(pos, placer) local parcel_faction = factions.get_faction_at(pos) if parcel_faction then local meta = minetest.get_meta(pos) - meta:set_string("faction", parcel_faction.name or "") + local name = parcel_faction.name + meta:set_string("faction", name) meta:set_string("infotext", "Faction Chest (owned by faction " .. - meta:get_string("faction") .. ")") + name .. ")") end end - clonenode.can_dig = function(pos,player) - local meta = minetest.get_meta(pos); + local can_dig = function(pos, player) + local meta = minetest.get_meta(pos) local inv = meta:get_inventory() return inv:is_empty("main") and - factions.can_use_node(pos, player:get_player_name(),"container") + factions.can_use_node(pos, player:get_player_name(), "container") end - clonenode.allow_metadata_inventory_move = function(pos, from_list, from_index, + local allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player) - if not factions.can_use_node(pos, player:get_player_name(),"container") then + if not factions.can_use_node(pos, player:get_player_name(), "container") then return 0 end return count end - clonenode.allow_metadata_inventory_put = function(pos, listname, index, stack, player) - if not factions.can_use_node(pos, player:get_player_name(),"container") then + local allow_metadata_inventory_put = function(pos, listname, index, stack, player) + if not factions.can_use_node(pos, player:get_player_name(), "container") then return 0 end return stack:get_count() end - clonenode.allow_metadata_inventory_take = function(pos, listname, index, stack, player) - if not factions.can_use_node(pos, player:get_player_name(),"container") then + local allow_metadata_inventory_take = function(pos, listname, index, stack, player) + if not factions.can_use_node(pos, player:get_player_name(), "container") then return 0 end return stack:get_count() end - clonenode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - if not factions.can_use_node(pos, clicker:get_player_name(),"container") then + local on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if not factions.can_use_node(pos, clicker:get_player_name(), "container") then return itemstack end - def_on_rightclick(pos, node, clicker, itemstack, pointed_thing) + return def_on_rightclick(pos, node, clicker, itemstack, pointed_thing) end - minetest.register_node(":default:chest",clonenode) + minetest.override_item("default:chest", {after_place_node = after_place_node, + can_dig = can_dig, + allow_metadata_inventory_move = allow_metadata_inventory_move, + allow_metadata_inventory_put = allow_metadata_inventory_put, + allow_metadata_inventory_take = allow_metadata_inventory_take, + on_rightclick = on_rightclick}) end + -- Edit default doors and trapdoors to make them require the door permission. -local doors = {"doors:door_wood_a","doors:door_wood_b","doors:door_steel_a","doors:door_steel_b","doors:door_glass_a","doors:door_glass_b" -,"doors:door_obsidian_glass_a","doors:door_obsidian_glass_b","doors:trapdoor","doors:trapdoor_open","doors:trapdoor_steel","doors:trapdoor_steel_open"} -for i,k in ipairs(doors) do - if minetest.registered_nodes[k] then - local dw = minetest.registered_nodes[k] - local def_after_place_node = dw.on_rightclick +local doors = {"doors:door_wood_a", "doors:door_wood_b", "doors:door_steel_a", "doors:door_steel_b", "doors:door_glass_a", "doors:door_glass_b", + "doors:door_obsidian_glass_a", "doors:door_obsidian_glass_b", "doors:trapdoor", "doors:trapdoor_open", "doors:trapdoor_steel", "doors:trapdoor_steel_open", + "doors:woodglass_door_a", "doors:woodglass_door_b", "doors:slide_door_a", "doors:slide_door_b", "doors:screen_door_a", "doors:screen_door_b", "doors:rusty_prison_door_a", + "doors:rusty_prison_door_b", "doors:prison_door_a", "doors:prison_door_b", "doors:japanese_door_a", "doors:japanese_door_b"} +for i, l in ipairs(doors) do + local dw = minetest.registered_nodes[l] + if dw then + local def_on_rightclick = dw.on_rightclick local def_can_dig = dw.can_dig - local clonenode = {} - for k,v in pairs(minetest.registered_nodes[k]) do clonenode[k] = v end - clonenode.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - if factions.can_use_node(pos, clicker:get_player_name(),"door") then - def_after_place_node(pos, node, clicker, itemstack, pointed_thing) + + local on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if factions.can_use_node(pos, clicker:get_player_name(), "door") then + def_on_rightclick(pos, node, clicker, itemstack, pointed_thing) + end + return itemstack + end + + local can_dig = nil + + if def_can_dig then + can_dig = function(pos, digger) + if factions.can_use_node(pos, digger:get_player_name(), "door") then + return def_can_dig(pos, digger) + end + return false + end + else + can_dig = function(pos, digger) + if factions.can_use_node(pos, digger:get_player_name(), "door") then + return true + end + return false end end - clonenode.can_dig = function(pos, digger) - if factions.can_use_node(pos, digger:get_player_name(),"door") then - return def_can_dig(pos, digger) + minetest.override_item(l, {on_rightclick = on_rightclick, + can_dig = can_dig}) + end +end + +local door_items = {"doors:door_wood", "doors:door_steel", "doors:door_glass", "doors:door_obsidian_glass", "doors:trapdoor", "doors:trapdoor_steel", "doors:woodglass_door", "doors:slide_door", + "doors:screen_door", "doors:rusty_prison_door", "doors:prison_door", "doors:japanese_door"} + +for i, l in ipairs(door_items) do + local it = minetest.registered_items[l] + if it then + local def_on_place = it.on_place + if def_on_place ~= nil then + local on_place = function(itemstack, placer, pointed_thing) + local r = def_on_place(itemstack, placer, pointed_thing) + local pos = pointed_thing.above + local parcel_faction = factions.get_faction_at(pos) + if parcel_faction then + local meta = minetest.get_meta(pos) + local name = parcel_faction.name + meta:set_string("faction", name) + meta:set_string("infotext", "Faction Door (owned by faction " .. + name .. ")") + end + return r end - return false + minetest.override_item(l, {on_place = on_place}) end - minetest.register_node(":"..k,clonenode) end end -- Code below was copied from TenPlus1's protector mod(MIT) and changed up a bit.