summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md26
-rw-r--r--functions.lua64
-rw-r--r--init.lua46
-rw-r--r--table_save.lua133
4 files changed, 269 insertions, 0 deletions
diff --git a/README.md b/README.md
index 6a9d928..d726438 100644
--- a/README.md
+++ b/README.md
@@ -192,6 +192,20 @@ Load nodes from "(world folder)/schems/<file>.we" with position 1 of the current
//load some random filename
//load huge_base
+### //metasave <file>
+
+Save the current WorldEdit region including metadata to "(world folder)/schems/<file>.wem".
+
+ //metasave some random filename
+ //metasave huge_base
+
+### //metaload <file>
+
+Load nodes and metadata from "(world folder)/schems/<file>.wem" with position 1 of the current WorldEdit region as the origin.
+
+ //metaload some random filename
+ //metaload huge_base
+
WorldEdit API
-------------
WorldEdit exposes all significant functionality in a simple interface. Adding WorldEdit to the file "depends.txt" in your mod gives you access to all of the `worldedit` functions. These are useful if you're looking for high-performance node manipulation without all the hassle of writing tons of code.
@@ -294,6 +308,18 @@ This function is deprecated, and should not be used unless there is a need to su
Returns the number of nodes deserialized.
+### worldedit.metasave(pos1, pos2, file)
+
+Saves the nodes and meta defined by positions `pos1` and `pos2` into a file
+
+Returns the number of nodes saved
+
+### worldedit.metaload(pos1, file)
+
+Loads the nodes and meta from `file` to position `pos1`
+
+Returns the number of nodes loaded
+
License
-------
Copyright 2012 sfan5 and Anthony Zhang (Temperest)
diff --git a/functions.lua b/functions.lua
index fbdfb54..2d16daf 100644
--- a/functions.lua
+++ b/functions.lua
@@ -566,3 +566,67 @@ worldedit.deserialize_old = function(originpos, value)
end
return count
end
+
+--saves the nodes and meta defined by positions `pos1` and `pos2` into a file, returning the number of nodes saved
+worldedit.metasave = function(pos1, pos2, file)
+ local path = minetest.get_worldpath() .. "/schems"
+ local filename = path .. "/" .. file .. ".wem"
+ os.execute("mkdir \"" .. path .. "\"") --create directory if it does not already exist
+ local rows = {}
+ local pos1, pos2 = worldedit.sort_pos(pos1, pos2)
+ local pos = {x=pos1.x, y=0, z=0}
+ local count = 0
+ local result = {}
+ local env = minetest.env
+ while pos.x <= pos2.x do
+ pos.y = pos1.y
+ while pos.y <= pos2.y do
+ pos.z = pos1.z
+ while pos.z <= pos2.z do
+ local node = env:get_node(pos)
+ if node.name ~= "air" and node.name ~= "ignore" then
+ count = count + 1
+ local row = {
+ x = pos.x-pos1.x,
+ y = pos.y-pos1.y,
+ z = pos.z-pos1.z,
+ name = node.name,
+ param1 = node.param1,
+ param2 = node.param2,
+ meta = env:get_meta(pos):to_table(),
+ }
+ table.insert(rows, row)
+ end
+ pos.z = pos.z + 1
+ end
+ pos.y = pos.y + 1
+ end
+ pos.x = pos.x + 1
+ end
+ local err = table.save(rows,filename)
+ if err then return _,err end
+ return count
+end
+
+--loads the nodes and meta from `file` to position `pos1`, returning the number of nodes loaded
+worldedit.metaload = function(pos1, file)
+ local filename = minetest.get_worldpath() .. "/schems/" .. file .. ".wem"
+ local rows, err = table.load(filename)
+ if err then return _,err end
+ local pos = {x=0, y=0, z=0}
+ local node = {name="", param1=0, param2=0}
+ local count = 0
+ local env = minetest.env
+ for i,row in pairs(rows) do
+ pos.x = pos1.x + tonumber(row.x)
+ pos.y = pos1.y + tonumber(row.y)
+ pos.z = pos1.z + tonumber(row.z)
+ node.name = row.name
+ node.param1 = row.param1
+ node.param2 = row.param2
+ env:add_node(pos, node)
+ env:get_meta(pos):from_table(row.meta)
+ count = count + 1
+ end
+ return count
+end \ No newline at end of file
diff --git a/init.lua b/init.lua
index 32bf8e2..1e9b0ef 100644
--- a/init.lua
+++ b/init.lua
@@ -529,3 +529,49 @@ minetest.register_chatcommand("/load", {
minetest.chat_send_player(name, count .. " nodes loaded")
end,
})
+
+minetest.register_chatcommand("/metasave", {
+ params = "<file>",
+ description = "Save the current WorldEdit region to \"(world folder)/schems/<file>.wem\"",
+ privs = {worldedit=true},
+ func = function(name, param)
+ local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
+ if pos1 == nil or pos2 == nil then
+ minetest.chat_send_player(name, "No WorldEdit region selected")
+ return
+ end
+ if param == "" then
+ minetest.chat_send_player(name, "Invalid usage: " .. param)
+ return
+ end
+ local count, err = worldedit.metasave(pos1, pos2, param)
+ if err then
+ minetest.chat_send_player(name, "error loading file: " .. err)
+ else
+ minetest.chat_send_player(name, count .. " nodes saved")
+ end
+ end,
+})
+
+minetest.register_chatcommand("/metaload", {
+ params = "<file>",
+ description = "Load nodes from \"(world folder)/schems/<file>.wem\" with position 1 of the current WorldEdit region as the origin",
+ privs = {worldedit=true},
+ func = function(name, param)
+ local pos1 = worldedit.pos1[name]
+ if pos1 == nil then
+ minetest.chat_send_player(name, "No WorldEdit region selected")
+ return
+ end
+ if param == "" then
+ minetest.chat_send_player(name, "Invalid usage: " .. param)
+ return
+ end
+ local count, err = worldedit.metaload(pos1, param)
+ if err then
+ minetest.chat_send_player(name, "error loading file: " .. err)
+ else
+ minetest.chat_send_player(name, count .. " nodes loaded")
+ end
+ end,
+})
diff --git a/table_save.lua b/table_save.lua
new file mode 100644
index 0000000..cbc18ae
--- /dev/null
+++ b/table_save.lua
@@ -0,0 +1,133 @@
+--[[
+ Save Table to File
+ Load Table from File
+ v 1.0
+
+ Lua 5.2 compatible
+
+ Only Saves Tables, Numbers and Strings
+ Insides Table References are saved
+ Does not save Userdata, Metatables, Functions and indices of these
+ ----------------------------------------------------
+ table.save( table , filename )
+
+ on failure: returns an error msg
+
+ ----------------------------------------------------
+ table.load( filename or stringtable )
+
+ Loads a table that has been saved via the table.save function
+
+ on success: returns a previously saved table
+ on failure: returns as second argument an error msg
+ ----------------------------------------------------
+
+ Licensed under the same terms as Lua itself.
+]]--
+do
+ -- declare local variables
+ --// exportstring( string )
+ --// returns a "Lua" portable version of the string
+ local function exportstring( s )
+ return string.format("%q", s)
+ end
+
+ --// The Save Function
+ function table.save( tbl,filename )
+ local charS,charE = " ","\n"
+ local file,err = io.open( filename, "wb" )
+ if err then return err end
+
+ -- initiate variables for save procedure
+ local tables,lookup = { tbl },{ [tbl] = 1 }
+ file:write( "return {"..charE )
+
+ for idx,t in ipairs( tables ) do
+ file:write( "-- Table: {"..idx.."}"..charE )
+ file:write( "{"..charE )
+ local thandled = {}
+
+ for i,v in ipairs( t ) do
+ thandled[i] = true
+ local stype = type( v )
+ -- only handle value
+ if stype == "table" then
+ if not lookup[v] then
+ table.insert( tables, v )
+ lookup[v] = #tables
+ end
+ file:write( charS.."{"..lookup[v].."},"..charE )
+ elseif stype == "string" then
+ file:write( charS..exportstring( v )..","..charE )
+ elseif stype == "number" then
+ file:write( charS..tostring( v )..","..charE )
+ end
+ end
+
+ for i,v in pairs( t ) do
+ -- escape handled values
+ if (not thandled[i]) then
+
+ local str = ""
+ local stype = type( i )
+ -- handle index
+ if stype == "table" then
+ if not lookup[i] then
+ table.insert( tables,i )
+ lookup[i] = #tables
+ end
+ str = charS.."[{"..lookup[i].."}]="
+ elseif stype == "string" then
+ str = charS.."["..exportstring( i ).."]="
+ elseif stype == "number" then
+ str = charS.."["..tostring( i ).."]="
+ end
+
+ if str ~= "" then
+ stype = type( v )
+ -- handle value
+ if stype == "table" then
+ if not lookup[v] then
+ table.insert( tables,v )
+ lookup[v] = #tables
+ end
+ file:write( str.."{"..lookup[v].."},"..charE )
+ elseif stype == "string" then
+ file:write( str..exportstring( v )..","..charE )
+ elseif stype == "number" then
+ file:write( str..tostring( v )..","..charE )
+ end
+ end
+ end
+ end
+ file:write( "},"..charE )
+ end
+ file:write( "}" )
+ file:close()
+ end
+
+ --// The Load Function
+ function table.load( sfile )
+ local ftables,err = loadfile( sfile )
+ if err then return _,err end
+ local tables = ftables()
+ for idx = 1,#tables do
+ local tolinki = {}
+ for i,v in pairs( tables[idx] ) do
+ if type( v ) == "table" then
+ tables[idx][i] = tables[v[1]]
+ end
+ if type( i ) == "table" and tables[i[1]] then
+ table.insert( tolinki,{ i,tables[i[1]] } )
+ end
+ end
+ -- link indices
+ for _,v in ipairs( tolinki ) do
+ tables[idx][v[2]],tables[idx][v[1]] = tables[idx][v[1]],nil
+ end
+ end
+ return tables[1]
+ end
+-- close do
+end
+-- ChillCode \ No newline at end of file