1
0
mirror of https://github.com/HybridDog/nether-pack.git synced 2024-12-26 02:30:24 +01:00

Override player:set_pos etc. to disallow teleports from/to nether

constantly testing the player position is not longer necessary.
This commit is contained in:
HybridDog 2018-08-15 19:52:39 +02:00
parent 4a7dd247e7
commit df2d49edb0

View File

@ -79,49 +79,48 @@ local function get_player_died_target(player)
end end
-- used for obsidian portal -- used for obsidian portal
local function obsidian_teleport(player, pname) local function obsidian_teleport(player, pname, target)
minetest.chat_send_player(pname, "For any reason you arrived here. Type " .. minetest.chat_send_player(pname, "For any reason you arrived here. Type " ..
"/nether_help to find out things like craft recipes.") "/nether_help to find out things like craft recipes.")
if obsidian_portal_kills then players_in_nether[pname] = true
save_nether_players()
update_background(player, true)
if target then
player:set_pos(target)
else
player:set_hp(0) player:set_hp(0)
return true
end end
if not mclike_portal then
local target = vector.round(get_player_died_target(player))
if generated_or_generate(target) then
player:moveto(target)
return true
end
end
return false
end end
-- teleports players to nether or helps it -- teleports players to nether or helps it
local function player_to_nether(player, safe) local function player_to_nether(player, pos)
local pname = player:get_player_name() local pname = player:get_player_name()
if players_in_nether[pname] then if players_in_nether[pname] then
return return
end end
players_in_nether[pname] = true players_in_nether[pname] = true
save_nether_players() save_nether_players()
if not safe then update_background(player, true)
if pos then
player:set_pos(pos)
return
end
minetest.chat_send_player(pname, "For any reason you arrived here. " .. minetest.chat_send_player(pname, "For any reason you arrived here. " ..
"Type /nether_help to find out things like craft recipes.") "Type /nether_help to find out things like craft recipes.")
player:set_hp(0) player:set_hp(0)
if not nether_prisons then if not nether_prisons then
player:moveto(get_player_died_target(player)) player:set_pos(get_player_died_target(player))
end end
end end
update_background(player, true)
end
local function player_from_nether(player) local function player_from_nether(player, pos)
local pname = player:get_player_name() local pname = player:get_player_name()
if players_in_nether[pname] then if players_in_nether[pname] then
players_in_nether[pname] = nil players_in_nether[pname] = nil
save_nether_players() save_nether_players()
end end
update_background(player) update_background(player)
player:set_pos(pos)
end end
@ -173,9 +172,8 @@ minetest.register_chatcommand("from_hell", {
return false, "Something went wrong." return false, "Something went wrong."
end end
minetest.chat_send_player(pname, "You are free now") minetest.chat_send_player(pname, "You are free now")
player_from_nether(player)
local pos = player:getpos() local pos = player:getpos()
player:moveto({x=pos.x, y=100, z=pos.z}) player_from_nether(player, {x=pos.x, y=100, z=pos.z})
return true, pname.." is now out of the nether." return true, pname.." is now out of the nether."
end end
}) })
@ -189,7 +187,7 @@ if nether_prisons then
return return
end end
local target = get_player_died_target(player) local target = get_player_died_target(player)
player:moveto(target) player:set_pos(target)
minetest.after(0, function(pname, target) minetest.after(0, function(pname, target)
-- fixes respawn bug -- fixes respawn bug
local player = minetest.get_player_by_name(pname) local player = minetest.get_player_by_name(pname)
@ -200,63 +198,76 @@ if nether_prisons then
return true return true
end) end)
-- function for teleporting players where they belong to -- override set_pos etc. to disallow player teleportion by e.g. travelnet
local function update_players() local function can_teleport(player, pos)
for _,player in pairs(minetest.get_connected_players()) do
local pname = player:get_player_name() local pname = player:get_player_name()
local ppos = player:getpos() local in_nether = players_in_nether[pname] == true
if players_in_nether[pname] then
if ppos.y > nether.start then -- test if the target is valid
player:moveto({x=ppos.x, y=portal_target, z=ppos.z}) if pos.y < nether.start then
update_background(player, true) if in_nether then
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport out of the nether.".. return true
"\n2. Maybe the server lagged."..
"\n3. please rejoin")]]
end end
elseif ppos.y < nether.start then elseif not in_nether then
return true
end
-- test if the current position is valid
local current_pos = player:get_pos()
local now_in_nether = current_pos.y < nether.start
if now_in_nether ~= in_nether then
if in_nether then
minetest.log("action", "Player \"" .. pname ..
"\" has to be in the nether, teleporting it!")
update_background(player, true)
current_pos.y = portal_target
player:set_pos(current_pos)
else
minetest.log("action", "Player \"" .. pname ..
"\" must not be in the nether, teleporting it!")
update_background(player) update_background(player)
player:moveto({x=ppos.x, y=20, z=ppos.z}) current_pos.y = 20
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport to the nether.".. player:set_pos(current_pos)
"\n2. Maybe the server lagged."..
"\n3. please rejoin")]]
end
end end
return false
end end
-- the function delayer mod works similar to a scheduler minetest.chat_send_player(pname,
local delay_function = minetest.delay_function or minetest.after "You can not simply teleport to or from the nether!")
local function tick() minetest.log("action", "Player \"" .. pname ..
update_players() "\" attempted to teleport from or to the nether, ignoring.")
minetest.after(0.5, function() delay_function(1.5, tick) end) return false
end end
tick() local methods = {"set_pos", "move_to", "setpos", "moveto"}
local metatable_overridden
-- set background when player joins
minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
minetest.after(0, function(player) -- set the background when the player joins
if player if player:getpos().y < nether.start then
and player:getpos().y < nether.start then
update_background(player, true) update_background(player, true)
end end
end, player)
-- overide set_pos etc. if not yet done
if metatable_overridden then
return
end
metatable_overridden = true
local mt = getmetatable(player)
for i = 1,#methods do
local methodname = methods[i]
local origfunc = mt[methodname]
mt[methodname] = function(...)
if can_teleport(...) then
origfunc(...)
end
end
end
end) end)
else else
-- test if player is in nether when he/she joins -- test if player is in nether when he/she joins
--~ minetest.register_on_joinplayer(function(player) minetest.register_on_joinplayer(function(player)
--~ print(dump(player:get_pos())) players_in_nether[player:get_player_name()] =
--~ minetest.after(0, function(player) player:getpos().y < nether.start or nil
--~ local pname = player:get_player_name() end)
--~ if player:getpos().y < nether.start then
--~ if not players_in_nether[pname] then
--~ players_in_nether[pname] = true
--~ end
--~ return
--~ end
--~ if players_in_nether[pname] then
--~ players_in_nether[pname] = nil
--~ end
--~ end, player)
--~ end)
end end
-- removes the violet stuff from the obsidian portal -- removes the violet stuff from the obsidian portal
@ -301,19 +312,26 @@ local function obsi_teleport_player(player, pos, target)
return return
end end
if not obsidian_teleport(player, pname) then local has_teleported
if obsidian_portal_kills then
obsidian_teleport(player, pname)
has_teleported = true
elseif not mclike_portal then
local target = vector.round(get_player_died_target(player))
if generated_or_generate(target) then
obsidian_teleport(player, pname, target)
has_teleported = true
end
end
if not has_teleported then
-- e.g. ungenerated area -- e.g. ungenerated area
return return
end end
players_in_nether[pname] = true
save_nether_players()
update_background(player, true)
remove_portal_essence(pos) remove_portal_essence(pos)
minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1}) minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1})
--obj:setpos(target)
end end
-- abm for particles of the obsidian portal essence and for teleporting -- abm for particles of the obsidian portal essence and for teleporting
@ -541,7 +559,6 @@ minetest.after(0.1, function()
on_place = function(stack, player, pt) on_place = function(stack, player, pt)
if pt.under if pt.under
and minetest.get_node(pt.under).name == "default:obsidian" then and minetest.get_node(pt.under).name == "default:obsidian" then
--print("[nether] tries to enable a portal")
local done = make_portal(pt.under) local done = make_portal(pt.under)
if done then if done then
minetest.chat_send_player(player:get_player_name(), minetest.chat_send_player(player:get_player_name(),
@ -573,8 +590,7 @@ function(r)
return tab return tab
end end
-- detects if it's a portal local function is_netherportal(pos)
local function netherport(pos)
local x, y, z = pos.x, pos.y, pos.z local x, y, z = pos.x, pos.y, pos.z
for _,i in pairs({-1, 3}) do for _,i in pairs({-1, 3}) do
if minetest.get_node({x=x, y=y+i, z=z}).name ~= "nether:white" then if minetest.get_node({x=x, y=y+i, z=z}).name ~= "nether:white" then
@ -638,14 +654,13 @@ function nether_port(player, pos)
minetest.log("error", "[nether] nether_port: something failed.") minetest.log("error", "[nether] nether_port: something failed.")
return return
end end
if not netherport(pos) then if not is_netherportal(pos) then
return return
end end
minetest.sound_play("nether_teleporter", {pos=pos}) minetest.sound_play("nether_teleporter", {pos=pos})
local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z}) local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z})
if pos.y < nether.start then if pos.y < nether.start then
set_portal(known_portals_d, pos.z,pos.x, pos.y) set_portal(known_portals_d, pos.z,pos.x, pos.y)
player_from_nether(player)
local my = tonumber(meta:get_string("y")) local my = tonumber(meta:get_string("y"))
local y = get_portal(known_portals_u, pos.z,pos.x) local y = get_portal(known_portals_u, pos.z,pos.x)
@ -656,9 +671,9 @@ function nether_port(player, pos)
else else
y = my or 100 y = my or 100
end end
pos.y = y pos.y = y - 0.3
player:moveto(pos) player_from_nether(player, pos)
else else
set_portal(known_portals_u, pos.z,pos.x, pos.y) set_portal(known_portals_u, pos.z,pos.x, pos.y)
@ -671,10 +686,9 @@ function nether_port(player, pos)
else else
y = my or portal_target+math.random(4) y = my or portal_target+math.random(4)
end end
pos.y = y pos.y = y - 0.3
player:moveto(pos) player_to_nether(player, pos)
player_to_nether(player, true)
end end
minetest.sound_play("nether_teleporter", {pos=pos}) minetest.sound_play("nether_teleporter", {pos=pos})
return true return true