forked from mtcontrib/nether-pack
change nether pearl and portal.lua
This commit is contained in:
parent
6245b9e4e1
commit
524312a8d3
@ -18,4 +18,5 @@ If you got ideas or found bugs, please tell them to me.
|
|||||||
|
|
||||||
|
|
||||||
TODO:
|
TODO:
|
||||||
— find a way to get the perlin noise inside [-1; 1] or use another noise
|
— find a way to get the perlin noise inside [-1; 1] or use another noise
|
||||||
|
— add something containing items to that buildings
|
||||||
|
236
nether/pearl.lua
236
nether/pearl.lua
@ -7,36 +7,60 @@ local function table_contains(t, v)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local teleportball_player
|
local creative = minetest.setting_getbool("creative_mode")
|
||||||
local function throw_pearl(item, player)
|
local function throw_pearl(item, player)
|
||||||
local playerpos = player:getpos()
|
local playerpos = player:getpos()
|
||||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, "nether:pearl_entity")
|
playerpos.y = playerpos.y+1.625
|
||||||
|
local obj = minetest.add_entity(playerpos, "nether:pearl_entity")
|
||||||
local dir = player:get_look_dir()
|
local dir = player:get_look_dir()
|
||||||
obj:setvelocity({x=dir.x*30, y=dir.y*30, z=dir.z*30})
|
obj:setvelocity(vector.multiply(dir, 30))
|
||||||
obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
|
obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
|
||||||
if not minetest.setting_getbool("creative_mode") then
|
obj:get_luaentity().player = player:get_player_name()
|
||||||
|
if not creative then
|
||||||
item:take_item()
|
item:take_item()
|
||||||
|
return item
|
||||||
end
|
end
|
||||||
teleportball_player = player
|
|
||||||
return item
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local ENTITY = {
|
local function get_node(pos)
|
||||||
timer=0,
|
local name = minetest.get_node(pos).name
|
||||||
collisionbox = {0,0,0,0,0,0}, --not pointable
|
if name == "ignore" then
|
||||||
physical = false, -- Collides with things
|
minetest.get_voxel_manip():read_from_map(pos, pos)
|
||||||
textures = {"nether_pearl.png"},
|
name = minetest.get_node_or_nil(pos)
|
||||||
lastpos={},
|
if not name then
|
||||||
player = "",
|
return
|
||||||
}
|
end
|
||||||
|
name = name.name
|
||||||
|
end
|
||||||
|
return name
|
||||||
|
end
|
||||||
|
|
||||||
local allowed_nodes = {"air", "default:water_source"}
|
local softs = {}
|
||||||
|
local function is_soft(pos)
|
||||||
|
local name = get_node(pos)
|
||||||
|
if not name then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local is_soft = softs[name]
|
||||||
|
if is_soft ~= nil then
|
||||||
|
return is_soft
|
||||||
|
end
|
||||||
|
if not minetest.registered_nodes[name] then
|
||||||
|
softs[name] = false
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
is_soft = minetest.registered_nodes[name].walkable == false
|
||||||
|
softs[name] = is_soft
|
||||||
|
return is_soft
|
||||||
|
end
|
||||||
|
|
||||||
|
-- teleports the player there if there's free space
|
||||||
local function teleport_player(pos, player)
|
local function teleport_player(pos, player)
|
||||||
local nd2 = minetest.get_node(pos).name
|
local nd2 = is_soft(pos)
|
||||||
pos.y = pos.y+1
|
pos.y = pos.y+1
|
||||||
local nd3 = minetest.get_node(pos).name
|
local nd3 = is_soft(pos)
|
||||||
if table_contains(allowed_nodes, nd2)
|
if nd2
|
||||||
and table_contains(allowed_nodes, nd3) then
|
and nd3 then
|
||||||
pos.y = pos.y-1.4
|
pos.y = pos.y-1.4
|
||||||
player:moveto(pos)
|
player:moveto(pos)
|
||||||
pos.y = pos.y-0.6
|
pos.y = pos.y-0.6
|
||||||
@ -45,70 +69,130 @@ local function teleport_player(pos, player)
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
ENTITY.on_step = function(self, dtime)
|
--[[
|
||||||
self.timer=self.timer+dtime
|
local dg_ps = {}
|
||||||
|
local function forceload(pos)
|
||||||
|
dg_ps[#dg_ps+1] = pos
|
||||||
|
minetest.forceload_block(pos)
|
||||||
|
minetest.after(5, function(pos)
|
||||||
|
minetest.forceload_free_block(pos)
|
||||||
|
for i,p in pairs(dg_ps) do
|
||||||
|
if vector.equals(p, pos) then
|
||||||
|
dg_ps[i] = nil
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end, pos)
|
||||||
|
end
|
||||||
|
minetest.register_on_shutdown(function()
|
||||||
|
for _,p in pairs(dg_ps) do
|
||||||
|
minetest.forceload_free_block(p)
|
||||||
|
end
|
||||||
|
end)--]]
|
||||||
|
|
||||||
|
minetest.register_entity("nether:pearl_entity", {
|
||||||
|
timer = 0,
|
||||||
|
collisionbox = {0,0,0,0,0,0}, --not pointable
|
||||||
|
physical = false, -- Collides with things
|
||||||
|
textures = {"nether_pearl.png"},
|
||||||
|
on_activate = function(self, staticdata)
|
||||||
|
if not staticdata
|
||||||
|
or staticdata == "" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local tmp = minetest.deserialize(staticdata)
|
||||||
|
if not tmp then
|
||||||
|
minetest.log("error", "[nether] pearl: invalid staticdata ")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.player = tmp.player
|
||||||
|
end,
|
||||||
|
get_staticdata = function(self)
|
||||||
|
--forceload(vector.round(self.object:getpos()))
|
||||||
|
return minetest.serialize({
|
||||||
|
player = self.player,
|
||||||
|
})
|
||||||
|
end,
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
self.timer = self.timer+dtime
|
||||||
|
|
||||||
|
--[[
|
||||||
|
local delay = self.delay
|
||||||
|
if delay < 0.1 then
|
||||||
|
self.delay = delay+dtime
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self.delay = 0--]]
|
||||||
|
|
||||||
|
if self.timer > 20 then
|
||||||
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local pos = self.object:getpos()
|
||||||
|
local rpos = vector.round(pos)
|
||||||
|
local lastpos = self.lastpos
|
||||||
|
if not lastpos then
|
||||||
|
self.lastpos = vector.new(rpos)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if lastpos.x
|
||||||
|
and vector.equals(vector.round(lastpos), rpos) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local player = self.player
|
||||||
|
if not player then
|
||||||
|
minetest.log("error", "[nether] pearl: missing playername")
|
||||||
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
player = minetest.get_player_by_name(player)
|
||||||
|
if not player then
|
||||||
|
minetest.log("error", "[nether] pearl: missing player")
|
||||||
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if not get_node(rpos) then
|
||||||
|
minetest.log("error", "[nether] pearl: missing node")
|
||||||
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
self.lastpos = vector.new(pos)
|
||||||
|
|
||||||
--[[ local delay = self.delay
|
|
||||||
if delay < 0.1 then
|
|
||||||
self.delay = delay+dtime
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self.delay = 0]]
|
|
||||||
local pos = self.object:getpos()
|
|
||||||
local lastpos = self.lastpos
|
|
||||||
if lastpos.x
|
|
||||||
and vector.equals(vector.round(lastpos), vector.round(pos)) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local player = self.player
|
|
||||||
if not player
|
|
||||||
or player == "" then
|
|
||||||
self.player = teleportball_player
|
|
||||||
player = teleportball_player
|
|
||||||
end
|
|
||||||
if not player then
|
|
||||||
self.object:remove()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if lastpos.x then --If there is no lastpos for some reason.
|
|
||||||
local free, p = minetest.line_of_sight(lastpos, pos)
|
local free, p = minetest.line_of_sight(lastpos, pos)
|
||||||
if not free then
|
if free then
|
||||||
local nd1 = minetest.get_node(p).name
|
return
|
||||||
if not table_contains(allowed_nodes, nd1)
|
end
|
||||||
and nd1 ~= "ignore" then
|
if is_soft(p) then
|
||||||
self.object:remove()
|
return
|
||||||
minetest.after(0, function(p) --minetest.after us used that the sound is played after the teleportation
|
end
|
||||||
minetest.sound_play("nether_pearl", {pos=p, max_hear_distance=10})
|
self.object:remove()
|
||||||
end, p)
|
minetest.after(0, function(p) --minetest.after is used that the sound is played after the teleportation
|
||||||
p.y = p.y+1
|
minetest.sound_play("nether_pearl", {pos=p, max_hear_distance=10})
|
||||||
if teleport_player(p, player) then
|
end, p)
|
||||||
|
p.y = p.y+1
|
||||||
|
if teleport_player(p, player) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
p.y = p.y-2
|
||||||
|
for i = -1,1,2 do
|
||||||
|
for _,j in pairs({{i, 0}, {0, i}}) do
|
||||||
|
if teleport_player({x=p.x+j[1], y=p.y, z=p.z+j[2]}, player) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
p.y = p.y-2
|
end
|
||||||
for i = -1,1,2 do
|
end
|
||||||
for _,j in pairs({{i, 0}, {0, i}}) do
|
for i = -1,1,2 do
|
||||||
if teleport_player({x=p.x+j[1], y=p.y, z=p.z+j[2]}, player) then
|
for j = -1,1,2 do
|
||||||
return
|
if teleport_player({x=p.x+j, y=p.y, z=p.z+i}, player) then
|
||||||
end
|
return
|
||||||
end
|
|
||||||
end
|
|
||||||
for i = -1,1,2 do
|
|
||||||
for j = -1,1,2 do
|
|
||||||
if teleport_player({x=p.x+j, y=p.y, z=p.z+i}, player) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if self.timer > 20 then
|
})
|
||||||
self.object:remove()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self.lastpos = vector.new(pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_entity("nether:pearl_entity", ENTITY)
|
|
||||||
|
|
||||||
minetest.override_item("nether:pearl", {on_use = throw_pearl})
|
minetest.override_item("nether:pearl", {on_use = throw_pearl})
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
-- kills the player if he uses PilzAdam portal
|
-- kills the player if he uses PilzAdam portal
|
||||||
local obsidian_portal_kills = true
|
local obsidian_portal_kills = true
|
||||||
local portal_target = nether.buildings+1
|
local portal_target = nether.buildings+1
|
||||||
local damage_enabled = minetest.setting_getbool("enable_damage")
|
local nether_prisons = minetest.setting_getbool("enable_damage")
|
||||||
|
|
||||||
local abm_allowed
|
local abm_allowed
|
||||||
minetest.after(5, function()
|
minetest.after(5, function()
|
||||||
@ -40,7 +40,7 @@ local function save_nether_players()
|
|||||||
end
|
end
|
||||||
|
|
||||||
local update_background
|
local update_background
|
||||||
if damage_enabled then
|
if nether_prisons then
|
||||||
function update_background(player, down)
|
function update_background(player, down)
|
||||||
if down then
|
if down then
|
||||||
player:set_sky({r=15, g=0, b=0}, "plain")
|
player:set_sky({r=15, g=0, b=0}, "plain")
|
||||||
@ -84,372 +84,372 @@ local function player_from_nether(player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if damage_enabled then
|
if nether_prisons then
|
||||||
local function player_exists(name)
|
local function player_exists(name)
|
||||||
for _,player in pairs(minetest.get_connected_players()) do
|
for _,player in pairs(minetest.get_connected_players()) do
|
||||||
if player:get_player_name() == name then
|
if player:get_player_name() == name then
|
||||||
return true
|
return true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Chatcommands (edited) written by sss
|
-- Chatcommands (edited) written by sss
|
||||||
minetest.register_chatcommand("to_hell", {
|
minetest.register_chatcommand("to_hell", {
|
||||||
params = "[<player_name>]",
|
params = "[<player_name>]",
|
||||||
description = "Send someone to hell",
|
description = "Send someone to hell",
|
||||||
func = function(name, pname)
|
func = function(name, pname)
|
||||||
if not minetest.check_player_privs(name, {nether=true}) then
|
if not minetest.check_player_privs(name, {nether=true}) then
|
||||||
return false, "You need the nether priv to execute this chatcommand."
|
return false, "You need the nether priv to execute this chatcommand."
|
||||||
|
end
|
||||||
|
if not player_exists(pname) then
|
||||||
|
pname = name
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if not player then
|
||||||
|
return false, "Something went wrong."
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(pname, "Go to hell !!!")
|
||||||
|
player_to_nether(player)
|
||||||
|
return true, pname.." is now in the nether."
|
||||||
end
|
end
|
||||||
if not player_exists(pname) then
|
})
|
||||||
pname = name
|
|
||||||
end
|
|
||||||
local player = minetest.get_player_by_name(pname)
|
|
||||||
if not player then
|
|
||||||
return false, "Something went wrong."
|
|
||||||
end
|
|
||||||
minetest.chat_send_player(pname, "Go to hell !!!")
|
|
||||||
player_to_nether(player)
|
|
||||||
return true, pname.." is now in the nether."
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_chatcommand("from_hell", {
|
minetest.register_chatcommand("from_hell", {
|
||||||
params = "[<player_name>]",
|
params = "[<player_name>]",
|
||||||
description = "Extract from hell",
|
description = "Extract from hell",
|
||||||
func = function(name, pname)
|
func = function(name, pname)
|
||||||
if not minetest.check_player_privs(name, {nether=true}) then
|
if not minetest.check_player_privs(name, {nether=true}) then
|
||||||
return false, "You need the nether priv to execute this chatcommand."
|
return false, "You need the nether priv to execute this chatcommand."
|
||||||
|
end
|
||||||
|
if not player_exists(pname) then
|
||||||
|
pname = name
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if not player then
|
||||||
|
return false, "Something went wrong."
|
||||||
|
end
|
||||||
|
minetest.chat_send_player(pname, "You are free now")
|
||||||
|
player_from_nether(player)
|
||||||
|
local pos = player:getpos()
|
||||||
|
player:moveto({x=pos.x, y=100, z=pos.z})
|
||||||
|
return true, pname.." is now out of the nether."
|
||||||
end
|
end
|
||||||
if not player_exists(pname) then
|
})
|
||||||
pname = name
|
|
||||||
end
|
|
||||||
local player = minetest.get_player_by_name(pname)
|
|
||||||
if not player then
|
|
||||||
return false, "Something went wrong."
|
|
||||||
end
|
|
||||||
minetest.chat_send_player(pname, "You are free now")
|
|
||||||
player_from_nether(player)
|
|
||||||
local pos = player:getpos()
|
|
||||||
player:moveto({x=pos.x, y=100, z=pos.z})
|
|
||||||
return true, pname.." is now out of the nether."
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_on_respawnplayer(function(player)
|
minetest.register_on_respawnplayer(function(player)
|
||||||
local pname = player:get_player_name()
|
|
||||||
if not table.icontains(players_in_nether, pname) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local target = vector.add(player:getpos(), {x=math.random(-100,100), y=0, z=math.random(-100,100)})
|
|
||||||
target.y = portal_target + math.random(4)
|
|
||||||
player:moveto(target)
|
|
||||||
minetest.after(0, function(pname, target)
|
|
||||||
local player = minetest.get_player_by_name(pname)
|
|
||||||
if player then
|
|
||||||
player:moveto(target)
|
|
||||||
end
|
|
||||||
end, pname, target)
|
|
||||||
return true
|
|
||||||
end)
|
|
||||||
|
|
||||||
local function update_players()
|
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
|
||||||
local pname = player:get_player_name()
|
local pname = player:get_player_name()
|
||||||
local ppos = player:getpos()
|
if not table.icontains(players_in_nether, pname) then
|
||||||
if table.icontains(players_in_nether, pname) then
|
return
|
||||||
if ppos.y > nether.start then
|
end
|
||||||
player:moveto({x=ppos.x, y=portal_target, z=ppos.z})
|
local target = vector.add(player:getpos(), {x=math.random(-100,100), y=0, z=math.random(-100,100)})
|
||||||
update_background(player, true)
|
target.y = portal_target + math.random(4)
|
||||||
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport out of the nether."..
|
player:moveto(target)
|
||||||
|
minetest.after(0, function(pname, target)
|
||||||
|
local player = minetest.get_player_by_name(pname)
|
||||||
|
if player then
|
||||||
|
player:moveto(target)
|
||||||
|
end
|
||||||
|
end, pname, target)
|
||||||
|
return true
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function update_players()
|
||||||
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
local ppos = player:getpos()
|
||||||
|
if table.icontains(players_in_nether, pname) then
|
||||||
|
if ppos.y > nether.start then
|
||||||
|
player:moveto({x=ppos.x, y=portal_target, z=ppos.z})
|
||||||
|
update_background(player, true)
|
||||||
|
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport out of the nether."..
|
||||||
|
"\n2. Maybe the server lagged."..
|
||||||
|
"\n3. please rejoin")]]
|
||||||
|
end
|
||||||
|
elseif ppos.y < nether.start then
|
||||||
|
update_background(player)
|
||||||
|
player:moveto({x=ppos.x, y=20, z=ppos.z})
|
||||||
|
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport to the nether."..
|
||||||
"\n2. Maybe the server lagged."..
|
"\n2. Maybe the server lagged."..
|
||||||
"\n3. please rejoin")]]
|
"\n3. please rejoin")]]
|
||||||
end
|
end
|
||||||
elseif ppos.y < nether.start then
|
|
||||||
update_background(player)
|
|
||||||
player:moveto({x=ppos.x, y=20, z=ppos.z})
|
|
||||||
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport to the nether."..
|
|
||||||
"\n2. Maybe the server lagged."..
|
|
||||||
"\n3. please rejoin")]]
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
local timer = 0 --doesn't work if the server lags
|
local timer = 0 --doesn't work if the server lags
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
timer = timer + dtime;
|
timer = timer + dtime;
|
||||||
if timer >= 2 then
|
if timer >= 2 then
|
||||||
--minetest.after(1, update_players)
|
--minetest.after(1, update_players)
|
||||||
update_players()
|
update_players()
|
||||||
timer = 0
|
timer = 0
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
minetest.after(0, function(player)
|
|
||||||
if player:getpos().y < nether.start then
|
|
||||||
update_background(player, true)
|
|
||||||
end
|
end
|
||||||
end, player)
|
end)
|
||||||
end)
|
|
||||||
|
|
||||||
local function remove_portal_essence(pos)
|
minetest.register_on_joinplayer(function(player)
|
||||||
for z = -1,1 do
|
minetest.after(0, function(player)
|
||||||
for y = -2,2 do
|
if player:getpos().y < nether.start then
|
||||||
for x = -1,1 do
|
update_background(player, true)
|
||||||
local p = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
|
|
||||||
if minetest.get_node(p).name == "nether:portal" then
|
|
||||||
minetest.remove_node(p)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end, player)
|
||||||
end
|
end)
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_abm({
|
local function remove_portal_essence(pos)
|
||||||
nodenames = {"nether:portal"},
|
for z = -1,1 do
|
||||||
interval = 1,
|
for y = -2,2 do
|
||||||
chance = 2,
|
for x = -1,1 do
|
||||||
catch_up = false,
|
local p = {x=pos.x+x, y=pos.y+y, z=pos.z+z}
|
||||||
action = function(pos, node)
|
if minetest.get_node(p).name == "nether:portal" then
|
||||||
if not abm_allowed then
|
minetest.remove_node(p)
|
||||||
return
|
|
||||||
end
|
|
||||||
minetest.add_particlespawner({
|
|
||||||
amount = 32,
|
|
||||||
time = 4,
|
|
||||||
minpos = {x=pos.x-0.25, y=pos.y-0.5, z=pos.z-0.25},
|
|
||||||
maxpos = {x=pos.x+0.25, y=pos.y+0.34, z=pos.z+0.25},
|
|
||||||
minvel = {x=0, y=1, z=0},
|
|
||||||
maxvel = {x=0, y=2, z=0},
|
|
||||||
minacc = {x=-0.5,y=-3,z=-0.3},
|
|
||||||
maxacc = {x=0.5,y=-0.4,z=0.3},
|
|
||||||
minexptime = 1,
|
|
||||||
maxexptime = 1,
|
|
||||||
minsize = 0.4,
|
|
||||||
maxsize = 3,
|
|
||||||
collisiondetection = true,
|
|
||||||
texture = "nether_portal_particle.png^[transform"..math.random(0,7),
|
|
||||||
})
|
|
||||||
for _,obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do
|
|
||||||
if obj:is_player() then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local target = minetest.string_to_pos(meta:get_string("target"))
|
|
||||||
if target then
|
|
||||||
minetest.after(3, function(obj, pos, target)
|
|
||||||
local pname = obj:get_player_name()
|
|
||||||
if table.icontains(players_in_nether, pname) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local objpos = obj:getpos()
|
|
||||||
objpos.y = objpos.y+0.1 -- Fix some glitches at -8000
|
|
||||||
if minetest.get_node(vector.round(objpos)).name ~= "nether:portal" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
remove_portal_essence(pos)
|
|
||||||
|
|
||||||
minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1})
|
|
||||||
player_to_nether(obj)
|
|
||||||
--obj:setpos(target)
|
|
||||||
|
|
||||||
end, obj, pos, target)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
local function move_check(p1, max, dir)
|
|
||||||
local p = {x=p1.x, y=p1.y, z=p1.z}
|
|
||||||
local d = math.abs(max-p1[dir]) / (max-p1[dir])
|
|
||||||
while p[dir] ~= max do
|
|
||||||
p[dir] = p[dir] + d
|
|
||||||
if minetest.get_node(p).name ~= "default:obsidian" then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local function check_portal(p1, p2)
|
|
||||||
if p1.x ~= p2.x then
|
|
||||||
if not move_check(p1, p2.x, "x") then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
if not move_check(p2, p1.x, "x") then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
elseif p1.z ~= p2.z then
|
|
||||||
if not move_check(p1, p2.z, "z") then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
if not move_check(p2, p1.z, "z") then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if not move_check(p1, p2.y, "y") then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
if not move_check(p2, p1.y, "y") then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local function is_portal(pos)
|
|
||||||
for d=-3,3 do
|
|
||||||
for y=-4,4 do
|
|
||||||
local px = {x=pos.x+d, y=pos.y+y, z=pos.z}
|
|
||||||
local pz = {x=pos.x, y=pos.y+y, z=pos.z+d}
|
|
||||||
if check_portal(px, {x=px.x+3, y=px.y+4, z=px.z}) then
|
|
||||||
return px, {x=px.x+3, y=px.y+4, z=px.z}
|
|
||||||
end
|
|
||||||
if check_portal(pz, {x=pz.x, y=pz.y+4, z=pz.z+3}) then
|
|
||||||
return pz, {x=pz.x, y=pz.y+4, z=pz.z+3}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function make_portal(pos)
|
|
||||||
local p1, p2 = is_portal(pos)
|
|
||||||
if not p1
|
|
||||||
or not p2 then
|
|
||||||
print("[nether] something failed.")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if p1.y < nether.start then
|
|
||||||
print("[nether] aborted, obsidian portals can't be used to get out")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for d=1,2 do
|
|
||||||
for y=p1.y+1,p2.y-1 do
|
|
||||||
local p
|
|
||||||
if p1.z == p2.z then
|
|
||||||
p = {x=p1.x+d, y=y, z=p1.z}
|
|
||||||
else
|
|
||||||
p = {x=p1.x, y=y, z=p1.z+d}
|
|
||||||
end
|
|
||||||
if minetest.get_node(p).name ~= "air" then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local param2
|
|
||||||
if p1.z == p2.z then
|
|
||||||
param2 = 0
|
|
||||||
else
|
|
||||||
param2 = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
local target = {x=p1.x, y=p1.y, z=p1.z}
|
|
||||||
target.x = target.x + 1
|
|
||||||
target.y = portal_target + math.random(4)
|
|
||||||
|
|
||||||
for d=0,3 do
|
|
||||||
for y=p1.y,p2.y do
|
|
||||||
local p = {}
|
|
||||||
if param2 == 0 then
|
|
||||||
p = {x=p1.x+d, y=y, z=p1.z}
|
|
||||||
else
|
|
||||||
p = {x=p1.x, y=y, z=p1.z+d}
|
|
||||||
end
|
|
||||||
if minetest.get_node(p).name == "air" then
|
|
||||||
minetest.set_node(p, {name="nether:portal", param2=param2})
|
|
||||||
end
|
|
||||||
local meta = minetest.get_meta(p)
|
|
||||||
meta:set_string("p1", minetest.pos_to_string(p1))
|
|
||||||
meta:set_string("p2", minetest.pos_to_string(p2))
|
|
||||||
meta:set_string("target", minetest.pos_to_string(target))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
print("[nether] construction accepted.")
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.override_item("default:obsidian", {
|
|
||||||
on_destruct = function(pos)
|
|
||||||
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 == "default:obsidian" or nn == "nether:portal" then
|
|
||||||
if nn == "nether: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 == "default:obsidian" or nn == "nether:portal" then
|
|
||||||
if nn == "nether: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
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.after(0.1, function()
|
|
||||||
minetest.override_item("default:mese_crystal_fragment", {
|
|
||||||
on_place = function(stack, player, pt)
|
|
||||||
if pt.under
|
|
||||||
and minetest.get_node(pt.under).name == "default:obsidian" then
|
|
||||||
print("[nether] tries to enable a portal")
|
|
||||||
local done = make_portal(pt.under)
|
|
||||||
if done then
|
|
||||||
minetest.chat_send_player(
|
|
||||||
player:get_player_name(),
|
|
||||||
"Warning: If you are in the nether you may not be able to find the way out!"
|
|
||||||
)
|
|
||||||
if not minetest.setting_getbool("creative_mode") then
|
|
||||||
stack:take_item()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return stack
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_abm({
|
||||||
|
nodenames = {"nether:portal"},
|
||||||
|
interval = 1,
|
||||||
|
chance = 2,
|
||||||
|
catch_up = false,
|
||||||
|
action = function(pos, node)
|
||||||
|
if not abm_allowed then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.add_particlespawner({
|
||||||
|
amount = 32,
|
||||||
|
time = 4,
|
||||||
|
minpos = {x=pos.x-0.25, y=pos.y-0.5, z=pos.z-0.25},
|
||||||
|
maxpos = {x=pos.x+0.25, y=pos.y+0.34, z=pos.z+0.25},
|
||||||
|
minvel = {x=0, y=1, z=0},
|
||||||
|
maxvel = {x=0, y=2, z=0},
|
||||||
|
minacc = {x=-0.5,y=-3,z=-0.3},
|
||||||
|
maxacc = {x=0.5,y=-0.4,z=0.3},
|
||||||
|
minexptime = 1,
|
||||||
|
maxexptime = 1,
|
||||||
|
minsize = 0.4,
|
||||||
|
maxsize = 3,
|
||||||
|
collisiondetection = true,
|
||||||
|
texture = "nether_portal_particle.png^[transform"..math.random(0,7),
|
||||||
|
})
|
||||||
|
for _,obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do
|
||||||
|
if obj:is_player() then
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local target = minetest.string_to_pos(meta:get_string("target"))
|
||||||
|
if target then
|
||||||
|
minetest.after(3, function(obj, pos, target)
|
||||||
|
local pname = obj:get_player_name()
|
||||||
|
if table.icontains(players_in_nether, pname) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local objpos = obj:getpos()
|
||||||
|
objpos.y = objpos.y+0.1 -- Fix some glitches at -8000
|
||||||
|
if minetest.get_node(vector.round(objpos)).name ~= "nether:portal" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
remove_portal_essence(pos)
|
||||||
|
|
||||||
|
minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1})
|
||||||
|
player_to_nether(obj)
|
||||||
|
--obj:setpos(target)
|
||||||
|
|
||||||
|
end, obj, pos, target)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
local function move_check(p1, max, dir)
|
||||||
|
local p = {x=p1.x, y=p1.y, z=p1.z}
|
||||||
|
local d = math.abs(max-p1[dir]) / (max-p1[dir])
|
||||||
|
while p[dir] ~= max do
|
||||||
|
p[dir] = p[dir] + d
|
||||||
|
if minetest.get_node(p).name ~= "default:obsidian" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function check_portal(p1, p2)
|
||||||
|
if p1.x ~= p2.x then
|
||||||
|
if not move_check(p1, p2.x, "x") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if not move_check(p2, p1.x, "x") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
elseif p1.z ~= p2.z then
|
||||||
|
if not move_check(p1, p2.z, "z") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if not move_check(p2, p1.z, "z") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if not move_check(p1, p2.y, "y") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if not move_check(p2, p1.y, "y") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_portal(pos)
|
||||||
|
for d=-3,3 do
|
||||||
|
for y=-4,4 do
|
||||||
|
local px = {x=pos.x+d, y=pos.y+y, z=pos.z}
|
||||||
|
local pz = {x=pos.x, y=pos.y+y, z=pos.z+d}
|
||||||
|
if check_portal(px, {x=px.x+3, y=px.y+4, z=px.z}) then
|
||||||
|
return px, {x=px.x+3, y=px.y+4, z=px.z}
|
||||||
|
end
|
||||||
|
if check_portal(pz, {x=pz.x, y=pz.y+4, z=pz.z+3}) then
|
||||||
|
return pz, {x=pz.x, y=pz.y+4, z=pz.z+3}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function make_portal(pos)
|
||||||
|
local p1, p2 = is_portal(pos)
|
||||||
|
if not p1
|
||||||
|
or not p2 then
|
||||||
|
print("[nether] something failed.")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
if p1.y < nether.start then
|
||||||
|
print("[nether] aborted, obsidian portals can't be used to get out")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for d=1,2 do
|
||||||
|
for y=p1.y+1,p2.y-1 do
|
||||||
|
local p
|
||||||
|
if p1.z == p2.z then
|
||||||
|
p = {x=p1.x+d, y=y, z=p1.z}
|
||||||
|
else
|
||||||
|
p = {x=p1.x, y=y, z=p1.z+d}
|
||||||
|
end
|
||||||
|
if minetest.get_node(p).name ~= "air" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local param2
|
||||||
|
if p1.z == p2.z then
|
||||||
|
param2 = 0
|
||||||
|
else
|
||||||
|
param2 = 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local target = {x=p1.x, y=p1.y, z=p1.z}
|
||||||
|
target.x = target.x + 1
|
||||||
|
target.y = portal_target + math.random(4)
|
||||||
|
|
||||||
|
for d=0,3 do
|
||||||
|
for y=p1.y,p2.y do
|
||||||
|
local p = {}
|
||||||
|
if param2 == 0 then
|
||||||
|
p = {x=p1.x+d, y=y, z=p1.z}
|
||||||
|
else
|
||||||
|
p = {x=p1.x, y=y, z=p1.z+d}
|
||||||
|
end
|
||||||
|
if minetest.get_node(p).name == "air" then
|
||||||
|
minetest.set_node(p, {name="nether:portal", param2=param2})
|
||||||
|
end
|
||||||
|
local meta = minetest.get_meta(p)
|
||||||
|
meta:set_string("p1", minetest.pos_to_string(p1))
|
||||||
|
meta:set_string("p2", minetest.pos_to_string(p2))
|
||||||
|
meta:set_string("target", minetest.pos_to_string(target))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
print("[nether] construction accepted.")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.override_item("default:obsidian", {
|
||||||
|
on_destruct = function(pos)
|
||||||
|
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 == "default:obsidian" or nn == "nether:portal" then
|
||||||
|
if nn == "nether: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 == "default:obsidian" or nn == "nether:portal" then
|
||||||
|
if nn == "nether: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
|
end
|
||||||
})
|
})
|
||||||
end)
|
|
||||||
|
minetest.after(0.1, function()
|
||||||
|
minetest.override_item("default:mese_crystal_fragment", {
|
||||||
|
on_place = function(stack, player, pt)
|
||||||
|
if pt.under
|
||||||
|
and minetest.get_node(pt.under).name == "default:obsidian" then
|
||||||
|
print("[nether] tries to enable a portal")
|
||||||
|
local done = make_portal(pt.under)
|
||||||
|
if done then
|
||||||
|
minetest.chat_send_player(
|
||||||
|
player:get_player_name(),
|
||||||
|
"Warning: If you are in the nether you may not be able to find the way out!"
|
||||||
|
)
|
||||||
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
|
stack:take_item()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return stack
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user