forked from VoxeLibre/VoxeLibre
Nether portals now work without corners, too
This commit is contained in:
parent
f2bee2286f
commit
130f05b9cd
|
@ -23,17 +23,17 @@ local destroy_portal = function(pos)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local first = true
|
local counter = 1
|
||||||
|
|
||||||
-- p1 metadata of first node
|
|
||||||
local mp1
|
local mp1
|
||||||
for x = p1.x, p2.x do
|
for x = p1.x, p2.x do
|
||||||
for y = p1.y, p2.y do
|
for y = p1.y, p2.y do
|
||||||
for z = p1.z, p2.z do
|
for z = p1.z, p2.z do
|
||||||
local p = vector.new(x, y, z)
|
local p = vector.new(x, y, z)
|
||||||
local m = minetest.get_meta(p)
|
local m = minetest.get_meta(p)
|
||||||
if first then
|
if counter == 2 then
|
||||||
--[[ Only proceed if the first node still has metadata.
|
--[[ Only proceed if the second node still has metadata.
|
||||||
|
(first node is a corner and not needed for the portal)
|
||||||
If it doesn't have metadata, another node propably triggred the delection
|
If it doesn't have metadata, another node propably triggred the delection
|
||||||
routine earlier, so we bail out earlier to avoid an infinite cascade
|
routine earlier, so we bail out earlier to avoid an infinite cascade
|
||||||
of on_destroy events. ]]
|
of on_destroy events. ]]
|
||||||
|
@ -53,7 +53,7 @@ local destroy_portal = function(pos)
|
||||||
m:set_string("portal_frame2", "")
|
m:set_string("portal_frame2", "")
|
||||||
m:set_string("portal_target", "")
|
m:set_string("portal_target", "")
|
||||||
end
|
end
|
||||||
first = false
|
counter = counter + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -139,13 +139,15 @@ local function build_portal(pos, target)
|
||||||
for x = p1.x, p2.x do
|
for x = p1.x, p2.x do
|
||||||
for y = p1.y, p2.y do
|
for y = p1.y, p2.y do
|
||||||
p = {x = x, y = y, z = p1.z}
|
p = {x = x, y = y, z = p1.z}
|
||||||
if not (x == p1.x or x == p2.x or y == p1.y or y == p2.y) then
|
if not ((x == p1.x or x == p2.x) and (y == p1.y or y == p2.y)) then
|
||||||
minetest.set_node(p, {name = "mcl_portals:portal", param2 = 0})
|
if not (x == p1.x or x == p2.x or y == p1.y or y == p2.y) then
|
||||||
|
minetest.set_node(p, {name = "mcl_portals:portal", param2 = 0})
|
||||||
|
end
|
||||||
|
local meta = minetest.get_meta(p)
|
||||||
|
meta:set_string("portal_frame1", minetest.pos_to_string(p1))
|
||||||
|
meta:set_string("portal_frame2", minetest.pos_to_string(p2))
|
||||||
|
meta:set_string("portal_target", minetest.pos_to_string(target))
|
||||||
end
|
end
|
||||||
local meta = minetest.get_meta(p)
|
|
||||||
meta:set_string("portal_frame1", minetest.pos_to_string(p1))
|
|
||||||
meta:set_string("portal_frame2", minetest.pos_to_string(p2))
|
|
||||||
meta:set_string("portal_target", minetest.pos_to_string(target))
|
|
||||||
|
|
||||||
if y ~= p1.y then
|
if y ~= p1.y then
|
||||||
for z = -2, 2 do
|
for z = -2, 2 do
|
||||||
|
@ -189,20 +191,25 @@ end
|
||||||
|
|
||||||
local function move_check(p1, max, dir)
|
local function move_check(p1, max, dir)
|
||||||
local p = {x = p1.x, y = p1.y, z = p1.z}
|
local p = {x = p1.x, y = p1.y, z = p1.z}
|
||||||
local d = math.abs(max - p1[dir]) / (max - p1[dir])
|
local d = math.sign(max - p1[dir])
|
||||||
|
local min = p[dir]
|
||||||
|
|
||||||
while p[dir] ~= max do
|
for k = min, max, d do
|
||||||
p[dir] = p[dir] + d
|
p[dir] = k
|
||||||
if minetest.get_node(p).name ~= "mcl_core:obsidian" then
|
local node = minetest.get_node(p)
|
||||||
|
-- Check for obsidian (except at corners)
|
||||||
|
if k ~= min and k ~= max and node.name ~= "mcl_core:obsidian" then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
-- Abort if any of the portal frame blocks already has metadata.
|
-- Abort if any of the portal frame blocks already has metadata.
|
||||||
-- This mod does not yet portals which neighbor each other directly.
|
-- This mod does not yet portals which neighbor each other directly.
|
||||||
-- TODO: Reorganize the way how portal frame coordinates are stored.
|
-- TODO: Reorganize the way how portal frame coordinates are stored.
|
||||||
local meta = minetest.get_meta(p)
|
if node.name == "mcl_core:obsidian" then
|
||||||
local p1 = meta:get_string("portal_frame1")
|
local meta = minetest.get_meta(p)
|
||||||
if minetest.string_to_pos(p1) ~= nil then
|
local pframe1 = meta:get_string("portal_frame1")
|
||||||
return false
|
if minetest.string_to_pos(pframe1) ~= nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -289,16 +296,17 @@ local function make_portal(pos)
|
||||||
target.y = find_nether_target_y(target.x, target.z)
|
target.y = find_nether_target_y(target.x, target.z)
|
||||||
end
|
end
|
||||||
|
|
||||||
for d = 0, 3 do
|
local dmin, dmax, ymin, ymax = 0, 3, p1.y, p2.y
|
||||||
for y = p1.y, p2.y do
|
for d = dmin, dmax do
|
||||||
local p = {}
|
for y = ymin, ymax do
|
||||||
|
if not ((d == dmin or d == dmax) and (y == ymin or y == ymax)) then
|
||||||
|
local p
|
||||||
if param2 == 0 then
|
if param2 == 0 then
|
||||||
p = {x = p1.x + d, y = y, z = p1.z}
|
p = {x = p1.x + d, y = y, z = p1.z}
|
||||||
else
|
else
|
||||||
p = {x = p1.x, y = y, z = p1.z + d}
|
p = {x = p1.x, y = y, z = p1.z + d}
|
||||||
end
|
end
|
||||||
if minetest.get_node(p).name == "air"
|
if minetest.get_node(p).name == "air" then
|
||||||
then
|
|
||||||
minetest.set_node(p, {name = "mcl_portals:portal", param2 = param2})
|
minetest.set_node(p, {name = "mcl_portals:portal", param2 = param2})
|
||||||
end
|
end
|
||||||
local meta = minetest.get_meta(p)
|
local meta = minetest.get_meta(p)
|
||||||
|
@ -311,6 +319,7 @@ local function make_portal(pos)
|
||||||
meta:set_string("portal_target", minetest.pos_to_string(target))
|
meta:set_string("portal_target", minetest.pos_to_string(target))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue