This commit is contained in:
dgm3333 2014-05-26 21:52:09 +00:00
commit 5825b8ef29
4 changed files with 506 additions and 7 deletions

View File

@ -22,6 +22,10 @@ Many commands also have shorter names that can be typed faster. For example, if
| `//hdo` | `//hollowdome` |
| `//do` | `//dome` |
| `//hcyl` | `//hollowcylinder` |
| `//co` | `//correctorigin` |
| `//oc` | `//correctorigin` |
| `//la` | `//loadalign` |
| `//lao` | `//loadalignoffset`|
### `//about`
@ -307,6 +311,7 @@ Save the current WorldEdit region to "(world folder)/schems/`<file>`.we".
### `//allocate <file>`
Set the region defined by nodes from "(world folder)/schems/`<file>`.we" as the current WorldEdit region.
Also display any mods which are not currently enabled in the world, but are referenced in the schem file.
//allocate some random filename
//allocate huge_base
@ -314,10 +319,51 @@ Set the region defined by nodes from "(world folder)/schems/`<file>`.we" as the
### `//load <file>`
Load nodes from "(world folder)/schems/`<file>`.we" with position 1 of the current WorldEdit region as the origin.
NB is it suggested you do a dummy-run with //allocate to list referenced mods not currently enabled (which will cause errors)
//load some random filename
//load huge_base
### `//correctorigin`
Moves pos1 and pos2 so pos1 is at the origin of the region (ie pos1 located with minimum x,y,z, pos2 with maximum x,y,z)
This is ideally used before /save to decrease confusion with placement for /load and /loadalign
Shortcut of /co and /oc (to ease confusion) is set in worldedit_shortcommands/init.lua
//correctorigin
### `//loadalignoffset [x y z]`
Set a global variable to enable an offset to the player location for /loadalign
-- This can be useful it a particular location is not easily accessible (eg if you want a file y-origin to be below ground level, or x- or z- inside a cliff)
-- the offset is cleared by using the command without params (=arguments)
-- Shortcut of /lao is set in worldedit_shortcommands/init.lua
//load
//load x y z
### `//loadalign <file>`
Load nodes from "(world folder)/schems/`<file>`.we" with player location as the origin. The loaded schem will be in a region to the front, right and above the players location.
NB is it suggested you do a dummy-run with //allocate to list referenced mods not currently enabled (which will cause errors)
If the location is not easily accessible (eg if you want a file y-origin to be below ground level, or x- or z- inside a cliff), you can set an offset with /loadalignoffset
The player is moved backwards one space to moved them out of the load zone (or more if there is and offset). This may mean the player ends up inside a node (if it suddenly gets dark). You may be able to step out. If not you'll have to teleport to an unblocked location.
The /save command saves the file with the origin at the xmin,ymin,zmin, irrespective of where pos1 and pos2 are. To reduce confusion it is suggested that you use the /correctorigin command before saving
to move the markers to reflect this, but if you are copying a section one node wide, there are two possible orientations.
You need to be facing in the positive z direction to correctly orient yourself to the orientation when it is reloaded.
If you are using a schem regularly, and markers are not in your prefered orientation, it is best to do an initial /loadalign to get the correct orientation, then resave it
The loaded region is marked with pos1/pos2 with pos1 where the origin would have been when the schem was saved.
The function has only been tested with the current (version 4) schem files, so consider use with older schem files to be at your own risk.
The most likely bugs with untested versions are: either the entire region is incorrectly rotated or individual nodes are incorrectly oriented (so faces point in the incorrect direction)
The functions is a modifications of the original register //load to support alignment relative to player, so code from the screwdriver mod was used as a starter for node orientation.
The main functions are in the WorldEdit/worldedit/serialization.lua (worldedit.deserializeAligned which also uses worldedit.getNewRotation, and might need worldedit.screwdriver_handler
depending on compatibility with old files)
Shortcut of /la is set in worldedit_shortcommands/init.lua
//loadalign some random filename
//loadalign huge_base
### `//lua <code>`
Executes `<code>` as a Lua chunk in the global namespace.

View File

