1
0
mirror of https://github.com/HybridDog/nether-pack.git synced 2025-07-03 00:20:45 +02:00

change nether pearl and portal.lua

This commit is contained in:
HybridDog
2016-01-01 12:39:21 +01:00
parent 6245b9e4e1
commit 524312a8d3
3 changed files with 507 additions and 422 deletions

View File

@ -3,7 +3,7 @@
-- kills the player if he uses PilzAdam portal
local obsidian_portal_kills = true
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
minetest.after(5, function()
@ -40,7 +40,7 @@ local function save_nether_players()
end
local update_background
if damage_enabled then
if nether_prisons then
function update_background(player, down)
if down then
player:set_sky({r=15, g=0, b=0}, "plain")
@ -84,372 +84,372 @@ local function player_from_nether(player)
end
if damage_enabled then
local function player_exists(name)
for _,player in pairs(minetest.get_connected_players()) do
if player:get_player_name() == name then
return true
if nether_prisons then
local function player_exists(name)
for _,player in pairs(minetest.get_connected_players()) do
if player:get_player_name() == name then
return true
end
end
return false
end
return false
end
-- Chatcommands (edited) written by sss
minetest.register_chatcommand("to_hell", {
params = "[<player_name>]",
description = "Send someone to hell",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
return false, "You need the nether priv to execute this chatcommand."
-- Chatcommands (edited) written by sss
minetest.register_chatcommand("to_hell", {
params = "[<player_name>]",
description = "Send someone to hell",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
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
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", {
params = "[<player_name>]",
description = "Extract from hell",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
return false, "You need the nether priv to execute this chatcommand."
minetest.register_chatcommand("from_hell", {
params = "[<player_name>]",
description = "Extract from hell",
func = function(name, pname)
if not minetest.check_player_privs(name, {nether=true}) then
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
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)
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
minetest.register_on_respawnplayer(function(player)
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."..
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 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."..
"\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."..
"\n3. please rejoin")]]
end
end
end
local timer = 0 --doesn't work if the server lags
minetest.register_globalstep(function(dtime)
timer = timer + dtime;
if timer >= 2 then
--minetest.after(1, update_players)
update_players()
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)
local timer = 0 --doesn't work if the server lags
minetest.register_globalstep(function(dtime)
timer = timer + dtime;
if timer >= 2 then
--minetest.after(1, update_players)
update_players()
timer = 0
end
end, player)
end)
end)
local function remove_portal_essence(pos)
for z = -1,1 do
for y = -2,2 do
for x = -1,1 do
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
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
end
end, player)
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
})
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()
local function remove_portal_essence(pos)
for z = -1,1 do
for y = -2,2 do
for x = -1,1 do
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
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)
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