diff --git a/init.lua b/init.lua index 54d43dd..d2cd784 100644 --- a/init.lua +++ b/init.lua @@ -9,9 +9,9 @@ toggle_areas.area_privs = {} toggle_areas.registered_on_enter = {} toggle_areas.registered_on_leave = {} -areas_owner_privs = minetest.settings:get("toggle_areas.owner_privs") ~= "+creative, +fly, +fast" -areas_guest_privs = minetest.settings:get("toggle_areas.guest_privs") ~= "-fly, -fast" -default_privs = minetest.settings:get("toggle_areas.default_privs") ~= "+fast" +areas_owner_privs = minetest.settings:get("toggle_areas.owner_privs") or "+creative, +fly, +fast" +areas_guest_privs = minetest.settings:get("toggle_areas.guest_privs") or "-fly, -fast" +default_privs = minetest.settings:get("toggle_areas.default_privs") or "+fast" function toggle_areas:load_areas() local test = minetest.deserialize(mod_storage:get_string("astore")) @@ -52,7 +52,7 @@ end function toggle_areas:decode_privs_string(str) -- minetest/builtin/common/misc_helpers.lua:core.string_to_privs() assert(type(str) == "string") - delim = ',' + local delim = ',' local privs_grant = {} local privs_revoke = {} for _, priv in pairs(string.split(str, delim)) do @@ -74,8 +74,12 @@ function toggle_areas:is_areas_mod(area_id) return is_areas_id, a_id end -function toggle_areas:get_area_size(area_id) - +function toggle_areas:get_area_size(astore_area) + local pos1 = astore_area.min + local pos2 = astore_area.max + local x = math.abs( pos2.x - pos1.x ) + local z = math.abs( pos2.z - pos1.x ) + return x*z end function toggle_areas:save_player_privs(player) @@ -115,7 +119,7 @@ function toggle_areas:player_enter_area(player, privstring) local name = player:get_player_name() local has_creative = minetest.check_player_privs(name, {creative=true}) - privs_grant, privs_revoke = toggle_areas:decode_privs_string(privstring) + local privs_grant, privs_revoke = toggle_areas:decode_privs_string(privstring) if not has_creative and privs_grant.creative and not privs_revoke.creative then minetest.chat_send_player(name, "You entered creative mode") @@ -145,9 +149,13 @@ function toggle_areas:update_player(player) local pmeta = player:get_meta() -- pmeta:mark_as_private("toggle_areas") - local player_stored_areas = minetest.deserialize(pmeta:get_string("toggle_areas")) or {} + local player_last_active_area = pmeta:get_string("toggle_areas.active_area") or "-1" + local player_active_area = "-1" local areas_owner = false local areas_guest = false + local areas_open = false + local new_area = nil + local smallest_area = {} if minetest.check_player_privs(name, { protection_bypass=true }) then minetest.log("warning", "[toggle_areas] Player has protection_bypass priv") @@ -161,56 +169,55 @@ function toggle_areas:update_player(player) for a_id, a_area in pairs( a_current_areas ) do if a_area.owner == name then areas_owner = true + player_active_area = "a"..a_id + break + elseif a_area.open then + areas_open = true + player_active_area = "a"..a_id + break else areas_guest = true - end - if not player_stored_areas["a_"..a_id] then - player_stored_areas["a_"..a_id] = true - minetest.log("warning", "[toggle_areas] Player entered area a_"..tostring(a_id)) - + player_active_area = "a"..a_id + break end end end -- enter area - local current_areas = self.astore:get_areas_for_pos(pos, false, true) + local current_areas = self.astore:get_areas_for_pos(pos, true, true) for astore_id, astore_area in pairs( current_areas ) do - if not player_stored_areas[astore_id] then - player_stored_areas[astore_id] = true - minetest.chat_send_player(name, "You entered area ["..tostring(astore_id).."] "..astore_area.data) - minetest.log("warning", "[toggle_areas] Player entered area "..tostring(astore_id)) --- for i=1, #toggle_areas.registered_on_enter[astore_id] do --- toggle_areas.registered_on_enter[astore_id][i](player) --- end + local areasize = toggle_areas:get_area_size(astore_area) + if not smallest_area.size or areasize < smallest_area.size then + smallest_area.id = astore_id + smallest_area.size = areasize end end + if player_active_area == "-1" and smallest_area.id then + player_active_area = smallest_area.id + end - -- leave area - for id, _ in pairs(player_stored_areas) do - local is_areas_id, a_id = toggle_areas:is_areas_mod(id) - if not is_areas_id and not current_areas[id] then - player_stored_areas[id] = nil - minetest.log("warning", "[toggle_areas] Player left area "..tostring(id)) --- for i=1, #toggle_areas.registered_on_leave[id] do --- toggle_areas.registered_on_leave[id][i](player) --- end + local privstring = default_privs + if areas_owner or areas_open then + privstring = areas_owner_privs + elseif areas_guest then + if toggle_areas.area_privs[player_active_area] then + privstring = toggle_areas.area_privs[player_active_area] + else + privstring = areas_guest_privs end - -- leave areas mod area - if is_areas_id and not a_current_areas[a_id] then - player_stored_areas[id] = nil - minetest.log("warning", "[toggle_areas] Player left areas area "..tostring(id)) + elseif smallest_area.id then + if toggle_areas.area_privs[smallest_area.id] then + privstring = toggle_areas.area_privs[smallest_area.id] end end - - local current_player_area = -1 - for id, _ in pairs(player_stored_areas) do - + + if player_active_area ~= player_last_active_area then + minetest.log("warning", "[toggle_areas] player entering new area "..player_last_active_area.."->"..player_active_area) + toggle_areas:player_enter_area(player, privstring) + pmeta:set_string("toggle_areas.active_area", player_active_area) end - local privstring = toggle_areas.area_privs[area_id] or default_privs - -- todo areas owner / guest -- print(dump(pmeta:to_table())) - pmeta:set_string("toggle_areas", minetest.serialize(player_stored_areas)) end toggle_areas:load_areas()