@ -89,11 +89,12 @@ worldedit.allocate = function(originpos, value)
local originx, originy, originz = originpos.x, originpos.y, originpos.z
local count = 0
local version = worldedit.valueversion(value)
local missingMods = ""
if version == 1 or version == 2 then --flat table format
--obtain the node table
local get_tables = loadstring(value)
if get_tables then --error loading value
return originpos, originpos, count
return originpos, originpos, count, missingMods
end
local tables = get_tables()
@ -163,6 +164,8 @@ worldedit.allocate = function(originpos, value)
--local nodes = minetest.deserialize(value) --wip: this is broken for larger tables in the current version of LuaJIT
-- The following loop sets up pos1 and pos2 to encompass the boundary of the region,
-- and checks all nodes reference mods present in the current world. If they are not present, they are returned for processing if required.
count = #nodes
for index = 1, count do
local entry = nodes[index]
@ -173,18 +176,31 @@ worldedit.allocate = function(originpos, value)
if x > pos2x then pos2x = x end
if y > pos2y then pos2y = y end
if z > pos2z then pos2z = z end
local colonLoc = string.find(entry.name, ":")
if colonLoc ~= nil then
local curMod = entry.name:sub(0,colonLoc-1)
if not string.find(missingMods, (curMod.. ";")) then
if not minetest.get_modpath(curMod) then
missingMods = missingMods.. curMod.. "; "
end
end
end
end
if string.len(missingMods) ~= 0 then
print("Worldedit file dependencies include the following missing mods:")
print(missingMods)
end
end
local pos1 = {x=pos1x, y=pos1y, z=pos1z}
local pos2 = {x=pos2x, y=pos2y, z=pos2z}
return pos1, pos2, count
return pos1, pos2, count, missingMods
end
--loads the nodes represented by string `value` at position `originpos`, returning the number of nodes deserialized
--contains code based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile) by ChillCode, available under the MIT license (GPL compatible)
worldedit.deserialize = function(originpos, value)
--make area stay loaded
local pos1, pos2 = worldedit.allocate(originpos, value)
local pos1, pos2, count, missingMods = worldedit.allocate(originpos, value)
local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2)
@ -269,5 +285,259 @@ worldedit.deserialize = function(originpos, value)
get_meta(entry):from_table(entry.meta)
end
end
return count
return count, missingMods
end
-- create a copy of a node added by worldedit.deserializeAligned, then rotate it and replace the original with the correctly aligned copy
-- hopefully this function is not required, but is included as it may aid/improve backward compatibility if worldedit.getNewRotation doesn't work properly
worldedit.screwdriver_handler = function(pos, axisChange)
-- This function is hopefully not needed, but is included just in case (for old file formats)
-- the basis of this is the minetest screwdriver function
-- it would probably
if axisChange == "Z" then return end
-- create a copy of the node
local nodeRot = minetest.get_node({x=pos.x, y=pos.y, z=pos.z})
-- Get ready to set the param2
local n = nodeRot.param2
-- screwdriver uses axis direction. not sure why, but leave it there just in case...
local axisdir = math.floor(n / 4)
local rotation = n - axisdir * 4
-- screwdriver uses a separate function rather than modulus. Not sure why, but this seems to work
if axisChange == "X" then
n = axisdir * 4 + ((rotation + 1) % 4)
elseif axisChange == "z" then
n = axisdir * 4 + ((rotation + 2) % 4)
elseif axisChange == "x" then
n = axisdir * 4 + ((rotation + 3) % 4)
else
n = axisdir * 4
end
-- now replace the node with the copied one
nodeRot.param2 = n
minetest.swap_node({x=pos.x, y=pos.y, z=pos.z}, nodeRot)
end
-- return the correct orientation for a node within a region being loaded by worldedit.deserializeAligned
worldedit.getNewRotation = function(param2, axisChange)
-- the basis of this is the minetest screwdriver function
if axisChange == "Z" then return param2 end
-- screwdriver uses axisdir. not sure why, but leave it there just in case...
local axisdir = math.floor(param2 / 4)
local rotation = param2 - axisdir * 4
-- screwdriver uses a separate function rather than modulus. Not sure why, but modulus seems to work without the extra call
if axisChange == "X" then
param2 = axisdir * 4 + ((rotation + 1) % 4)
elseif axisChange == "z" then
param2 = axisdir * 4 + ((rotation + 2) % 4)
elseif axisChange == "x" then
param2 = axisdir * 4 + ((rotation + 3) % 4)
end
-- now return the new param2
return param2
end
--loads the nodes represented by string `value` at position `originpos`, returning the number of nodes deserialized
--contains code based on [table.save/table.load](http://lua-users.org/wiki/SaveTableToFile) by ChillCode, available under the MIT license (GPL compatible)
worldedit.deserializeAligned = function(originpos, value, axis)
--make area stay loaded
local pos1, pos2, count, missingMods = worldedit.allocate(originpos, value)
local manip = minetest.get_voxel_manip()
manip:read_from_map(pos1, pos2)
local huge = math.huge
local originx, originy, originz = originpos.x, originpos.y, originpos.z
local count = 0
local pos1x, pos1y, pos1z = huge, huge, huge
local pos2x, pos2y, pos2z = -huge, -huge, -huge
local add_node, get_meta = minetest.add_node, minetest.get_meta
local version = worldedit.valueversion(value)
-- print ("Debug info deserializeAligned: version: ".. version)
-- minetest.chat_send_all("Debug info deserializeAligned: version: ".. version)
if version == 1 or version == 2 then --original flat table format
--obtain the node table
local get_tables = loadstring(value)
if not get_tables then --error loading value
return count
end
local tables = get_tables()
--transform the node table into an array of nodes
for i = 1, #tables do
for j, v in pairs(tables[i]) do
if type(v) == "table" then
tables[i][j] = tables[v[1]]
end
end
end
local nodes = tables[1]
--load the node array
count = #nodes
if version == 1 then --original flat table format
print ("WorldEdit deserializeAligned: attempting to rotate untested file format version: 1")
for index = 1, count do
local entry = nodes[index]
local pos = entry[1]
if axis == "x" then
pos.x, pos.y, pos.z = originx + pos.z, originy - pos.y, originz - pos.x
elseif axis == "X" then
pos.x, pos.y, pos.z = originx - pos.z, originy - pos.y, originz + pos.x
elseif axis == "z" then
pos.x, pos.y, pos.z = originx + pos.x, originy - pos.y, originz + pos.z
elseif axis == "Z" then
pos.x, pos.y, pos.z = originx - pos.x, originy - pos.y, originz - pos.z
end
-- pos.x, pos.y, pos.z = originx - pos.x, originy - pos.y, originz - pos.z
if pos.x < pos1x then pos1x = pos.x end
if pos.y < pos1y then pos1y = pos.y end
if pos.z < pos1z then pos1z = pos.z end
if pos.x > pos2x then pos2x = pos.x end
if pos.y > pos2y then pos2y = pos.y end
if pos.z > pos2z then pos2z = pos.z end
entry[2].param2 = worldedit.getNewRotation(entry[2].param2,axis) -- adjust param2 (rotation of the node) to match the overall rotation of the load
-- this has only been tested to work with version == 4
-- I'm not sure of the format, so if it wouldn't work then disable and
-- enable the worldedit.screwdriver_handler after the node has been added
add_node(pos, entry[2])
-- worldedit.screwdriver_handler({x=pos.x, y=pos.y, z=pos.z}, axis) -- this would rotate the node after it's been placed (just in case needed for old format)
end
else --previous meta flat table format
print ("WorldEdit deserializeAligned: attempting to rotate untested file format version: 2")
for index = 1, #nodes do
local entry = nodes[index]
if axis == "x" then
entry.x, entry.y, entry.z = originx - entry.z, originy + entry.y, originz + entry.x
elseif axis == "X" then
entry.x, entry.y, entry.z = originx + entry.z, originy + entry.y, originz - entry.x
elseif axis == "z" then
entry.x, entry.y, entry.z = originx - entry.x, originy + entry.y, originz - entry.z
elseif axis == "Z" then
entry.x, entry.y, entry.z = originx + entry.x, originy + entry.y, originz + entry.z
end
-- entry.x, entry.y, entry.z = originx + entry.x, originy + entry.y, originz + entry.z
if entry.x < pos1x then pos1x = entry.x end
if entry.y < pos1y then pos1y = entry.y end
if entry.z < pos1z then pos1z = entry.z end
if entry.x > pos2x then pos2x = entry.x end
if entry.y > pos2y then pos2y = entry.y end
if entry.z > pos2z then pos2z = entry.z end
entry.param2 = worldedit.getNewRotation(entry.param2,axis) -- adjust param2 (rotation of the node) to match the overall rotation of the load
-- this has only been tested to work with version == 4
-- I'm not sure of the format, so if it wouldn't work then disable and
-- enable the worldedit.screwdriver_handler after the node has been added
add_node(entry, entry) --entry acts both as position and as node
-- worldedit.screwdriver_handler({x=entry.x, y=entry.y, z=entry.z}, axis) -- this would rotate the node after it's been placed (just in case needed for old format)
get_meta(entry):from_table(entry.meta)
end
end
elseif version == 3 then --previous list format
print ("WorldEdit deserializeAligned: attempting to rotate untested file format version: 3")
local pos = {x=0, y=0, z=0}
local node = {name="", param1=0, param2=0}
for x, y, z, name, param1, param2 in value:gmatch("([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)%s+([^%s]+)%s+(%d+)%s+(%d+)[^\r\n]*[\r\n]*") do --match node entries
if axis == "x" then
pos.x, pos.y, pos.z = originx - tonumber(z), originy + tonumber(y), originz + tonumber(x)
elseif axis == "X" then
pos.x, pos.y, pos.z = originx + tonumber(z), originy + tonumber(y), originz - tonumber(x)
elseif axis == "z" then
pos.x, pos.y, pos.z = originx - tonumber(x), originy + tonumber(y), originz - tonumber(z)
elseif axis == "z" then
pos.x, pos.y, pos.z = originx + tonumber(x), originy + tonumber(y), originz + tonumber(z)
end
-- pos.x, pos.y, pos.z = originx + tonumber(x), originy + tonumber(y), originz + tonumber(z)
node.name, node.param1, node.param2 = name, param1, param2
if pos.x < pos1x then pos1x = pos.x end
if pos.y < pos1y then pos1y = pos.y end
if pos.z < pos1z then pos1z = pos.z end
if pos.x > pos2x then pos2x = pos.x end
if pos.y > pos2y then pos2y = pos.y end
if pos.z > pos2z then pos2z = pos.z end
node.param2 = worldedit.getNewRotation(node.param2,axis) -- adjust param2 (rotation of the node) to match the overall rotation of the load
-- this has only been tested to work with version == 4
-- I'm not sure of the format, so if it wouldn't work then disable and
-- enable the worldedit.screwdriver_handler after the node has been added
add_node(pos, node)
-- worldedit.screwdriver_handler({x=pos.x, y=pos.y, z=pos.z}, axis) -- this would rotate the node after it's been placed (just in case needed for old format)
count = count + 1
end
elseif version == 4 then --current nested table format
--wip: this is a filthy hack that works surprisingly well
value = value:gsub("return%s*{", "", 1):gsub("}%s*$", "", 1)
local escaped = value:gsub("\\\\", "@@"):gsub("\\\"", "@@"):gsub("(\"[^\"]*\")", function(s) return string.rep("@", #s) end)
local startpos, startpos1, endpos = 1, 1
local nodes = {}
-- loop through the loaded file, and save each piece of node information to the node table
while true do
startpos, endpos = escaped:find("},%s*{", startpos)
if not startpos then
break
end
local current = value:sub(startpos1, startpos)
table.insert(nodes, minetest.deserialize("return " .. current))
startpos, startpos1 = endpos, endpos
end
table.insert(nodes, minetest.deserialize("return " .. value:sub(startpos1)))
--local nodes = minetest.deserialize(value) --wip: this is broken for larger tables in the current version of LuaJIT
--load the nodes
count = #nodes
for index = 1, count do
local entry = nodes[index]
print("Node: name: ".. entry.name)
if axis == "x" then
entry.x, entry.y, entry.z = originx - entry.z, originy + entry.y, originz + entry.x
elseif axis == "X" then
entry.x, entry.y, entry.z = originx + entry.z, originy + entry.y, originz - entry.x
elseif axis == "z" then
entry.x, entry.y, entry.z = originx - entry.x, originy + entry.y, originz - entry.z
elseif axis == "Z" then
entry.x, entry.y, entry.z = originx + entry.x, originy + entry.y, originz + entry.z
end
-- entry.x, entry.y, entry.z = originx + entry.x, originy + entry.y, originz + entry.z
if entry.x < pos1x then pos1x = entry.x end
if entry.y < pos1y then pos1y = entry.y end
if entry.z < pos1z then pos1z = entry.z end
if entry.x > pos2x then pos2x = entry.x end
if entry.y > pos2y then pos2y = entry.y end
if entry.z > pos2z then pos2z = entry.z end
entry.param2 = worldedit.getNewRotation(entry.param2,axis) -- adjust param2 (rotation of the node) to match the overall rotation of the load
add_node(entry, entry) --entry acts both as position and as node
end
--load the metadata
for index = 1, count do
local entry = nodes[index]
get_meta(entry):from_table(entry.meta)
end
end
-- Correct pos1 and pos2 location so markers appear as they would have without rotation (ie when saved with corrected origin)
if axis == "x" then
pos1x, pos2x = pos2x, pos1x
elseif axis == "X" then
pos1z, pos2z = pos2z, pos1z
elseif axis == "z" then
pos1x, pos2x = pos2x, pos1x
pos1z, pos2z = pos2z, pos1z
end
return count, {x=pos1x, y=pos1y, z=pos1z}, {x=pos2x, y=pos2y, z=pos2z}, missingMods
end

View File

@ -854,6 +854,7 @@ minetest.register_chatcommand("/allocate", {
privs = {worldedit=true},
func = function(name, param)
local pos = get_position(name)
local missingMods = ""
if pos == nil then return end
if param == "" then
@ -878,7 +879,7 @@ minetest.register_chatcommand("/allocate", {
worldedit.player_notify(name, "invalid file: file is invalid or created with newer version of WorldEdit")
return
end
local nodepos1, nodepos2, count = worldedit.allocate(pos, value)
local nodepos1, nodepos2, count, missingMods = worldedit.allocate(pos, value)
worldedit.pos1[name] = nodepos1
worldedit.mark_pos1(name)
@ -886,6 +887,9 @@ minetest.register_chatcommand("/allocate", {
worldedit.mark_pos2(name)
worldedit.player_notify(name, count .. " nodes allocated")
if missingMods ~= "" then
worldedit.player_notify(name, "Warning: schem file contains references to the following missing mods: ".. missingMods)
end
end,
})
@ -896,6 +900,7 @@ minetest.register_chatcommand("/load", {
func = function(name, param)
local pos = get_position(name)
if pos == nil then return end
local missingMods = ""
if param == "" then
worldedit.player_notify(name, "invalid usage: " .. param)
@ -931,9 +936,183 @@ minetest.register_chatcommand("/load", {
return
end
local count = worldedit.deserialize(pos, value)
local count, missingMods = worldedit.deserialize(pos, value)
worldedit.player_notify(name, count .. " nodes loaded")
if missingMods ~= "" then
worldedit.player_notify(name, "Warning: schem file contains references to the following missing mods: ".. missingMods)
end
end,
})
-- Chat command to move pos1 and pos2 to correct origin (ie pos1 located with minimum x,y,z, pos2 with maximum x,y,z)
-- this is ideally used before /save to decrease confusion with placement for /load and /loadalign
-- This command has a helper function of worldedit.correctOrigin (located below)
-- Shortcut of /co and /oc (to ease confusion) is set in worldedit_shortcommands/init.lua
minetest.register_chatcommand("/correctorigin", {
params = "",
description = "Moves pos1 and pos2 so region is marked with pos1 at the origin (ie minimum x,y,z)",
privs = {worldedit=true},
func = function(name)
worldedit.correctOrigin(name)
end,
})
--Corrects pos1 and pos2 so pos1 is located at the region origin - (ie pos1 located with minimum x,y,z, pos2 with maximum z,y,z)
-- not sure where best located, so left with the chat command.
worldedit.correctOrigin = function(name)
local pos1, pos2 = worldedit.pos1[name], worldedit.pos2[name]
if pos1 == nil or pos2 == nil then
worldedit.player_notify(name, "no region selected")
return nil
end
pos1, pos2 = worldedit.sort_pos(pos1, pos2)
worldedit.pos1[name] = pos1
worldedit.mark_pos1(name)
worldedit.pos2[name] = pos2
worldedit.mark_pos2(name)
end
-- Chat command to enable a global variable which enables an offset to the player (or pos1) location for /loadalign
-- This can be useful it a particular location is not easily accessible (eg if you want a file y-origin to be below ground level, or x- or z- inside a cliff)
-- the offset is cleared by using the command without params (=arguments)
-- Shortcut of /lao is set in worldedit_shortcommands/init.lua
minetest.register_chatcommand("/loadalignoffset", {
params = "x y z",
description = "Set an offset for the worldedit command /loadaligned (x y z)",
privs = {worldedit=true},
func = function(name, param)
local found, _, x, y, z = param:find("^([+-]?%d+)%s+([+-]?%d+)%s+([+-]?%d+)$")
if x == nil or y == nil or z == nil then
worldedit.player_notify(name, "LoadAlign Offset set to 0 for all axes (to set provide: 'x y z')")
laPosOffset = {x=tonumber(0), y=tonumber(0), z=tonumber(0)}
else
laPosOffset = {x=tonumber(x), y=tonumber(y), z=tonumber(z)}
end
end,
})
-- Chat command to allow loading of a schem file which is aligned to player forward direction. The loaded schem will be in a region to the front, right and above the players location.
-- If the location is not easily accessible (eg if you want a file y-origin to be below ground level, or x- or z- inside a cliff), you can set an offset with /loadalignoffset
-- The player is moved backwards one space to moved them out of the load zone (or more if there is and offset). This may mean the player ends up inside a node (if it suddenly gets dark). You may be able to step out. If not you'll have to teleport to an unblocked location.
-- The /save command saves the file with the origin at the xmin,ymin,zmin, irrespective of where pos1 and pos2 are. To reduce confusion it is suggested that you use the /correctorigin command before saving
-- to move the markers to reflect this, but if you are copying a section one node wide, there are two possible orientations.
-- You need to be facing in the positive z direction to correctly orient yourself to the orientation when it is reloaded.
-- If you are using a schem regularly, and markers are not in your prefered orientation, it is best to do an initial /loadalign to get the correct orientation, then resave it
-- The loaded region is marked with pos1/pos2 with pos1 where the origin would have been when the schem was saved.
-- The function has only been tested with the current (version 4) schem files, so consider use with older schem files to be at your own risk.
-- The most likely bugs with untested versions are: either the entire region is incorrectly rotated or individual nodes are incorrectly oriented (so faces point in the incorrect direction)
-- The functions is a modifications of the original register //load to support alignment relative to player, so code from the screwdriver mod was used as a starter for node orientation.
-- The main functions are in the WorldEdit/worldedit/serialization.lua (worldedit.deserializeAligned which also uses worldedit.getNewRotation, and might need worldedit.screwdriver_handler
-- depending on compatibility with old files)
-- Shortcut of /la is set in worldedit_shortcommands/init.lua
minetest.register_chatcommand("/loadalign", {
params = "<file>",
-- usePlayer (p) forces using player location rather than position markers prior to load. markImport (m) places pos1/pos2 around the new region"
description = "Load nodes from \"(world folder)/schems/<file>[.we[m]]\" with position 1 (or player location) of the current WorldEdit region as the origin. xyz offset from the player/pos1 position (eg for foundations), can be set with /loadalignoffset.",
privs = {worldedit=true},
func = function(name, param)
local posOffx, posOffy, posOffz
local player = minetest.get_player_by_name(name)
local plPos = player:getpos()
local pos
local missingMods = ""
-- There's probably a snazzy way of using patterns to enable multiple optional parameters including a filename, but I don't know how...
-- ideally I would like to be able to supply as params: filename, pos, usePlayer, markImport
fileName = param
-- if this function ever gets merged with load, it's probably easier to be able to determine if player should be used as the origin
-- also anything but 'p' will use pos1 as the origin (if it's set), and just use the player for alignment
usePlayer = "p"
markImport = "m" -- mark the dimensions of the loaded section (anything but 'm' will not mark
-- if set use the global posOffset (as this enables offset to be set once and reused)
if laPosOffset == nil then
posOffx, posOffy, posOffz = 0, 0, 0
else
posOffx, posOffy, posOffz = laPosOffset.x, laPosOffset.y, laPosOffset.z
end
if usePlayer ~= "p" then pos = get_position(name) end
if pos == nil then
usePlayer = "p"
pos = plPos
end
pos = {x=math.floor(pos.x+posOffx+0.51),y=math.floor(pos.y+posOffy+0.51),z=math.floor(pos.z+posOffz+0.51)}
if fileName == "" then
worldedit.player_notify(name, "invalid usage: " .. param)
return
end
if not string.find(fileName, "^[%w \t.,+-_=!@#$%%^&*()%[%]{};'\"]+$") then
worldedit.player_notify(name, "invalid file name: " .. param)
return
end
--find the file in the world path, check it exists
local testpaths = {
minetest.get_worldpath() .. "/schems/" .. fileName,
minetest.get_worldpath() .. "/schems/" .. fileName .. ".we",
minetest.get_worldpath() .. "/schems/" .. fileName .. ".wem",
}
local file, err
for index, path in ipairs(testpaths) do
file, err = io.open(path, "rb")
if not err then
break
end
end
if err then
worldedit.player_notify(name, "could not open file \"" .. param .. "\"")
return
end
local value = file:read("*a")
file:close()
-- check the schem version is recognised
if worldedit.valueversion(value) == 0 then --unknown version
worldedit.player_notify(name, "invalid file: file is invalid or created with newer version of WorldEdit")
return
end
-- identify the direction the player is facing, and move them player out of the load region
local dir = player:get_look_dir()
local axx, axy, axz = math.abs(dir.x), math.abs(dir.y), math.abs(dir.z)
if axx > axz and dir.x >= 0 then
axis = "X"
if usePlayer == "p" then player:setpos({x=(plPos.x-1+posOffx), y=plPos.y, z=plPos.z}) end
elseif axx > axz and dir.x < 0 then
axis = "x"
if usePlayer == "p" then player:setpos({x=(plPos.x+1-posOffx), y=plPos.y, z=plPos.z}) end
elseif axx < axz and dir.z >= 0 then
axis = "Z"
if usePlayer == "p" then player:setpos({x=plPos.x, y=plPos.y, z=(plPos.z-1+posOffz)}) end
elseif axx < axz and dir.z < 0 then
axis = "z"
if usePlayer == "p" then player:setpos({x=plPos.x, y=plPos.y, z=(plPos.z+1-posOffz)}) end
end
local count, pos1, pos2, missingMods = worldedit.deserializeAligned(pos, value, axis)
-- placer pos1 and pos2 markers around the loaded region
if markImport == "m" then
worldedit.pos1[name] = pos1
worldedit.mark_pos1(name)
worldedit.pos2[name] = pos2
worldedit.mark_pos2(name)
end
worldedit.player_notify(name, (count .. " nodes loaded. PlayerFacing: ".. axis.. " Location: x=".. pos.x.. " y=".. pos.y.. " z=".. pos.z.. " Offset: x=".. posOffx.. " y=".. posOffy.. " z=".. posOffz )) --.. x ", y=".. y, "z=".. z)
if missingMods ~= "" then
worldedit.player_notify(name, "Warning: schem file contains references to the following missing mods: ".. missingMods)
end
end,
})

View File

@ -47,4 +47,8 @@ worldedit.alias_chatcommand("/hlt", "/highlight")
worldedit.alias_chatcommand("/rsr", "/restore")
worldedit.alias_chatcommand("/l", "/lua")
worldedit.alias_chatcommand("/lt", "/luatransform")
worldedit.alias_chatcommand("/clro", "/clearobjects")
worldedit.alias_chatcommand("/clro", "/clearobjects")
worldedit.alias_chatcommand("/la", "/loadalign")
worldedit.alias_chatcommand("/lao", "/loadalignoffset")
worldedit.alias_chatcommand("/co", "/correctorigin")
worldedit.alias_chatcommand("/oc", "/correctorigin")