diff --git a/README.md b/README.md index e45fb86..4ab2c76 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,4 @@ # factions mod for minetest -Mod for handling in game factions and reputation. - -# TODO LIST - -Redo the parcel attack system(Can be turned on in settings). - -Add command to show or hide all parcel position locations as markers. - -Add money. - -Player money tax. - -faction territory titles. - -faction territories (Like a faction within a faction) - -faction color. - -Color tags based on faction color(add support for entity tag mods). - -More claim and unclaim commands. - -faction access manage command. - -Maybe expand on diplomacy. - -Write the forum topic better. - -Code clean up and optimization. - -Add short worded commands. - -Parcels should show up at a more accurate position just like in mc factions. - -Add-on mod mc style tnt. - -Add-on mod lag-free fire(if thats possible). \ No newline at end of file +Mod for handling in game factions. diff --git a/chatcommands.lua b/chatcommands.lua index e481860..0a96c24 100644 --- a/chatcommands.lua +++ b/chatcommands.lua @@ -6,7 +6,7 @@ factions_chat = {} factions.commands = {} -factions.register_command = function(cmd_name, cmd, ignore_param_count,or_perm) +factions.register_command = function(cmd_name, cmd, ignore_param_count, or_perm, dont_show_in_help) factions.commands[cmd_name] = { -- default command name = cmd_name, faction_permissions = {}, @@ -14,6 +14,7 @@ factions.register_command = function(cmd_name, cmd, ignore_param_count,or_perm) format = {}, infaction = true, description = "This command has no description.", + dont_show_in_help = dont_show_in_help, run = function(self, player, argv) if self.global_privileges then local tmp = {} @@ -64,20 +65,17 @@ factions.register_command = function(cmd_name, cmd, ignore_param_count,or_perm) table.insert(args.factions, fac) end elseif argtype == "player" then - local pl = minetest.get_player_by_name(arg) - if not pl and not factions.players[arg] then - send_error(player, "Player is not online.") - return false - else - table.insert(args.players, pl) - end + local data = minetest.get_auth_handler().get_auth(arg) + if data then + table.insert(args.players, arg) + else + send_error(player, "Player does not exist.") + return false + end elseif argtype == "string" then table.insert(args.strings, arg) else table.insert(args.unknowns, arg) - --minetest.log("error", "Bad format definition for function "..self.name) - --send_error(player, "Internal server error") - --return false end end for i=2, #argv do @@ -125,6 +123,13 @@ factions.register_command = function(cmd_name, cmd, ignore_param_count,or_perm) end end +factions.register_commands = function(cmd_names, cmd, ignore_param_count, or_perm) + local hide = false + for k, v in pairs(cmd_names) do + factions.register_command(k, cmd, ignore_param_count, or_perm, hide) + hide = true + end +end local init_commands init_commands = function() @@ -146,20 +151,11 @@ init_commands = function() } ) - local def_privs = { interact=true} + local def_privs = {interact = true} if factions_config.faction_user_priv == true then def_privs.faction_user = true end - minetest.register_chatcommand("factions", - { - params = " parameters", - description = "Factions commands. Type /factions help for available commands.", - privs = def_privs, - func = factions_chat.cmdhandler, - } - ) - minetest.register_chatcommand("f", { params = " parameters", @@ -168,6 +164,15 @@ init_commands = function() func = factions_chat.cmdhandler, } ) + + minetest.register_chatcommand("faction", + { + params = " parameters", + description = "Factions commands. Type /faction help for available commands.", + privs = def_privs, + func = factions_chat.cmdhandler, + } + ) end @@ -188,10 +193,11 @@ if factions_config.faction_user_priv == true then def_global_privileges = {"faction_user"} end -factions.register_command ("set_name", { +factions.register_command ("name", { faction_permissions = {"name"}, format = {"string"}, description = "Change the faction's name.", + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local factionname = args.strings[1] @@ -208,57 +214,119 @@ factions.register_command ("set_name", { factions.register_command ("claim", { faction_permissions = {"claim"}, description = "Claim the plot of land you're on.", + description_arg = ":", + format = {"string"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - local p = parcelpos - local can_claim = factions.can_claim_parcel(faction.name, p) - - if can_claim then - minetest.chat_send_player(player, "Claming parcel " .. p) - factions.claim_parcel(faction.name, p) - return true - else - 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_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.") - return false - else - send_error(player, "Your faction cannot claim any (more) parcel(s).") - return false - end - end + local arg_one = args.strings[1] + local arg_two = args.strings[2] + if not arg_one or arg_one == "o" or arg_one == "one" then + return claim_helper(player, faction, parcelpos) + elseif arg_one == "a" or arg_one == "auto" then + factions.claim_auto(player, faction) + elseif arg_one == "f" or arg_one == "fill" then + factions.claim_fill(player, faction) + elseif arg_one == "s" or arg_one == "square" then + if arg_two then + local r = tonumber(arg_two) + + if not r then + send_error(player, "Only use numbers in the second cmd parameter [0-9].") + return + end + + factions.claim_square(player, faction, r) + else + factions.claim_square(player, faction, 3) + end + elseif arg_one == "c" or arg_one == "circle" then + if arg_two then + local r = tonumber(arg_two) + + if not r then + send_error(player, "Only use numbers in the second cmd parameter [0-9].") + return + end + + factions.claim_circle(player, faction, r) + else + factions.claim_circle(player, faction, 3) + end + elseif arg_one == "all" then + factions.claim_all(player, faction) + elseif arg_one == "l" or arg_one == "list" then + local timer = 0 + minetest.chat_send_player(player, "All claims:") + for i in pairs(faction.land) do + minetest.after(timer, minetest.chat_send_player, player, i) + timer = timer + 0.1 + end + elseif arg_one == "h" or arg_one == "help" then + factions.claim_help(player, arg_two) + end end -},false) +},true) factions.register_command("unclaim", { faction_permissions = {"claim"}, description = "Unclaim the plot of land you're on.", + description_arg = ":", + format = {"string"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - local parcel_faction = factions.get_parcel_faction(parcelpos) - if not parcel_faction then - send_error(player, "This parcel does not exist.") - return false + local arg_one = args.strings[1] + local arg_two = args.strings[2] + if not arg_one or arg_one == "o" or arg_one == "one" then + return unclaim_helper(player, faction, parcelpos) + elseif arg_one == "a" or arg_one == "auto" then + factions.unclaim_auto(player, faction) + elseif arg_one == "f" or arg_one == "fill" then + factions.unclaim_fill(player, faction) + elseif arg_one == "s" or arg_one == "square" then + if arg_two then + local r = tonumber(arg_two) + + if not r then + send_error(player, "Only use numbers in the second cmd parameter [0-9].") + return + end + + factions.unclaim_square(player, faction, r) + else + factions.unclaim_square(player, faction, 3) + end + elseif arg_one == "c" or arg_one == "circle" then + if arg_two then + local r = tonumber(arg_two) + + if not r then + send_error(player, "Only use numbers in the second cmd parameter [0-9].") + return + end + + factions.unclaim_circle(player, faction, r) + else + factions.unclaim_circle(player, faction, 3) + end + elseif arg_one == "all" then + factions.unclaim_all(player, faction) + elseif arg_one == "l" or arg_one == "list" then + local timer = 0 + minetest.chat_send_player(player, "All claims:") + for i in pairs(faction.land) do + minetest.after(timer, minetest.chat_send_player, player, i) + timer = timer + 0.1 + end + elseif arg_one == "h" or arg_one == "help" then + factions.unclaim_help(player, arg_two) end - if parcel_name ~= name then - send_error(player, "This parcel does not belong to you.") - return false - else - factions.unclaim_parcel(faction.name, parcelpos) - return true - end end -},false) +},true) --list all known factions factions.register_command("list", { description = "List all registered factions.", + description_arg = ":", infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) @@ -281,16 +349,18 @@ factions.register_command("list", { --show factions mod version factions.register_command("version", { description = "Displays mod version.", + description_arg = ":", infaction = false, on_success = function(player, faction, pos, parcelpos, args) - minetest.chat_send_player(player, "factions: version 0.8.4", false) + minetest.chat_send_player(player, "factions: version 0.8.8", false) end },false) ---show description of faction +--show description of faction factions.register_command("info", { format = {"faction"}, description = "Shows a faction's description.", + description_arg = " :", infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) @@ -303,6 +373,7 @@ factions.register_command("info", { factions.register_command("leave", { description = "Leave your faction", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) factions.remove_player(faction.name, player) @@ -314,10 +385,10 @@ factions.register_command("kick", { faction_permissions = {"kick"}, format = {"player"}, description = "Kick a player from your faction", + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - local victim = args.players[1] - local name = victim:get_player_name() + local name = args.players[1] local victim_faction, facname = factions.get_player_faction(name) @@ -341,6 +412,7 @@ factions.register_command("create", { format = {"string"}, infaction = false, description = "Create a new faction", + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if faction then @@ -366,6 +438,7 @@ factions.register_command("create", { factions.register_command("join", { format = {"faction"}, description = "Join a faction", + description_arg = " :", infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) @@ -393,6 +466,7 @@ factions.register_command("join", { factions.register_command("disband", { faction_permissions = {"disband"}, description = "Disband your faction", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) factions.disband(faction.name) @@ -403,6 +477,7 @@ factions.register_command("disband", { factions.register_command("flag", { faction_permissions = {"flags"}, description = "Manage the faction's flags.", + description_arg = " :", global_privileges = def_global_privileges, format = {"string"}, on_success = function(player, faction, pos, parcelpos, args) @@ -440,10 +515,11 @@ factions.register_command("flag", { end },true) -factions.register_command("description", { +factions.register_command("desc", { format = {"string"}, faction_permissions = {"description"}, description = "Set your faction's description", + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) factions.set_description(faction.name, table.concat(args.strings," ")) @@ -455,10 +531,35 @@ factions.register_command("invite", { format = {"player"}, faction_permissions = {"invite"}, description = "Invite a player to your faction", + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) if args.players and args.players[1] then - factions.invite_player(faction.name, args.players[1]:get_player_name()) + if player == args.players[1] then + send_error(player, "You can not invite yourself.") + return + end + factions.invite_player(faction.name, args.players[1]) + minetest.chat_send_player(player, "Invite Sent.") + end + return true + end +},false) + +factions.register_command("invites", { + description = "List invited players.", + description_arg = ":", + faction_permissions = {"invite"}, + global_privileges = def_global_privileges, + on_success = function(player, faction, pos, parcelpos, args) + minetest.chat_send_player(player, "Invited players:") + local foundplayer = false + for p, _ in pairs(faction.invited_players) do + minetest.chat_send_player(player, p) + foundplayer = true + end + if not foundplayer then + minetest.chat_send_player(player, "None:") end return true end @@ -468,9 +569,11 @@ factions.register_command("uninvite", { format = {"player"}, faction_permissions = {"invite"}, description = "Revoke a player's invite.", + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) - factions.revoke_invite(faction.name, args.players[1]:get_player_name()) + factions.revoke_invite(faction.name, args.players[1]) + minetest.chat_send_player(player, "Invite canceled.") return true end },false) @@ -480,6 +583,7 @@ factions.register_command("delete", { format = {"faction"}, infaction = false, description = "Delete a faction", + description_arg = " :", on_success = function(player, faction, pos, parcelpos, args) factions.disband(args.factions[1].name) return true @@ -488,6 +592,7 @@ factions.register_command("delete", { factions.register_command("ranks", { description = "List ranks within your faction", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) for rank, permissions in pairs(faction.ranks) do @@ -498,7 +603,8 @@ factions.register_command("ranks", { },false) factions.register_command("rank_privileges", { - description = "List available rank privileges.", + description = "List available rank privileges", + description_arg = ":", global_privileges = def_global_privileges, infaction = false, on_success = function(player, faction, pos, parcelpos, args) @@ -510,14 +616,15 @@ factions.register_command("rank_privileges", { end },false) -factions.register_command("set_message_of_the_day", { +factions.register_command("motd", { format = {"string"}, faction_permissions = {"motd"}, - description = "Sets the message that shows up every time a faction member logs-in.", + description = "Sets the message that shows up every time a faction member logs-in", + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local s = "" - for i,l in pairs(args.strings) do + for i, l in pairs(args.strings) do s = s .. l .. " " end factions.set_message_of_the_day(faction.name, "Message of the day: " .. s) @@ -528,6 +635,7 @@ factions.register_command("set_message_of_the_day", { if factions_config.faction_diplomacy == true then factions.register_command("send_alliance", { description = "Send an alliance request to another faction", + description_arg = " :", global_privileges = def_global_privileges, format = {"string"}, faction_permissions = {"diplomacy"}, @@ -573,6 +681,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("send_neutral", { description = "Send neutral to another faction", + description_arg = " :", global_privileges = def_global_privileges, format = {"string"}, faction_permissions = {"diplomacy"}, @@ -618,6 +727,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("accept", { description = "accept an request from another faction", + description_arg = " :", global_privileges = def_global_privileges, format = {"string"}, faction_permissions = {"diplomacy"}, @@ -653,6 +763,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("refuse", { description = "refuse an request from another faction", + description_arg = " :", global_privileges = def_global_privileges, format = {"string"}, faction_permissions = {"diplomacy"}, @@ -679,6 +790,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("declare_war", { description = "Declare war on a faction", + description_arg = " :", global_privileges = def_global_privileges, format = {"string"}, faction_permissions = {"diplomacy"}, @@ -713,6 +825,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("break", { description = "Break an alliance.", + description_arg = " :", global_privileges = def_global_privileges, format = {"string"}, faction_permissions = {"diplomacy"}, @@ -739,6 +852,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("inbox", { description = "Check your diplomacy request inbox.", + description_arg = ":", global_privileges = def_global_privileges, faction_permissions = {"diplomacy"}, on_success = function(player, faction, pos, parcelpos, args) @@ -760,10 +874,11 @@ if factions_config.faction_diplomacy == true then minetest.chat_send_player(player, "none:") end end - },false,true) + },false) factions.register_command("allies", { description = "Shows the factions that are allied to you.", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local empty = true @@ -781,6 +896,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("neutral", { description = "Shows the factions that are neutral with you.", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local empty = true @@ -798,6 +914,7 @@ if factions_config.faction_diplomacy == true then factions.register_command("enemies", { description = "Shows enemies of your faction", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local empty = true @@ -815,28 +932,59 @@ if factions_config.faction_diplomacy == true then end factions.register_command("who", { - description = "List players in your faction, and their ranks.", - global_privileges = def_global_privileges, + description = "List players in a faction, and their ranks.", + description_arg = " (none | ):", + infaction = false, + global_privileges = def_global_privileges, + format = {"string"}, on_success = function(player, faction, pos, parcelpos, args) - if not faction.players then - minetest.chat_send_player(player, "There is nobody in this faction (" .. faction.name .. ")") - return true - end - - minetest.chat_send_player(player, "Players in faction " .. faction.name .. ": ") - - for p, rank in pairs(faction.players) do - minetest.chat_send_player(player, p .." (" .. rank .. ")") - end + local str = args.strings[1] + if str then + local f = factions.get_faction(str) + + if not f and not f.players then + f = factions.get_player_faction(player) + if not f or not f.players then + minetest.chat_send_player(player, "Your not in a faction.") + return + else + minetest.chat_send_player(player, "Players in faction " .. f.name .. ": ") + for p, rank in pairs(f.players) do + minetest.chat_send_player(player, p .." (" .. rank .. ")") + end + return true + end + else + minetest.chat_send_player(player, "Players in faction " .. f.name .. ": ") + for p, rank in pairs(f.players) do + minetest.chat_send_player(player, p .." (" .. rank .. ")") + end + return true + end + else + local f = factions.get_player_faction(player) + if not f or not f.players then + minetest.chat_send_player(player, "Your not in a faction.") + return + else + minetest.chat_send_player(player, "Players in faction " .. f.name .. ": ") + for p, rank in pairs(f.players) do + minetest.chat_send_player(player, p .." (" .. rank .. ")") + end + return true + end + end + return true end -},false) +},true) local parcel_size_center = factions_config.parcel_size / 2 factions.register_command("show_parcel", { description = "Shows parcel for six seconds.", + description_arg = ":", global_privileges = def_global_privileges, infaction = false, on_success = function(player, faction, pos, parcelpos, args) @@ -858,6 +1006,7 @@ factions.register_command("show_parcel", { factions.register_command("new_rank", { description = "Add a new rank.", + description_arg = " :", format = {"string"}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -904,6 +1053,7 @@ factions.register_command("new_rank", { factions.register_command("replace_privs", { description = "Deletes current permissions and replaces them with the ones given.", + description_arg = " :", format = {"string"}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -950,6 +1100,7 @@ factions.register_command("replace_privs", { factions.register_command("remove_privs", { description = "Remove permissions from a rank.", + description_arg = " :", format = {"string"}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -996,6 +1147,7 @@ factions.register_command("remove_privs", { factions.register_command("add_privs", { description = "add permissions to a rank.", + description_arg = " :", format = {"string"}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -1042,6 +1194,7 @@ factions.register_command("add_privs", { factions.register_command("set_rank_name", { description = "Change the name of given rank.", + description_arg = " :", format = {"string","string"}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -1063,6 +1216,7 @@ factions.register_command("set_rank_name", { factions.register_command("del_rank", { description = "Replace and delete a rank.", + description_arg = " :", format = {"string", "string"}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -1080,6 +1234,7 @@ factions.register_command("del_rank", { factions.register_command("set_def_rank", { description = "Change the default rank given to new players and also replace rankless players in this faction", + description_arg = " :", format = {"string"}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -1096,6 +1251,7 @@ factions.register_command("set_def_rank", { factions.register_command("reset_ranks", { description = "Reset's all of the factions rankings back to the default ones.", + description_arg = ":", format = {}, faction_permissions = {"ranks"}, global_privileges = def_global_privileges, @@ -1105,8 +1261,9 @@ factions.register_command("reset_ranks", { end },false) -factions.register_command("set_spawn", { +factions.register_command("sethome", { description = "Set the faction's spawn", + description_arg = ":", faction_permissions = {"spawn"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) @@ -1115,8 +1272,9 @@ factions.register_command("set_spawn", { end },false) -factions.register_command("del_spawn", { +factions.register_command("unsethome", { description = "Set the faction's spawn to zero", + description_arg = ":", faction_permissions = {"spawn"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) @@ -1126,41 +1284,23 @@ factions.register_command("del_spawn", { },false) if factions_config.spawn_teleport == true then - - local tip = {} - - factions.register_command("tp_spawn", { + factions.register_command("home", { description = "Teleport to the faction's spawn", + description_arg = ":", 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) - factions.tp_spawn(faction.name, player) - tip[player] = nil - end, faction, player) - tip[player] = true - return true + factions.tp_spawn(faction.name, player) 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", { description = "See whose parcel you stand on.", + description_arg = ":", infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) @@ -1173,6 +1313,7 @@ factions.register_command("where", { factions.register_command("help", { description = "Shows help for commands.", + description_arg = ":", infaction = false, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) @@ -1181,13 +1322,14 @@ factions.register_command("help", { end },false) -factions.register_command("get_spawn", { +factions.register_command("gethome", { description = "Shows your faction's spawn", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local spawn = faction.spawn if spawn then - minetest.chat_send_player(player, "Spawn is at (" .. spawn.x .. ", " .. spawn.y .. ", " .. spawn.z .. ")") + minetest.chat_send_player(player, "Home is at (" .. spawn.x .. ", " .. spawn.y .. ", " .. spawn.z .. ")") return true else minetest.chat_send_player(player, "Your faction has no spawn set.") @@ -1198,14 +1340,14 @@ factions.register_command("get_spawn", { factions.register_command("promote", { description = "Promotes a player to a rank", + description_arg = " :", format = {"player", "string"}, faction_permissions = {"promote"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local rank = args.strings[1] if faction.ranks[rank] then - local player_to_promote = args.players[1] - local name = player_to_promote:get_player_name() + local name = args.players[1] local player_faction, facname = factions.get_player_faction(name) @@ -1213,6 +1355,7 @@ factions.register_command("promote", { if player_faction and promoter_facname == facname then factions.promote(faction.name, name, rank) + minetest.chat_send_player(player, "Promoted " .. name .. " to " .. rank .. "!") return true elseif not player_faction or promoter_facname ~= facname then send_error(player, name .. " is not in your faction") @@ -1230,6 +1373,7 @@ factions.register_command("promote", { factions.register_command("power", { description = "Display your faction's power", + description_arg = ":", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local pps = 0 @@ -1251,6 +1395,7 @@ factions.register_command("power", { factions.register_command("free", { description = "Forcefully frees a parcel", + description_arg = ":", infaction = false, global_privileges = {"faction_admin"}, on_success = function(player, faction, pos, parcelpos, args) @@ -1267,7 +1412,7 @@ factions.register_command("free", { factions.register_command("chat", { description = "Send a message to your faction's members", - format = {"string"}, + description_arg = " :", global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local msg = table.concat(args.strings, " ") @@ -1275,21 +1420,27 @@ factions.register_command("chat", { end },true) -factions.register_command("forceupdate", { +factions.register_command("force_update", { description = "Forces an update tick.", + description_arg = ":", global_privileges = {"faction_admin"}, + infaction = false, on_success = function(player, faction, pos, parcelpos, args) factions.faction_tick() end },false) -factions.register_command("which", { - description = "Gets a player's faction", +factions.register_command("player", { + description = "Get which faction a player is in", + description_arg = " :", infaction = false, format = {"string"}, global_privileges = def_global_privileges, on_success = function(player, faction, pos, parcelpos, args) local playername = args.strings[1] + if not playername then + playername = player + end local faction1, facname = factions.get_player_faction(playername) if not faction1 then send_error(player, "Player " .. playername .. " does not belong to any faction") @@ -1299,19 +1450,21 @@ factions.register_command("which", { return true end end -},false) +},true) factions.register_command("set_leader", { description = "Set a player as a faction's leader", + description_arg = " :", infaction = false, global_privileges = {"faction_admin"}, format = {"faction", "player"}, on_success = function(player, faction, pos, parcelpos, args) - local playername = args.players[1]:get_player_name() + local playername = args.players[1] local playerfaction, facname = factions.get_player_faction(playername) local targetfaction = args.factions[1] - if playername ~= targetname then - send_error(player, "Player " .. playername .. " is not in faction " .. targetname .. ".") + + if facname ~= targetfaction.name then + send_error(player, "Player " .. playername .. " is not in faction " .. targetfaction.name .. ".") return false end factions.set_leader(targetfaction.name, playername) @@ -1321,6 +1474,7 @@ factions.register_command("set_leader", { factions.register_command("set_admin", { description = "Make a faction an admin faction", + description_arg = " :", infaction = false, global_privileges = {"faction_admin"}, format = {"faction"}, @@ -1341,6 +1495,7 @@ factions.register_command("set_admin", { factions.register_command("remove_admin", { description = "Make a faction not an admin faction", + description_arg = " :", infaction = false, global_privileges = {"faction_admin"}, format = {"faction"}, @@ -1360,6 +1515,7 @@ factions.register_command("remove_admin", { factions.register_command("reset_power", { description = "Reset a faction's power", + description_arg = " :", infaction = false, global_privileges = {"faction_admin"}, format = {"faction"}, @@ -1375,6 +1531,7 @@ factions.register_command("reset_power", { factions.register_command("obliterate", { description = "Remove all factions", + description_arg = ":", infaction = false, global_privileges = {"faction_admin"}, on_success = function(player, faction, pos, parcelpos, args) @@ -1387,6 +1544,7 @@ factions.register_command("obliterate", { factions.register_command("get_factions_spawn", { description = "Get a faction's spawn", + description_arg = " :", infaction = false, global_privileges = {"faction_admin"}, format = {"faction"}, @@ -1402,23 +1560,9 @@ factions.register_command("get_factions_spawn", { end },false) -factions.register_command("whoin", { - description = "Get all members of a faction", - infaction = false, - global_privileges = def_global_privileges, - format = {"faction"}, - on_success = function(player, faction, pos, parcelpos, args) - local msg = {} - for player, _ in pairs(args.factions[1].players) do - table.insert(msg, player) - end - minetest.chat_send_player(player, table.concat(msg, ", ")) - return true - end -},false) - factions.register_command("stats", { description = "Get stats of a faction", + description_arg = " :", infaction = false, global_privileges = def_global_privileges, format = {"faction"}, @@ -1426,10 +1570,10 @@ factions.register_command("stats", { local f = args.factions[1] local pps = 0 if factions_config.enable_power_per_player then - if factions.onlineplayers[faction.name] == nil then - factions.onlineplayers[faction.name] = {} + if factions.onlineplayers[f.name] == nil then + factions.onlineplayers[f.name] = {} end - local t = factions.onlineplayers[faction.name] + local t = factions.onlineplayers[f.name] local count = 0 for _ in pairs(t) do count = count + 1 end pps = factions_config.power_per_player * count @@ -1443,6 +1587,7 @@ factions.register_command("stats", { factions.register_command("seen", { description = "Check the last time a faction had a member logged in", + description_arg = " :", infaction = false, global_privileges = def_global_privileges, format = {"faction"}, @@ -1460,7 +1605,7 @@ factions.register_command("seen", { },false) ------------------------------------------------------------------------------- --- name: cmdhandler(playername,parameter) +-- name: cmdhandler(playername, parameter) -- --! @brief chat command handler --! @memberof factions_chat @@ -1478,7 +1623,7 @@ factions_chat.cmdhandler = function (playername,parameter) if parameter == nil or parameter == "" then if player_faction then - minetest.chat_send_player(playername, "You are in faction "..player_name..". Type /f help for a list of commands.") + minetest.chat_send_player(playername, "You are in faction " .. player_faction.name .. ". Type /f help for a list of commands.") else minetest.chat_send_player(playername, "You are part of no faction") end @@ -1500,7 +1645,7 @@ factions_chat.cmdhandler = function (playername,parameter) end -function table_Contains(t,v) +function table_Contains(t, v) for k, a in pairs(t) do if a == v then return true @@ -1509,8 +1654,29 @@ function table_Contains(t,v) return false end +local premade_help = "" + +local premade_help_admin = "" + +local a_z = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"} + +for l, j in pairs(a_z) do + for k, v in pairs(factions.commands) do + if k:sub(1, 1) == j then + if not v.dont_show_in_help then + if not table_Contains(v.global_privileges, "faction_admin") then + premade_help = premade_help .. "\t/f " .. k .. v.description_arg .. " " .. v.description .. "\n" + end + premade_help_admin = premade_help_admin .. "\t/f " .. k .. v.description_arg .. " " .. v.description .. "\n" + end + end + end +end + +a_z = nil + ------------------------------------------------------------------------------- --- name: show_help(playername,parameter) +-- name: show_help(playername, parameter) -- --! @brief send help message to player --! @memberof factions_chat @@ -1521,23 +1687,18 @@ end function factions_chat.show_help(playername) local MSG = function(text) - minetest.chat_send_player(playername,text,false) + minetest.chat_send_player(playername, text, false) end MSG("factions mod") MSG("Usage:") local has, missing = minetest.check_player_privs(playername, { faction_admin = true}) - - for k, v in pairs(factions.commands) do - local args = {} - if has or not table_Contains(v.global_privileges,"faction_admin") then - for i in ipairs(v.format) do - table.insert(args, v.format[i]) - end - MSG("\t/factions "..k.." <"..table.concat(args, "> <").."> : "..v.description) - end - end + if has then + MSG(premade_help_admin) + else + MSG(premade_help) + end end init_commands() diff --git a/claim_events.lua b/claim_events.lua new file mode 100644 index 0000000..f9646ba --- /dev/null +++ b/claim_events.lua @@ -0,0 +1,422 @@ +--! @param parcelpos position of the wanted parcel +--! @return whether this faction can claim a parcelpos +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 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.claim_parcel(name, parcelpos) + -- check if claiming over other faction's territory + local otherfac = factions.parcels.get(parcelpos) + if otherfac then + factions.unclaim_parcel(otherfac, parcelpos) + factions.parcelless_check(otherfac) + end + 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.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.parcelless_check(name) + local faction = factions.factions.get(name) + + if faction.land then + local count = 0 + for index, value in pairs(faction.land) do + count = count + 1 + break + end + if count > 0 then + if faction.no_parcel ~= -1 then + factions.broadcast(name, "Faction " .. name .. " will not be disbanded because it now has parcels.") + end + faction.no_parcel = -1 + else + faction.no_parcel = os.time() + factions.on_no_parcel(name) + end + factions.factions.set(name, faction) + end +end + +function factions.get_parcel_faction(parcelpos) + local facname = factions.parcels.get(parcelpos) + if facname then + local faction = factions.factions.get(facname) + return faction, facname + end + return nil +end + +function claim_helper(player, faction, parcelpos, no_msgs) + faction = factions.factions.get(faction.name) + if not faction then + return false + end + if faction.power < factions_config.power_per_parcel then + if not no_msgs then + minetest.chat_send_player(player, "Not enough power.") + end + return false + end + local p = parcelpos + local can_claim = factions.can_claim_parcel(faction.name, p) + + if can_claim then + minetest.chat_send_player(player, "Claming parcel " .. p) + factions.claim_parcel(faction.name, p) + return true + else + local parcel_faction = factions.get_parcel_faction(p) + if parcel_faction and parcel_faction.name == faction.name then + if not no_msgs then + minetest.chat_send_player(player, "This parcel already belongs to your faction") + end + return false + elseif parcel_faction and parcel_faction.name ~= faction.name then + if not no_msgs then + minetest.chat_send_player(player, "This parcel belongs to another faction") + end + return false + else + if not no_msgs then + minetest.chat_send_player(player, "Your faction cannot claim any (more) parcel(s).") + end + return false + end + end +end + +function unclaim_helper(player, faction, parcelpos, no_msgs) + faction = factions.factions.get(faction.name) + if not faction then + return false + end + local parcel_faction = factions.get_parcel_faction(parcelpos) + if not parcel_faction then + if not no_msgs then + minetest.chat_send_player(player, "This parcel does not exist.") + end + return false + end + if parcel_faction.name ~= faction.name then + if not no_msgs then + minetest.chat_send_player(player, "This parcel does not belong to you.") + end + return false + else + factions.unclaim_parcel(faction.name, parcelpos) + return true + end +end + +local parcel_size = factions_config.parcel_size + +function factions.claim_square(player, faction, r) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = math.floor(pos.x / parcel_size) * parcel_size + pos.z = math.floor(pos.z / parcel_size) * parcel_size + + pos.x = pos.x - (parcel_size * (r - math.floor(r / 2))) + pos.z = pos.z - (parcel_size * (r - math.floor(r / 2))) + + local timer = 0 + + for i = 1, r do + for l = 1, r do + local p = {x = pos.x + (parcel_size * l), y = pos.y, z = pos.z + (parcel_size * i)} + minetest.after(timer, claim_helper, player, faction, factions.get_parcel_pos(p), true) + + timer = timer + 0.1 + end + end +end + +local auto_list = {} + +local function _claim_auto(player, faction) + if auto_list[player] then + local rplayer = minetest.get_player_by_name(player) + local parcelpos = vector.round(rplayer:get_pos()) + claim_helper(player, faction, factions.get_parcel_pos(parcelpos), true) + minetest.after(0.1, _claim_auto, player, faction) + end +end + +function factions.claim_auto(player, faction) + if auto_list[player] then + auto_list[player] = nil + minetest.chat_send_player(player, "Auto claim disabled.") + else + auto_list[player] = true + minetest.chat_send_player(player, "Auto claim enabled.") + _claim_auto(player, faction) + end +end + +local function _claim_fill(player, faction, pos) + if claim_helper(player, faction, factions.get_parcel_pos(pos), true) then + local pos1 = {x = pos.x - parcel_size, y = pos.y, z = pos.z} + minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos1) + local pos2 = {x = pos.x + parcel_size, y = pos.y, z = pos.z} + minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos2) + local pos3 = {x = pos.x, y = pos.y, z = pos.z - parcel_size} + minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos3) + local pos4 = {x = pos.x, y = pos.y, z = pos.z + parcel_size} + minetest.after(math.random(0, 11) / 10, _claim_fill, player, faction, pos4) + end +end + +function factions.claim_fill(player, faction) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = math.floor(pos.x / parcel_size) * parcel_size + pos.z = math.floor(pos.z / parcel_size) * parcel_size + + _claim_fill(player, faction, pos) +end + +local parcel_size_center = parcel_size / 2 + +function factions.claim_circle(player, faction, r) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = (math.floor(pos.x / parcel_size) * parcel_size) + parcel_size_center + pos.z = (math.floor(pos.z / parcel_size) * parcel_size) + parcel_size_center + + for i = 1, 360 do + minetest.after(0.05 * i, function(player, faction, r, pos) + + local angle = i * math.pi / 180 + + local rpos = {x = pos.x + r * math.cos(angle), y = pos.y, z = pos.z + r * math.sin(angle)} + + claim_helper(player, faction, factions.get_parcel_pos(rpos), true) + + end, player, faction, r, pos) + end +end + +local function _claim_all(player, faction, pos) + if faction.power >= factions_config.power_per_parcel then + claim_helper(player, faction, factions.get_parcel_pos(pos), true) + local pos1 = {x = pos.x - parcel_size, y = pos.y, z = pos.z} + minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos1) + local pos2 = {x = pos.x + parcel_size, y = pos.y, z = pos.z} + minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos2) + local pos3 = {x = pos.x, y = pos.y, z = pos.z - parcel_size} + minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos3) + local pos4 = {x = pos.x, y = pos.y, z = pos.z + parcel_size} + minetest.after(math.random(0, 11) / 10, _claim_all, player, faction, pos4) + end +end + +function factions.claim_all(player, faction) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = math.floor(pos.x / parcel_size) * parcel_size + pos.z = math.floor(pos.z / parcel_size) * parcel_size + + _claim_all(player, faction, pos) +end + +function factions.claim_help(player, func) + local text = ", " + + if func == "o" or func == "one" then + text = "/f claim o\n/f claim one\n Claim one parcel." + elseif func == "a" or func == "auto" then + text = "/f claim a\n/f claim auto\nClaim as you walk around." + elseif func == "f" or func == "fill" then + text = "/f claim f\n/f claim fill\nClaim by filling." + elseif func == "s" or func == "square" then + text = "/f claim s \n/f claim square \nClaim by square and radius." + elseif func == "c" or func == "circle" then + text = "/f claim c \n/f claim circle \nClaim by circle and radius." + elseif func == "all" then + text = "/f claim all\nClaim all faction land." + end + + minetest.chat_send_player(player, text) +end + +function factions.unclaim_square(player, faction, r) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = math.floor(pos.x / parcel_size) * parcel_size + pos.z = math.floor(pos.z / parcel_size) * parcel_size + + pos.x = pos.x - (parcel_size * (r - math.floor(r / 2))) + pos.z = pos.z - (parcel_size * (r - math.floor(r / 2))) + + local timer = 0 + + for i = 1, r do + for l = 1, r do + local p = {x = pos.x + (parcel_size * l), y = pos.y, z = pos.z + (parcel_size * i)} + minetest.after(timer, unclaim_helper, player, faction, factions.get_parcel_pos(p), true) + + timer = timer + 0.1 + end + end +end + +local function _unclaim_auto(player, faction) + if auto_list[player] then + local rplayer = minetest.get_player_by_name(player) + local parcelpos = vector.round(rplayer:get_pos()) + unclaim_helper(player, faction, factions.get_parcel_pos(parcelpos), true) + minetest.after(0.1, _unclaim_auto, player, faction) + end +end + +function factions.unclaim_auto(player, faction) + if auto_list[player] then + auto_list[player] = nil + minetest.chat_send_player(player, "Auto unclaim disabled.") + else + auto_list[player] = true + minetest.chat_send_player(player, "Auto unclaim enabled.") + _unclaim_auto(player, faction) + end +end + +local function _unclaim_fill(player, faction, pos) + if unclaim_helper(player, faction, factions.get_parcel_pos(pos), true) then + local pos1 = {x = pos.x - parcel_size, y = pos.y, z = pos.z} + minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos1) + local pos2 = {x = pos.x + parcel_size, y = pos.y, z = pos.z} + minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos2) + local pos3 = {x = pos.x, y = pos.y, z = pos.z - parcel_size} + minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos3) + local pos4 = {x = pos.x, y = pos.y, z = pos.z + parcel_size} + minetest.after(math.random(0, 11) / 10, _unclaim_fill, player, faction, pos4) + end +end + +function factions.unclaim_fill(player, faction) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = math.floor(pos.x / parcel_size) * parcel_size + pos.z = math.floor(pos.z / parcel_size) * parcel_size + + _unclaim_fill(player, faction, pos) +end + +local parcel_size_center = parcel_size / 2 + +function factions.unclaim_circle(player, faction, r) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = (math.floor(pos.x / parcel_size) * parcel_size) + parcel_size_center + pos.z = (math.floor(pos.z / parcel_size) * parcel_size) + parcel_size_center + + for i = 1, 360 do + minetest.after(0.05 * i, function(player, faction, r, pos) + + local angle = i * math.pi / 180 + + local rpos = {x = pos.x + r * math.cos(angle), y = pos.y, z = pos.z + r * math.sin(angle)} + + unclaim_helper(player, faction, factions.get_parcel_pos(rpos), true) + + end, player, faction, r, pos) + end +end + +local function _unclaim_all(player, faction) + local timer = 0 + for i in pairs(faction.land) do + minetest.after(timer, factions.unclaim_parcel, faction.name, i) + timer = timer + 0.1 + end +end + +function factions.unclaim_all(player, faction) + local rplayer = minetest.get_player_by_name(player) + local pos = vector.round(rplayer:get_pos()) + + pos.x = math.floor(pos.x / parcel_size) * parcel_size + pos.z = math.floor(pos.z / parcel_size) * parcel_size + + _unclaim_all(player, faction, pos) +end + +function factions.unclaim_help(player, func) + local text = ", " + + if func == "o" or func == "one" then + text = "/f unclaim o\n/f unclaim one\n Unclaim one parcel." + elseif func == "a" or func == "auto" then + text = "/f unclaim a\n/f unclaim auto\nUnclaim as you walk around." + elseif func == "f" or func == "fill" then + text = "/f unclaim f\n/f unclaim fill\nUnclaim by filling." + elseif func == "s" or func == "square" then + text = "/f unclaim s \n/f unclaim square \nUnclaim by square and radius." + elseif func == "c" or func == "circle" then + text = "/f unclaim c \n/f unclaim circle \nUnclaim by circle and radius." + elseif func == "all" then + text = "/f unclaim all\nUnclaim all faction land." + end + + minetest.chat_send_player(player, text) +end + +minetest.register_on_leaveplayer( + function(player) + auto_list[player:get_player_name()] = nil + end +) \ No newline at end of file diff --git a/databases.lua b/databases.lua new file mode 100644 index 0000000..d721a02 --- /dev/null +++ b/databases.lua @@ -0,0 +1,12 @@ +--! @class factions +--! @brief main class for factions +factions = {} + +-- Create cold databases. +factions.factions = colddb.Colddb(minetest.get_worldpath() .. "/factions/factions") +factions.parcels = colddb.Colddb(minetest.get_worldpath() .. "/factions/parcels") +factions.players = colddb.Colddb(minetest.get_worldpath() .. "/factions/players") +factions.player_ips = colddb.Colddb(minetest.get_worldpath() .. "/factions/ips") + +-- Memory only storage. +factions.onlineplayers = {} diff --git a/depends.txt b/depends.txt index 5867cba..2446a29 100644 --- a/depends.txt +++ b/depends.txt @@ -2,3 +2,4 @@ default? doors? xdecor? colddb +ts_doors? diff --git a/diplomacy_events.lua b/diplomacy_events.lua new file mode 100644 index 0000000..54b510d --- /dev/null +++ b/diplomacy_events.lua @@ -0,0 +1,89 @@ +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 + 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.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 bfaction.neutral[faction] then + factions.end_neutral(name, faction) + end + + factions.factions.set(name, bfaction) +end + +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.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 bfaction.enemies[faction] then + factions.end_enemy(name, faction) + end + + factions.factions.set(name, bfaction) +end + +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.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 bfaction.neutral[faction] then + factions.end_neutral(name, faction) + end + + factions.factions.set(name, bfaction) +end + +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 \ No newline at end of file diff --git a/eventcallbacks.lua b/eventcallbacks.lua new file mode 100644 index 0000000..f41e843 --- /dev/null +++ b/eventcallbacks.lua @@ -0,0 +1,136 @@ +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.on_set_name(name, oldname) + minetest.chat_send_all("Faction " .. oldname .. " has been changed its name to ".. name ..".") +end + +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 + + factions.broadcast(name, "This faction will disband in " .. l - now .. " seconds, because it has no parcels.") +end + +function factions.on_player_leave(name, player) + factions.broadcast(name, player .. " has left this faction") +end + +function factions.on_player_join(name, player) + factions.broadcast(name, player .. " has joined this faction") +end + +function factions.on_claim_parcel(name, pos) + factions.broadcast(name, "Parcel (" .. pos .. ") has been claimed.") +end + +function factions.on_unclaim_parcel(name, pos) + factions.broadcast(name, "Parcel ("..pos..") has been unclaimed.") +end + +function factions.on_disband(name, reason) + local msg = "Faction " .. name .. " has been disbanded." + if reason then + msg = msg .. " (" .. reason .. ")" + end + minetest.chat_send_all(msg) +end + +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.on_change_description(name) + local faction = factions.factions.get(name) + factions.broadcast(name, "Faction description has been modified to: " .. faction.description) +end + +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.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 + factions.broadcast(name, "This faction is no longer invite-free.") + end +end + +function factions.on_new_alliance(name, faction) + factions.broadcast(name, "This faction is now allied with " .. faction) +end + +function factions.on_end_alliance(name, faction) + factions.broadcast(name, "This faction is no longer allied with " .. faction .. "!") +end + +function factions.on_new_neutral(name, faction) + factions.broadcast(name, "This faction is now neutral with ".. faction) +end + +function factions.on_end_neutral(name, faction) + factions.broadcast(name, "This faction is no longer neutral with " .. faction .. "!") +end + +function factions.on_new_enemy(name, faction) + factions.broadcast(name, "This faction is now at war with " .. faction) +end + +function factions.on_end_enemy(name, faction) + factions.broadcast(name, "This faction is no longer at war with " .. faction .. "!") +end + +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.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.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.on_remove_privs(name, rank, privs) + factions.broadcast(name, "The privileges in rank " .. rank .. " have been revoked: " .. table.concat(privs, ", ")) +end + +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.on_set_rank_name(name, rank,newrank) + factions.broadcast(name, "The name of rank " .. rank .. " has been changed to " .. newrank) +end + +function factions.on_delete_rank(name, rank, newrank) + factions.broadcast(name, "The rank " .. rank .. " has been deleted and replaced by " .. newrank) +end + +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.on_reset_ranks(name) + factions.broadcast(name, "All of the faction's ranks have been reset to the default ones.") +end + +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.on_revoke_invite(name, player) + minetest.chat_send_player(player, "You are no longer invited to faction " .. name) +end diff --git a/factions.lua b/factions.lua index 5f159d9..95ab891 100644 --- a/factions.lua +++ b/factions.lua @@ -1,16 +1,3 @@ ---! @class factions ---! @brief main class for factions -factions = {} - --- 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) --! @param name String containing the faction's name @@ -32,8 +19,8 @@ util = { } 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"}, + , "spawn", "with_draw", "territory", "claim", "access", "disband", "flags", "ranks", "promote"}, + ["moderator"] = {"claim", "door", "build", "spawn", "invite", "kick", "promote", "container"}, ["member"] = {"build", "container", "door"} } @@ -48,7 +35,6 @@ starting_ranks = {["leader"] = {"build", "door", "container", "name", "descripti -- motd: set the faction's message of the day -- invite: (un)invite players to join the faction -- kick: kick players off the faction --- player_title: set player titles -- spawn: set the faction's spawn -- with_draw: withdraw money from the faction's bank -- territory: claim or unclaim territory @@ -61,7 +47,7 @@ starting_ranks = {["leader"] = {"build", "door", "container", "name", "descripti -- diplomacy: be able to control the faction's diplomacy factions.permissions = {"build", "pain_build", "door", "container", "name", "description", "motd", "invite", "kick" - , "player_title", "spawn", "with_draw", "territory", "claim", "access", "disband", "flags", "ranks", "promote"} + , "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" @@ -152,21 +138,6 @@ function factions.new_faction(name) return faction end -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 - 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.set_name(oldname, name) local faction = factions.factions.get(oldname) faction.name = name @@ -222,88 +193,6 @@ function factions.set_name(oldname, name) end -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(factions.onlineplayers[name]) do - updateHudPower(minetest.get_player_by_name(i), faction) - end - - factions.factions.set(name, faction) -end - -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.factions.set(name, faction) -end - -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.factions.set(name, faction) -end - -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(factions.onlineplayers[name]) do - updateHudPower(minetest.get_player_by_name(i), faction) - end - - factions.factions.set(name, faction) -end - -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.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(factions.onlineplayers[name]) do - updateHudPower(minetest.get_player_by_name(i), faction) - end - - factions.factions.set(name, faction) -end - function factions.count_land(name) local count = 0. for k, v in pairs(factions.factions.get(name).land) do @@ -312,10 +201,6 @@ function factions.count_land(name) return count end -minetest.register_on_prejoinplayer(function(name, ip) - factions.player_ips.set(name, ip) -end) - function factions.add_player(name, player, rank) local faction = factions.factions.get(name) @@ -346,10 +231,12 @@ function factions.add_player(name, player, 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, name) - createHudPower(pdata, faction) + if pdata then + local ipc = pdata:is_player_connected(player) + if ipc then + createHudFactionName(pdata, name) + createHudPower(pdata, faction) + end end factions.factions.set(name, faction) @@ -395,11 +282,13 @@ function factions.remove_player(name, player) 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") + if pdata then + local ipc = pdata:is_player_connected(player) + + if ipc then + removeHud(pdata,"factionName") + removeHud(pdata,"powerWatch") + end end factions.check_players_in_faction(name) @@ -407,92 +296,6 @@ 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.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 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.claim_parcel(name, parcelpos) - -- check if claiming over other faction's territory - local otherfac = factions.parcels.get(parcelpos) - if otherfac then - factions.unclaim_parcel(otherfac, parcelpos) - factions.parcelless_check(otherfac) - end - 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.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.parcelless_check(name) - local faction = factions.factions.get(name) - - if faction.land then - local count = 0 - for index, value in pairs(faction.land) do - count = count + 1 - break - end - if count > 0 then - if faction.no_parcel ~= -1 then - factions.broadcast(name, "Faction " .. name .. " will not be disbanded because it now has parcels.") - end - faction.no_parcel = -1 - else - 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.disband(name, reason) local faction = factions.factions.get(name) @@ -530,13 +333,15 @@ function factions.disband(name, reason) factions.on_disband(name, reason) - for i, l in pairs(factions.onlineplayers[name]) do - removeHud(i, "factionName") - removeHud(i, "powerWatch") + if factions.onlineplayers ~= nil and factions.onlineplayers[name] ~= nil then + for i, l in pairs(factions.onlineplayers[name]) do + removeHud(i, "factionName") + removeHud(i, "powerWatch") + end + + factions.onlineplayers[name] = nil end - factions.onlineplayers[name] = nil - factions.factions.remove(name) end end @@ -591,25 +396,6 @@ function factions.set_description(name, new) factions.factions.set(name, faction) end ---! @brief places player in invite list -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.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.toggle_join_free(name, bool) local faction = factions.factions.get(name) @@ -626,81 +412,6 @@ function factions.can_join(name, player) return faction.join_free or faction.invited_players[player] end -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 bfaction.neutral[faction] then - factions.end_neutral(name, faction) - end - - factions.factions.set(name, bfaction) -end - -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.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 bfaction.enemies[faction] then - factions.end_enemy(name, faction) - end - - factions.factions.set(name, bfaction) -end - -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.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 bfaction.neutral[faction] then - factions.end_neutral(name, faction) - end - - factions.factions.set(name, bfaction) -end - -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.set_spawn(name, pos) local faction = factions.factions.get(name) @@ -718,178 +429,10 @@ function factions.tp_spawn(name, playername) if player then player:set_pos(faction.spawn) + minetest.sound_play("whoosh", {pos = faction.spawn, gain = 0.5, max_hear_distance = 10}) 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.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.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.remove_privs(name, rank, perms) - local faction = factions.factions.get(name) - - local revoked = false - local p = faction.ranks[rank] - - for index, perm in pairs(p) do - if table_Contains(perms, perm) then - revoked = true - table.remove(p, index) - end - end - - faction.ranks[rank] = p - - if revoked then - factions.on_remove_privs(name, rank, perms) - else - factions.broadcast(name, "No privilege was revoked from rank " .. rank .. ".") - end - - factions.factions.set(name, faction) -end - -function factions.add_privs(name, rank, perms) - local faction = factions.factions.get(name) - - local added = false - local p = faction.ranks[rank] - - for index, perm in pairs(perms) do - if not table_Contains(p, perm) then - added = true - table.insert(p, perm) - end - end - - faction.ranks[rank] = p - - if added then - factions.on_add_privs(name, rank, perms) - else - factions.broadcast(name, "The rank " .. rank .. " already has these privileges.") - end - - factions.factions.set(name, faction) -end - -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 - faction.players[player] = newrank - end - end - - 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 == faction.default_rank then - faction.default_rank = newrank - factions.broadcast(name, "The default rank given to new players is set to " .. newrank) - end - - factions.on_set_rank_name(name, oldrank, newrank) - - factions.factions.set(name, faction) -end - -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 - - faction.default_rank = rank - factions.on_set_def_rank(name, rank) - - factions.factions.set(name, faction) -end - -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 - faction.players[player] = faction.default_leader_rank_rank - end - end - 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.delete_rank(name, rank, newrank) - local faction = factions.factions.get(name) - - for player, r in pairs(faction.players) do - if r == rank then - faction.players[player] = newrank - end - end - 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 == faction.default_rank then - faction.default_rank = newrank - factions.broadcast(name, "The default rank given to new players is set to "..newrank) - end - - factions.factions.set(name, faction) -end - ---! @brief set a player's rank -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.broadcast(name, msg, sender) if factions.onlineplayers[name] == nil then @@ -903,6 +446,9 @@ function factions.broadcast(name, msg, sender) end message = "Faction<" .. message + + minetest.log(message) + for k, _ in pairs(factions.onlineplayers[name]) do minetest.chat_send_player(k, message) end @@ -919,146 +465,6 @@ function factions.is_online(name) return false end --------------------------- --- callbacks for events -- - -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.on_set_name(name, oldname) - minetest.chat_send_all("Faction " .. oldname .. " has been changed its name to ".. name ..".") -end - -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 - - factions.broadcast(name, "This faction will disband in " .. l - now .. " seconds, because it has no parcels.") -end - -function factions.on_player_leave(name, player) - factions.broadcast(name, player .. " has left this faction") -end - -function factions.on_player_join(name, player) - factions.broadcast(name, player .. " has joined this faction") -end - -function factions.on_claim_parcel(name, pos) - factions.broadcast(name, "Parcel (" .. pos .. ") has been claimed.") -end - -function factions.on_unclaim_parcel(name, pos) - factions.broadcast(name, "Parcel ("..pos..") has been unclaimed.") -end - -function factions.on_disband(name, reason) - local msg = "Faction " .. name .. " has been disbanded." - if reason then - msg = msg .. " (" .. reason .. ")" - end - minetest.chat_send_all(msg) -end - -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.on_change_description(name) - local faction = factions.factions.get(name) - factions.broadcast(name, "Faction description has been modified to: " .. faction.description) -end - -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.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 - factions.broadcast(name, "This faction is no longer invite-free.") - end -end - -function factions.on_new_alliance(name, faction) - factions.broadcast(name, "This faction is now allied with " .. faction) -end - -function factions.on_end_alliance(name, faction) - factions.broadcast(name, "This faction is no longer allied with " .. faction .. "!") -end - -function factions.on_new_neutral(name, faction) - factions.broadcast(name, "This faction is now neutral with ".. faction) -end - -function factions.on_end_neutral(name, faction) - factions.broadcast(name, "This faction is no longer neutral with " .. faction .. "!") -end - -function factions.on_new_enemy(name, faction) - factions.broadcast(name, "This faction is now at war with " .. faction) -end - -function factions.on_end_enemy(name, faction) - factions.broadcast(name, "This faction is no longer at war with " .. faction .. "!") -end - -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.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.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.on_remove_privs(name, rank, privs) - factions.broadcast(name, "The privileges in rank " .. rank .. " have been revoked: " .. table.concat(privs, ", ")) -end - -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.on_set_rank_name(name, rank,newrank) - factions.broadcast(name, "The name of rank " .. rank .. " has been changed to " .. newrank) -end - -function factions.on_delete_rank(name, rank, newrank) - factions.broadcast(name, "The rank " .. rank .. " has been deleted and replaced by " .. newrank) -end - -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.on_reset_ranks(name) - factions.broadcast(name, "All of the faction's ranks have been reset to the default ones.") -end - -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.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 / parcel_size) * parcel_size .. "," .. math.floor(pos.z / parcel_size) * parcel_size @@ -1076,15 +482,6 @@ function factions.get_player_faction(playername) return nil end -function factions.get_parcel_faction(parcelpos) - local facname = factions.parcels.get(parcelpos) - if facname then - local faction = factions.factions.get(facname) - return faction, facname - end - return nil -end - function factions.get_faction(facname) return factions.factions.get(facname) end @@ -1110,17 +507,6 @@ function factions.get_faction_list() return names end -minetest.register_on_dieplayer( -function(player) - local faction, name = factions.get_player_faction(player:get_player_name()) - if not faction then - return true - end - factions.decrease_power(name, factions_config.power_per_death) - return true -end -) - function factions.faction_tick() local now = os.time() for i, facname in pairs(factions.get_faction_list()) do @@ -1149,119 +535,6 @@ function factions.faction_tick() end end -minetest.register_on_joinplayer( -function(player) - local name = player:get_player_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() - - 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.") - 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) - end - end - -end -) - -minetest.register_on_leaveplayer( - function(player) - local name = player:get_player_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 - hud_ids[id_name2] = nil - end - if hud_ids[id_name3] then - hud_ids[id_name3] = nil - end - end - end -) - -minetest.register_on_respawnplayer( - function(player) - 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: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, 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_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 (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 (factions.has_permission(player_fac_name, player, "build") or factions.has_permission(player_fac_name, player, "pain_build")) - else - return true - end - else - return true - end -end - function factionUpdate() factions.faction_tick() minetest.after(factions_config.tick_time, factionUpdate) diff --git a/init.lua b/init.lua index b9a3ce6..0e1cd81 100644 --- a/init.lua +++ b/init.lua @@ -2,7 +2,16 @@ factions_modpath = minetest.get_modpath("factions") dofile (factions_modpath .. "/config.lua") +dofile (factions_modpath .. "/databases.lua") +dofile (factions_modpath .. "/eventcallbacks.lua") +dofile (factions_modpath .. "/diplomacy_events.lua") +dofile (factions_modpath .. "/invite_events.lua") +dofile (factions_modpath .. "/player_events.lua") +dofile (factions_modpath .. "/power_events.lua") +dofile (factions_modpath .. "/protection_override.lua") +dofile (factions_modpath .. "/rank_events.lua") dofile (factions_modpath .. "/hud.lua") +dofile (factions_modpath .. "/claim_events.lua") dofile (factions_modpath .. "/factions.lua") dofile (factions_modpath .. "/chatcommands.lua") dofile (factions_modpath .. "/nodes.lua") diff --git a/invite_events.lua b/invite_events.lua new file mode 100644 index 0000000..94b5d0b --- /dev/null +++ b/invite_events.lua @@ -0,0 +1,19 @@ +--! @brief places player in invite list +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.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 diff --git a/nodes.lua b/nodes.lua index e48fd5c..467f3d5 100644 --- a/nodes.lua +++ b/nodes.lua @@ -39,7 +39,7 @@ if minetest.registered_nodes["default:chest"] then local meta = minetest.get_meta(pos) local name = parcel_faction.name meta:set_string("faction", name) - meta:set_string("infotext", "Faction Chest (owned by faction " .. + meta:set_string("infotext", "Faction Container (owned by faction " .. name .. ")") end end @@ -75,18 +75,51 @@ if minetest.registered_nodes["default:chest"] then return def_on_rightclick(pos, node, clicker, itemstack, pointed_thing) end 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}) + 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 +local door_items = {"doors:door_wood", "doors:door_steel", "doors:door_glass", "doors:door_obsidian_glass", "doors:woodglass_door", "doors:slide_door", + "doors:screen_door", "doors:rusty_prison_door", "doors:prison_door", "doors:japanese_door", "ts_doors:door_default_aspen_wood", "ts_doors:door_full_default_aspen_wood", + "ts_doors:door_default_pine_wood", "ts_doors:door_full_default_pine_wood", "ts_doors:door_default_acacia_wood", "ts_doors:door_full_default_acacia_wood", + "ts_doors:door_default_wood", "ts_doors:door_full_default_wood", "ts_doors:door_default_junglewood", "ts_doors:door_full_default_junglewood", + "ts_doors:door_default_bronzeblock", "ts_doors:door_full_default_bronzeblock", "ts_doors:door_default_copperblock", "ts_doors:door_full_default_copperblock", + "ts_doors:door_default_diamondblock", "ts_doors:door_full_default_diamondblock", "ts_doors:door_full_default_goldblock", "ts_doors:door_default_steelblock", "ts_doors:door_full_default_steelblock"} + +local trapdoor_items = {"doors:trapdoor", "doors:trapdoor_steel", "ts_doors:trapdoor_default_aspen_wood", "ts_doors:trapdoor_full_default_aspen_wood", + "ts_doors:trapdoor_default_wood", "ts_doors:trapdoor_full_default_wood", "ts_doors:trapdoor_default_acacia_wood", "ts_doors:trapdoor_full_default_acacia_wood", + "ts_doors:trapdoor_default_bronzeblock", "ts_doors:trapdoor_full_default_bronzeblock", "ts_doors:trapdoor_default_copperblock", "ts_doors:trapdoor_full_default_copperblock", "ts_doors:trapdoor_full_default_diamondblock", + "ts_doors:door_default_goldblock", "ts_doors:trapdoor_default_steelblock", "ts_doors:trapdoor_full_default_steelblock", "ts_doors:trapdoor_default_pine_wood", "ts_doors:trapdoor_full_default_pine_wood", + "ts_doors:trapdoor_full_default_goldblock", "ts_doors:trapdoor_default_junglewood", "ts_doors:trapdoor_full_default_junglewood", + "ts_doors:trapdoor_default_diamondblock", "ts_doors:trapdoor_default_goldblock"} + -- 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", - "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"} +local doors = {} + +local all_items = {} + +local item_count = 1 + +local old_i = 0 + +for i, l in ipairs(door_items) do + doors[item_count] = l .. "_a" + doors[item_count + 1] = l .. "_b" + all_items[i] = l + item_count = item_count + 2 + old_i = old_i + 1 +end + +for i, l in ipairs(trapdoor_items) do + doors[item_count] = l + doors[item_count + 1] = l .. "_open" + all_items[old_i + i] = l + item_count = item_count + 2 +end + for i, l in ipairs(doors) do local dw = minetest.registered_nodes[l] if dw then @@ -122,10 +155,7 @@ for i, l in ipairs(doors) do 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 +for i, l in ipairs(all_items) do local it = minetest.registered_items[l] if it then local def_on_place = it.on_place diff --git a/player_events.lua b/player_events.lua new file mode 100644 index 0000000..c572cff --- /dev/null +++ b/player_events.lua @@ -0,0 +1,105 @@ +local on_death = {} + +minetest.register_on_prejoinplayer(function(name, ip) + factions.player_ips.set(name, ip) +end) + +minetest.register_on_joinplayer( +function(player) + local name = player:get_player_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() + + 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.") + 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) + end + end + +end +) + +minetest.register_on_leaveplayer( + function(player) + local name = player:get_player_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 + hud_ids[id_name2] = nil + end + if hud_ids[id_name3] then + hud_ids[id_name3] = nil + end + for k, v in pairs(factions.onlineplayers[facname]) do + return + end + factions.onlineplayers[facname] = nil + on_death[name] = nil + end + end +) + +minetest.register_on_respawnplayer( + function(player) + local name = player:get_player_name() + local faction, facname = factions.get_player_faction(name) + + if not faction then + return false + else + on_death[name] = nil + if not faction.spawn then + return false + else + player:set_pos(faction.spawn) + return true + end + end + end +) + +minetest.register_on_dieplayer( +function(player) + local pname = player:get_player_name() + if on_death[pname] then + return + end + local faction, name = factions.get_player_faction(pname) + if not faction then + return + end + factions.decrease_power(name, factions_config.power_per_death) + on_death[pname] = true + return +end +) diff --git a/power_events.lua b/power_events.lua new file mode 100644 index 0000000..d1c0aec --- /dev/null +++ b/power_events.lua @@ -0,0 +1,81 @@ +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(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) + end + + factions.factions.set(name, faction) +end + +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.factions.set(name, faction) +end + +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.factions.set(name, faction) +end + +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(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) + end + + factions.factions.set(name, faction) +end + +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.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(factions.onlineplayers[name]) do + updateHudPower(minetest.get_player_by_name(i), faction) + end + + factions.factions.set(name, faction) +end diff --git a/protection_override.lua b/protection_override.lua new file mode 100644 index 0000000..2c9db80 --- /dev/null +++ b/protection_override.lua @@ -0,0 +1,36 @@ +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, 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 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 (factions.has_permission(parcel_fac_name, player, "build") or factions.has_permission(parcel_fac_name, player, "pain_build")) + elseif parcel_faction.allies[player_faction.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 (factions.has_permission(player_fac_name, player, "build") or factions.has_permission(player_fac_name, player, "pain_build")) + else + return true + end + else + return true + end +end diff --git a/rank_events.lua b/rank_events.lua new file mode 100644 index 0000000..e404b59 --- /dev/null +++ b/rank_events.lua @@ -0,0 +1,168 @@ +--! @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.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.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.remove_privs(name, rank, perms) + local faction = factions.factions.get(name) + + local revoked = false + local p = faction.ranks[rank] + + for index, perm in pairs(p) do + if table_Contains(perms, perm) then + revoked = true + table.remove(p, index) + end + end + + faction.ranks[rank] = p + + if revoked then + factions.on_remove_privs(name, rank, perms) + else + factions.broadcast(name, "No privilege was revoked from rank " .. rank .. ".") + end + + factions.factions.set(name, faction) +end + +function factions.add_privs(name, rank, perms) + local faction = factions.factions.get(name) + + local added = false + local p = faction.ranks[rank] + + for index, perm in pairs(perms) do + if not table_Contains(p, perm) then + added = true + table.insert(p, perm) + end + end + + faction.ranks[rank] = p + + if added then + factions.on_add_privs(name, rank, perms) + else + factions.broadcast(name, "The rank " .. rank .. " already has these privileges.") + end + + factions.factions.set(name, faction) +end + +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 + faction.players[player] = newrank + end + end + + 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 == faction.default_rank then + faction.default_rank = newrank + factions.broadcast(name, "The default rank given to new players is set to " .. newrank) + end + + factions.on_set_rank_name(name, oldrank, newrank) + + factions.factions.set(name, faction) +end + +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 + + faction.default_rank = rank + factions.on_set_def_rank(name, rank) + + factions.factions.set(name, faction) +end + +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 + faction.players[player] = faction.default_leader_rank_rank + end + end + 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.delete_rank(name, rank, newrank) + local faction = factions.factions.get(name) + + for player, r in pairs(faction.players) do + if r == rank then + faction.players[player] = newrank + end + end + 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 == faction.default_rank then + faction.default_rank = newrank + factions.broadcast(name, "The default rank given to new players is set to "..newrank) + end + + factions.factions.set(name, faction) +end + +--! @brief set a player's rank +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