mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-12-22 16:09:33 +01:00
Proper portal behaviour WRT explosions
This commit is contained in:
parent
272c456499
commit
6018f0c7cd
2 changed files with 110 additions and 110 deletions
|
@ -16,6 +16,52 @@ local np_cave = {
|
||||||
-- Portal frame material
|
-- Portal frame material
|
||||||
local portal_frame = "mcl_nether:quartz_block"
|
local portal_frame = "mcl_nether:quartz_block"
|
||||||
|
|
||||||
|
-- Destroy portal if pos (portal frame or portal node) got destroyed
|
||||||
|
local destroy_portal = function(pos)
|
||||||
|
-- Deactivate Nether portal
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local p1 = minetest.string_to_pos(meta:get_string("p1"))
|
||||||
|
local p2 = minetest.string_to_pos(meta:get_string("p2"))
|
||||||
|
if not p1 or not p2 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local first = true
|
||||||
|
|
||||||
|
-- p1 metadata of first node
|
||||||
|
local mp1
|
||||||
|
for x = p1.x, p2.x do
|
||||||
|
for y = p1.y, p2.y do
|
||||||
|
for z = p1.z, p2.z do
|
||||||
|
local p = vector.new(x, y, z)
|
||||||
|
local m = minetest.get_meta(p)
|
||||||
|
if first then
|
||||||
|
--[[ Only proceed if the first node still has metadata.
|
||||||
|
If it doesn't have metadata, another node propably triggred the delection
|
||||||
|
routine earlier, so we bail out earlier to avoid an infinite cascade
|
||||||
|
of on_destroy events. ]]
|
||||||
|
mp1 = minetest.string_to_pos(m:get_string("p1"))
|
||||||
|
if not mp1 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local nn = minetest.get_node(p).name
|
||||||
|
if nn == portal_frame or nn == "mcl_portals:portal_end" then
|
||||||
|
-- Remove portal nodes, but not myself
|
||||||
|
if nn == "mcl_portals:portal_end" and not vector.equals(p, pos) then
|
||||||
|
minetest.remove_node(p)
|
||||||
|
end
|
||||||
|
-- Clear metadata of portal nodes and the frame
|
||||||
|
m:set_string("p1", "")
|
||||||
|
m:set_string("p2", "")
|
||||||
|
m:set_string("target", "")
|
||||||
|
end
|
||||||
|
first = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Nodes
|
-- Nodes
|
||||||
minetest.register_node("mcl_portals:portal_end", {
|
minetest.register_node("mcl_portals:portal_end", {
|
||||||
description = "End Portal",
|
description = "End Portal",
|
||||||
|
@ -64,7 +110,11 @@ minetest.register_node("mcl_portals:portal_end", {
|
||||||
{-0.5, -0.5, -0.1, 0.5, 0.5, 0.1},
|
{-0.5, -0.5, -0.1, 0.5, 0.5, 0.1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
groups = {not_in_creative_inventory = 1}
|
groups = {not_in_creative_inventory = 1},
|
||||||
|
on_destruct = destroy_portal,
|
||||||
|
|
||||||
|
_mcl_hardness = -1,
|
||||||
|
_mcl_blast_resistance = 18000000,
|
||||||
})
|
})
|
||||||
|
|
||||||
local function build_end_portal(pos, target3)
|
local function build_end_portal(pos, target3)
|
||||||
|
@ -311,59 +361,7 @@ minetest.register_abm({
|
||||||
|
|
||||||
-- Frame material
|
-- Frame material
|
||||||
minetest.override_item(portal_frame, {
|
minetest.override_item(portal_frame, {
|
||||||
on_destruct = function(pos)
|
on_destruct = destroy_portal,
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local p1 = minetest.string_to_pos(meta:get_string("p1"))
|
|
||||||
local p2 = minetest.string_to_pos(meta:get_string("p2"))
|
|
||||||
local target3 = minetest.string_to_pos(meta:get_string("target3"))
|
|
||||||
if not p1 or not p2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for x = p1.x, p2.x do
|
|
||||||
for y = p1.y, p2.y do
|
|
||||||
for z = p1.z, p2.z do
|
|
||||||
local nn = minetest.get_node({x = x, y = y, z = z}).name
|
|
||||||
if nn == portal_frame or nn == "mcl_portals:portal_end" then
|
|
||||||
if nn == "mcl_portals:portal_end" then
|
|
||||||
minetest.remove_node({x = x, y = y, z = z})
|
|
||||||
end
|
|
||||||
local m = minetest.get_meta({x = x, y = y, z = z})
|
|
||||||
m:set_string("p1", "")
|
|
||||||
m:set_string("p2", "")
|
|
||||||
m:set_string("target3", "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
meta = minetest.get_meta(target3)
|
|
||||||
if not meta then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
p1 = minetest.string_to_pos(meta:get_string("p1"))
|
|
||||||
p2 = minetest.string_to_pos(meta:get_string("p2"))
|
|
||||||
if not p1 or not p2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for x = p1.x, p2.x do
|
|
||||||
for y = p1.y, p2.y do
|
|
||||||
for z = p1.z, p2.z do
|
|
||||||
local nn = minetest.get_node({x = x, y = y, z = z}).name
|
|
||||||
if nn == portal_frame or nn == "mcl_portals:portal_end" then
|
|
||||||
if nn == "mcl_portals:portal_end" then
|
|
||||||
minetest.remove_node({x = x, y = y, z = z})
|
|
||||||
end
|
|
||||||
local m = minetest.get_meta({x = x, y = y, z = z})
|
|
||||||
m:set_string("p1", "")
|
|
||||||
m:set_string("p2", "")
|
|
||||||
m:set_string("target3", "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Portal opener
|
-- Portal opener
|
||||||
|
@ -376,6 +374,9 @@ minetest.override_item("mcl_end:ender_eye", {
|
||||||
-- If used on frame, open portal
|
-- If used on frame, open portal
|
||||||
if pointed_thing.under and minetest.get_node(pointed_thing.under).name == portal_frame then
|
if pointed_thing.under and minetest.get_node(pointed_thing.under).name == portal_frame then
|
||||||
make_end_portal(pointed_thing.under)
|
make_end_portal(pointed_thing.under)
|
||||||
|
if minetest.get_modpath("doc") then
|
||||||
|
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal_end")
|
||||||
|
end
|
||||||
minetest.sound_play(
|
minetest.sound_play(
|
||||||
"fire_flint_and_steel",
|
"fire_flint_and_steel",
|
||||||
{pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8}
|
{pos = pointed_thing.above, gain = 0.5, max_hear_distance = 8}
|
||||||
|
|
|
@ -13,6 +13,52 @@ local np_cave = {
|
||||||
persist = 0.7
|
persist = 0.7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
-- Destroy portal if pos (portal frame or portal node) got destroyed
|
||||||
|
local destroy_portal = function(pos)
|
||||||
|
-- Deactivate Nether portal
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local p1 = minetest.string_to_pos(meta:get_string("p1"))
|
||||||
|
local p2 = minetest.string_to_pos(meta:get_string("p2"))
|
||||||
|
if not p1 or not p2 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local first = true
|
||||||
|
|
||||||
|
-- p1 metadata of first node
|
||||||
|
local mp1
|
||||||
|
for x = p1.x, p2.x do
|
||||||
|
for y = p1.y, p2.y do
|
||||||
|
for z = p1.z, p2.z do
|
||||||
|
local p = vector.new(x, y, z)
|
||||||
|
local m = minetest.get_meta(p)
|
||||||
|
if first then
|
||||||
|
--[[ Only proceed if the first node still has metadata.
|
||||||
|
If it doesn't have metadata, another node propably triggred the delection
|
||||||
|
routine earlier, so we bail out earlier to avoid an infinite cascade
|
||||||
|
of on_destroy events. ]]
|
||||||
|
mp1 = minetest.string_to_pos(m:get_string("p1"))
|
||||||
|
if not mp1 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local nn = minetest.get_node(p).name
|
||||||
|
if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then
|
||||||
|
-- Remove portal nodes, but not myself
|
||||||
|
if nn == "mcl_portals:portal" and not vector.equals(p, pos) then
|
||||||
|
minetest.remove_node(p)
|
||||||
|
end
|
||||||
|
-- Clear metadata of portal nodes and the frame
|
||||||
|
m:set_string("p1", "")
|
||||||
|
m:set_string("p2", "")
|
||||||
|
m:set_string("target", "")
|
||||||
|
end
|
||||||
|
first = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_node("mcl_portals:portal", {
|
minetest.register_node("mcl_portals:portal", {
|
||||||
description = "Nether Portal",
|
description = "Nether Portal",
|
||||||
tiles = {
|
tiles = {
|
||||||
|
@ -59,11 +105,13 @@ minetest.register_node("mcl_portals:portal", {
|
||||||
{-0.5, -0.5, -0.1, 0.5, 0.5, 0.1},
|
{-0.5, -0.5, -0.1, 0.5, 0.5, 0.1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
groups = {not_in_creative_inventory = 1}
|
groups = {not_in_creative_inventory = 1},
|
||||||
|
on_destruct = destroy_portal,
|
||||||
|
|
||||||
|
_mcl_hardness = -1,
|
||||||
|
_mcl_blast_resistance = 0,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- Functions
|
-- Functions
|
||||||
--Build arrival portal
|
--Build arrival portal
|
||||||
local function build_portal(pos, target)
|
local function build_portal(pos, target)
|
||||||
|
@ -327,59 +375,7 @@ minetest.register_abm({
|
||||||
|
|
||||||
-- Frame material
|
-- Frame material
|
||||||
minetest.override_item("mcl_core:obsidian", {
|
minetest.override_item("mcl_core:obsidian", {
|
||||||
on_destruct = function(pos)
|
on_destruct = destroy_portal,
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local p1 = minetest.string_to_pos(meta:get_string("p1"))
|
|
||||||
local p2 = minetest.string_to_pos(meta:get_string("p2"))
|
|
||||||
local target = minetest.string_to_pos(meta:get_string("target"))
|
|
||||||
if not p1 or not p2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for x = p1.x, p2.x do
|
|
||||||
for y = p1.y, p2.y do
|
|
||||||
for z = p1.z, p2.z do
|
|
||||||
local nn = minetest.get_node({x = x, y = y, z = z}).name
|
|
||||||
if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then
|
|
||||||
if nn == "mcl_portals:portal" then
|
|
||||||
minetest.remove_node({x = x, y = y, z = z})
|
|
||||||
end
|
|
||||||
local m = minetest.get_meta({x = x, y = y, z = z})
|
|
||||||
m:set_string("p1", "")
|
|
||||||
m:set_string("p2", "")
|
|
||||||
m:set_string("target", "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
meta = minetest.get_meta(target)
|
|
||||||
if not meta then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
p1 = minetest.string_to_pos(meta:get_string("p1"))
|
|
||||||
p2 = minetest.string_to_pos(meta:get_string("p2"))
|
|
||||||
if not p1 or not p2 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for x = p1.x, p2.x do
|
|
||||||
for y = p1.y, p2.y do
|
|
||||||
for z = p1.z, p2.z do
|
|
||||||
local nn = minetest.get_node({x = x, y = y, z = z}).name
|
|
||||||
if nn == "mcl_core:obsidian" or nn == "mcl_portals:portal" then
|
|
||||||
if nn == "mcl_portals:portal" then
|
|
||||||
minetest.remove_node({x = x, y = y, z = z})
|
|
||||||
end
|
|
||||||
local m = minetest.get_meta({x = x, y = y, z = z})
|
|
||||||
m:set_string("p1", "")
|
|
||||||
m:set_string("p2", "")
|
|
||||||
m:set_string("target", "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Portal opener
|
-- Portal opener
|
||||||
|
@ -396,6 +392,9 @@ minetest.override_item("mcl_fire:flint_and_steel", {
|
||||||
|
|
||||||
if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_core:obsidian" then
|
if pointed_thing.under and minetest.get_node(pointed_thing.under).name == "mcl_core:obsidian" then
|
||||||
make_portal(pointed_thing.under)
|
make_portal(pointed_thing.under)
|
||||||
|
if minetest.get_modpath("doc") then
|
||||||
|
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", "mcl_portals:portal")
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if pointed_thing.type == "node" then
|
if pointed_thing.type == "node" then
|
||||||
local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
|
local nodedef = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
|
||||||
|
|
Loading…
Reference in a new issue