From 751ab8953b8a6a7797285c5ba3e03f754091fa16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20Eng=C3=A9libert?= Date: Sat, 16 Aug 2025 10:40:38 +0200 Subject: [PATCH] Support multiple factions --- init.lua | 187 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 123 insertions(+), 64 deletions(-) diff --git a/init.lua b/init.lua index a281bba..94d5c54 100644 --- a/init.lua +++ b/init.lua @@ -67,6 +67,13 @@ local function get_member_list(meta) return meta:get_string("members"):split(" ") end +-- return list of factions as a table + +local function get_faction_list(meta) + + return meta:get_string("factions"):split(" ") +end + -- write member list table in protector meta as string local function set_member_list(meta, list) @@ -74,6 +81,13 @@ local function set_member_list(meta, list) meta:set_string("members", table.concat(list, " ")) end +-- write faction list table in protector meta as string + +local function set_faction_list(meta, list) + + meta:set_string("factions", table.concat(list, " ")) +end + -- check for owner name local function is_owner(meta, name) @@ -81,40 +95,65 @@ local function is_owner(meta, name) return name == meta:get_string("owner") end +-- add faction name to table as member + +local function add_faction(meta, name) + if name ~= string.match(name, "[%w_-]+") and name ~= "*" then return end + if name:len() > 25 then return end + local list = get_faction_list(meta) + if #list >= 4 then return end + table.insert(list, name) + set_faction_list(meta, list) +end + -- check for member name local function is_member(meta, name) - if factions_available and meta:get_int("faction_members") == 1 then - - if factions.version == nil then - - -- backward compatibility - if factions.get_player_faction(name) ~= nil - and factions.get_player_faction(meta:get_string("owner")) == - factions.get_player_faction(name) then - return true - end - else - -- is member if player and owner share at least one faction - local player_factions = factions.get_player_factions(name) - local owner = meta:get_string("owner") - - if player_factions ~= nil and player_factions ~= false then - - for _, f in ipairs(player_factions) do - - if factions.player_is_in_faction(f, owner) then return true end - end - end - end - end - for _, n in pairs(get_member_list(meta)) do if n == name then return true end end + if factions_available then + if meta:get_int("faction_members") == 1 then + -- migrate + add_faction(meta, "*") + meta:set_int("faction_members", 0) + end + if factions.version == nil then + -- backward compatibility + local player_faction = factions.get_player_faction(name) + if player_faction ~= nil then + for _, faction in pairs(get_faction_list(meta)) do + if ( + faction == "*" + and factions.get_player_faction(meta:get_string("owner")) == player_faction + ) or faction == player_faction then + return true + end + end + end + else + for _, faction in pairs(get_faction_list(meta)) do + if faction == "*" then + -- is member if player and owner share at least one faction + local player_factions = factions.get_player_factions(name) + local owner = meta:get_string("owner") + if player_factions ~= nil and player_factions ~= false then + for _, f in ipairs(player_factions) do + if factions.player_is_in_faction(f, owner) then + return true + end + end + end + elseif factions.player_is_in_faction(faction, name) then + return true + end + end + end + end + return false end @@ -128,9 +167,6 @@ local function add_member(meta, name) -- Constant (20) defined by player.h if name:len() > 25 then return end - -- does name already exist? - if is_owner(meta, name) or is_member(meta, name) then return end - local list = get_member_list(meta) if #list >= protector.max_shares then return end @@ -156,6 +192,19 @@ local function del_member(meta, name) set_member_list(meta, list) end +-- remove faction name from table + +local function del_faction(meta, name) + local list = get_faction_list(meta) + for i, n in pairs(list) do + if n == name then + table.remove(list, i) + break + end + end + set_faction_list(meta, list) +end + -- protector interface local function protector_formspec(meta) @@ -165,53 +214,25 @@ local function protector_formspec(meta) .. default.gui_bg_img .. "label[2.5,0;" .. F(S("-- Protector interface --")) .. "]" .. "label[0,1;" .. F(S("PUNCH node to show protected area")) .. "]" - .. "label[0,2;" .. F(S("Members:")) .. "]" + .. "label[0,1.5;" .. F(S("Members:")) .. "]" .. "button_exit[2.5,6.2;3,0.5;close_me;" .. F(S("Close")) .. "]" .. "field_close_on_enter[protector_add_member;false]" local members = get_member_list(meta) + local i = 0 - local checkbox_faction = false - - -- Display the checkbox only if the owner is member of at least 1 faction - if factions_available then - - if factions.version == nil then - - -- backward compatibility - if factions.get_player_faction(meta:get_string("owner")) then - checkbox_faction = true - end - else - local player_factions = factions.get_player_factions(meta:get_string("owner")) - - if player_factions ~= nil and type(player_factions) == "table" - and #player_factions >= 1 then - checkbox_faction = true - end - end - end - - if checkbox_faction then - - formspec = formspec .. "checkbox[0,5;faction_members;" - .. F(S("Allow faction access")) - .. ";" .. (meta:get_int("faction_members") == 1 and - "true" or "false") .. "]" - end - for n = 1, #members do if i < protector.max_shares then -- show username formspec = formspec .. "button[" .. (i % 4 * 2) - .. "," .. math_floor(i / 4 + 3) + .. "," .. (math.floor(i / 4) + 2.5) .. ";1.5,.5;protector_member;" .. F(members[n]) .. "]" -- username remove button .. "button[" .. (i % 4 * 2 + 1.25) .. "," - .. math_floor(i / 4 + 3) + .. (math.floor(i / 4) + 2.5) .. ";.75,.5;protector_del_member_" .. F(members[n]) .. ";X]" end @@ -222,12 +243,39 @@ local function protector_formspec(meta) -- user name entry field formspec = formspec .. "field[" .. (i % 4 * 2 + 1 / 3) .. "," - .. (math_floor(i / 4 + 3) + 1 / 3) + .. (math.floor(i / 4) + 2.5 + 1 / 3) .. ";1.433,.5;protector_add_member;;]" -- username add button .."button[" .. (i % 4 * 2 + 1.25) .. "," - .. math_floor(i / 4 + 3) .. ";.75,.5;protector_submit;+]" + .. (math.floor(i / 4) + 2.5) .. ";.75,.5;protector_submit;+]" + + end + + if factions_available then + formspec = formspec .. "label[0,4.25;" .. F(S("Factions: (use * to allow any of your factions)")) .. "]" + .. "field_close_on_enter[protector_add_faction;false]" + + local member_factions = get_faction_list(meta) + i = 0 + for n = 1, #member_factions do + if i < 4 then + formspec = formspec .. "button[" .. (i % 4 * 2) + .. "," .. math.floor(i / 4 + 5) + .. ";1.5,.5;protector_faction;" .. F(member_factions[n]) .. "]" + .. "button[" .. (i % 4 * 2 + 1.25) .. "," + .. math.floor(i / 4 + 5) + .. ";.75,.5;protector_del_faction_" .. F(member_factions[n]) .. ";X]" + end + i = i + 1 + end + if i < 4 then + formspec = formspec .. "field[" .. (i % 4 * 2 + 1 / 3) .. "," + .. (math.floor(i / 4 + 5) + 1 / 3) + .. ";1.433,.5;protector_add_faction;;]" + .."button[" .. (i % 4 * 2 + 1.25) .. "," + .. math.floor(i / 4 + 5) .. ";.75,.5;protector_submit_faction;+]" + end end return formspec @@ -621,8 +669,18 @@ core.register_on_player_receive_fields(function(player, formname, fields) local meta = core.get_meta(pos) ; if not meta then return end -- add faction members - if factions_available and fields.faction_members ~= nil then - meta:set_int("faction_members", fields.faction_members == "true" and 1 or 0) + if factions_available then + local add_faction_input = fields.protector_add_faction + if add_faction_input and add_faction_input ~= "" then + for _, i in pairs(add_faction_input:split(" ")) do + add_faction(meta, i) + end + end + for field, value in pairs(fields) do + if string.sub(field, 0, string.len("protector_del_faction_")) == "protector_del_faction_" then + del_faction(meta, string.sub(field, string.len("protector_del_faction_") + 1)) + end + end end -- add member [+] @@ -806,3 +864,4 @@ core.register_chatcommand("protector_del_member", { print ("[MOD] Protector Redo loaded") +