-- =================================================================== eregions.used = {} eregions.addabm_map = {} -- =================================================================== local eregions_addabm = function (efeature) if eregions.used [efeature] ~= nil then return end eregions.used [efeature] = 1 local func = eregions.addabm_map [efeature] if func ~= nil then func() end end -- =================================================================== -- Save the eregions table to a file function eregions:save() local datastr = minetest.serialize (self.eregions) if not datastr then minetest.log ("error", "[eregions] Failed to serialize eregion data") return end local file, err = io.open (eregions.filename, "w") if err then return err end file:write (datastr) file:close() end -- =================================================================== -- Load the eregions table from the save file function eregions:load() local file, err = io.open (eregions.filename, "r") if err then self.eregions = self.eregions or {} return err end self.eregions = minetest.deserialize (file:read ("*a")) if type(self.eregions) ~= "table" then self.eregions = {} end file:close() self:populateStore() for id, eregion in pairs (eregions.eregions) do eregions_addabm (eregion.efeature) end end -- =================================================================== --- Checks an AreaStore ID. -- Deletes the AreaStore (falling back to the iterative method) -- and prints an error message if the ID is invalid. -- @return Whether the ID was valid. function eregions:checkAreaStoreId (sid) if not sid then minetest.log ("error", "AreaStore failed to find an ID for an " .."eregion. Falling back to iterative eregion checking.") self.store = nil self.store_ids = nil end return sid and true or false end -- =================================================================== -- Populates the AreaStore after loading, if needed. function eregions:populateStore() if not rawget (_G, "AreaStore") then return end local store = AreaStore() local store_ids = {} for id, eregion in pairs (eregions.eregions) do local sid = store:insert_area (eregion.pos1, eregion.pos2, tostring (id)) if not self:checkAreaStoreId (sid) then return end store_ids [id] = sid end self.store = store self.store_ids = store_ids end -- =================================================================== -- Finds the first usable index in a table -- Eg: {[1]=false,[4]=true} -> 2 local function findFirstUnusedIndex (t) local i = 0 repeat i = i + 1 until t [i] == nil return i end -- =================================================================== local eregions_addabm_lavagel = function() minetest.register_abm ({ nodenames = { "default:lava_flowing" , "default:lava_source" , } , catch_up = false , chance = 1 , interval = 3 , action = function (pos, node) if eregions:has_feature (pos, "lavagel") then local newnode if node.name == "default:lava_source" then newnode = "default:lava_gel" else newnode = "air" end minetest.set_node (pos, { name = newnode }) end end }) end eregions.addabm_map ["lavagel"] = eregions_addabm_lavagel -- =================================================================== function eregions:add (efeature, pos1, pos2) local id = findFirstUnusedIndex (self.eregions) self.eregions [id] = { pos1 = pos1 , pos2 = pos2 , efeature = efeature , } if self.store then local sid = self.store:insert_area (pos1, pos2, tostring (id)) if self:checkAreaStoreId (sid) then self.store_ids [id] = sid end end eregions_addabm (efeature) return id end -- =================================================================== function eregions:remove (id) if self.eregions [id] == nil then return false end -- Remove main entry self.eregions [id] = nil -- Remove from AreaStore if self.store then self.store:remove_area (self.store_ids [id]) self.store_ids [id] = nil end return true end -- =================================================================== -- Move an eregion function eregions:move (id, eregion, pos1, pos2) eregion.pos1 = pos1 eregion.pos2 = pos2 if self.store then self.store:remove_area (eregions.store_ids [id]) local sid = self.store:insert_area (pos1, pos2, tostring (id)) if self:checkAreaStoreId (sid) then self.store_ids[id] = sid end end end -- =================================================================== function eregions:isERegionEFeature(id, name) local cur = self.eregions[id] if cur and minetest.check_player_privs(name, self.adminPrivs) then return true end while cur do if cur.efeature == name then return true elseif cur.parent then cur = self.eregions[cur.parent] else return false end end return false end -- =================================================================== -- End of module.