worldedit_jumpdrive/init.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,
})