245 lines
7.0 KiB
Lua
245 lines
7.0 KiB
Lua
-- code stolen from jumpdrive and worldedit_commands
|
|
|
|
-- simulate jump
|
|
local simulate_jump = function(source_pos1, source_pos2, delta) --, show_marker)
|
|
|
|
if source_pos1 == nil or
|
|
source_pos2 == nil or
|
|
delta == nil then
|
|
minetest.log("error", "[worldedit_jumpdrive] simulate_jump: invalid pos/delta")
|
|
return
|
|
end
|
|
|
|
local target_pos1 = vector.add(source_pos1, delta)
|
|
local target_pos2 = vector.add(source_pos2, delta)
|
|
|
|
if jumpdrive.check_mapgen(target_pos1) then -- TODO: use middle between pos1 and pos2?
|
|
return false, "Error: mapgen was active in this area, please try again later for your own safety!"
|
|
end
|
|
|
|
local x_overlap = (target_pos1.x <= source_pos2.x and target_pos1.x >= source_pos1.x) or
|
|
(target_pos2.x <= source_pos2.x and target_pos2.x >= source_pos1.x)
|
|
local y_overlap = (target_pos1.y <= source_pos2.y and target_pos1.y >= source_pos1.y) or
|
|
(target_pos2.y <= source_pos2.y and target_pos2.y >= source_pos1.y)
|
|
local z_overlap = (target_pos1.z <= source_pos2.z and target_pos1.z >= source_pos1.z) or
|
|
(target_pos2.z <= source_pos2.z and target_pos2.z >= source_pos1.z)
|
|
|
|
if x_overlap and y_overlap and z_overlap then
|
|
return false, "Error: jump into itself! extend your jump target"
|
|
end
|
|
|
|
-- load chunk
|
|
minetest.get_voxel_manip():read_from_map(target_pos1, target_pos2)
|
|
|
|
-- TODO: markers
|
|
--if show_marker then
|
|
-- jumpdrive.show_marker(targetPos, radius, "red")
|
|
-- jumpdrive.show_marker(pos, radius, "green")
|
|
--end
|
|
|
|
local msg = nil
|
|
local success = true
|
|
|
|
local blacklisted_pos_list = minetest.find_nodes_in_area(source_pos1, source_pos2, jumpdrive.blacklist)
|
|
for _, nodepos in ipairs(blacklisted_pos_list) do
|
|
return false, "Can't jump node @ " .. minetest.pos_to_string(nodepos)
|
|
end
|
|
|
|
--if next(minetest.find_nodes_in_area(target_pos1, target_pos2, {"vacuum:vacuum"})) ~= nil then
|
|
-- msg = "Warning: Jump-target is in vacuum!"
|
|
--end
|
|
|
|
local ignore_pos_list = minetest.find_nodes_in_area(target_pos1, target_pos2, {"ignore"})
|
|
for _, nodepos in ipairs(ignore_pos_list) do
|
|
return false, "Warning: Jump-target is in uncharted area"
|
|
end
|
|
|
|
local is_empty, empty_msg = jumpdrive.is_area_empty(target_pos1, target_pos2)
|
|
|
|
if not is_empty then
|
|
msg = "Jump-target is obstructed (" .. empty_msg .. ")"
|
|
success = false
|
|
end
|
|
|
|
return success, msg
|
|
end
|
|
|
|
-- execute jump
|
|
local execute_jump = function(source_pos1, source_pos2, delta, name, force)
|
|
|
|
if source_pos1 == nil or
|
|
source_pos2 == nil or
|
|
delta == nil then
|
|
minetest.log("error", "[worldedit_jumpdrive] execute_jump: invalid pos/delta")
|
|
return
|
|
end
|
|
|
|
local target_pos1 = vector.add(source_pos1, delta)
|
|
local target_pos2 = vector.add(source_pos2, delta)
|
|
|
|
local success, msg = simulate_jump(source_pos1, source_pos2, delta)
|
|
if not (success or force) then
|
|
return false, msg
|
|
end
|
|
|
|
local t0 = minetest.get_us_time()
|
|
|
|
if name and type(name) == "string" then
|
|
local pos = minetest.get_player_by_name(name):get_pos()
|
|
minetest.sound_play("jumpdrive_engine", {
|
|
pos = pos,
|
|
max_hear_distance = 50,
|
|
gain = 0.7,
|
|
})
|
|
end
|
|
|
|
-- actual move
|
|
jumpdrive.move(source_pos1, source_pos2, target_pos1, target_pos2)
|
|
|
|
local t1 = minetest.get_us_time()
|
|
local time_micros = t1 - t0
|
|
|
|
minetest.log("action", "[jumpdrive] jump took " .. time_micros .. " us")
|
|
|
|
-- show animation in source
|
|
minetest.add_particlespawner({
|
|
amount = 200,
|
|
time = 2,
|
|
minpos = source_pos1,
|
|
maxpos = source_pos2,
|
|
minvel = {x = -2, y = -2, z = -2},
|
|
maxvel = {x = 2, y = 2, z = 2},
|
|
minacc = {x = -3, y = -3, z = -3},
|
|
maxacc = {x = 3, y = 3, z = 3},
|
|
minexptime = 0.1,
|
|
maxexptime = 5,
|
|
minsize = 1,
|
|
maxsize = 1,
|
|
texture = "spark.png",
|
|
glow = 5,
|
|
})
|
|
|
|
|
|
-- show animation in target
|
|
minetest.add_particlespawner({
|
|
amount = 200,
|
|
time = 2,
|
|
minpos = target_pos1,
|
|
maxpos = target_pos2,
|
|
minvel = {x = -2, y = -2, z = -2},
|
|
maxvel = {x = 2, y = 2, z = 2},
|
|
minacc = {x = -3, y = -3, z = -3},
|
|
maxacc = {x = 3, y = 3, z = 3},
|
|
minexptime = 0.1,
|
|
maxexptime = 5,
|
|
minsize = 1,
|
|
maxsize = 1,
|
|
texture = "spark.png",
|
|
glow = 5,
|
|
})
|
|
|
|
return true, time_micros
|
|
end
|
|
|
|
-- //simulate_jump
|
|
worldedit.register_command("simulate_jump", {
|
|
params = "<x> <y> <z>",
|
|
description = "Simulate a jump of the current WorldEdit region along the vector (<x> <y> <z>)",
|
|
privs = {worldedit=true},
|
|
require_pos = 2,
|
|
parse = function(param)
|
|
local delta = minetest.string_to_pos(param)
|
|
if delta == nil then
|
|
return false
|
|
end
|
|
return true, delta
|
|
end,
|
|
nodes_needed = function(name, delta)
|
|
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) * 2
|
|
end,
|
|
func = function(name, delta)
|
|
if delta == nil then
|
|
worldedit.player_notify(name, "delta error")
|
|
return
|
|
end
|
|
|
|
local source_pos1, source_pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
|
|
local success, msg = simulate_jump(source_pos1, source_pos2, delta)
|
|
|
|
worldedit.player_notify(name, "[worldedit_jumpdrive] Result: " ..
|
|
tostring(success) .. ", " .. tostring(msg))
|
|
end,
|
|
})
|
|
|
|
-- //jump
|
|
worldedit.register_command("jump", {
|
|
params = "<x> <y> <z>",
|
|
description = "Jump the current WorldEdit region along the vector (<x> <y> <z>)",
|
|
privs = {worldedit=true},
|
|
require_pos = 2,
|
|
parse = function(param)
|
|
local delta = minetest.string_to_pos(param)
|
|
if delta == nil then
|
|
return false
|
|
end
|
|
return true, delta
|
|
end,
|
|
nodes_needed = function(name, delta)
|
|
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) * 2
|
|
end,
|
|
func = function(name, delta)
|
|
if delta == nil then
|
|
worldedit.player_notify(name, "delta error")
|
|
return
|
|
end
|
|
|
|
local source_pos1, source_pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
|
|
local success, msg = execute_jump(source_pos1, source_pos2, delta, name)
|
|
|
|
if success then
|
|
worldedit.pos1[name] = vector.add(source_pos1, delta)
|
|
worldedit.pos2[name] = vector.add(source_pos2, delta)
|
|
worldedit.marker_update(name)
|
|
end
|
|
|
|
worldedit.player_notify(name, "[worldedit_jumpdrive] Result: " ..
|
|
tostring(success) .. ", " .. tostring(msg))
|
|
end,
|
|
})
|
|
|
|
-- //force_jump
|
|
worldedit.register_command("force_jump", {
|
|
params = "<x> <y> <z>",
|
|
description = "Jump the current WorldEdit region along the vector (<x> <y> <z>) ignoring all safety checks",
|
|
privs = {worldedit=true},
|
|
require_pos = 2,
|
|
parse = function(param)
|
|
local delta = minetest.string_to_pos(param)
|
|
if delta == nil then
|
|
return false
|
|
end
|
|
return true, delta
|
|
end,
|
|
nodes_needed = function(name, delta)
|
|
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) * 2
|
|
end,
|
|
func = function(name, delta)
|
|
if delta == nil then
|
|
worldedit.player_notify(name, "delta error")
|
|
return
|
|
end
|
|
|
|
local source_pos1, source_pos2 = worldedit.sort_pos(worldedit.pos1[name], worldedit.pos2[name])
|
|
local success, msg = execute_jump(source_pos1, source_pos2, delta, name, true)
|
|
|
|
if success then
|
|
worldedit.pos1[name] = vector.add(source_pos1, delta)
|
|
worldedit.pos2[name] = vector.add(source_pos2, delta)
|
|
worldedit.marker_update(name)
|
|
end
|
|
|
|
worldedit.player_notify(name, "[worldedit_jumpdrive] Result: " ..
|
|
tostring(success) .. ", " .. tostring(msg))
|
|
end,
|
|
})
|