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

@ -19,3 +19,4 @@ If you got ideas or found bugs, please tell them to me.
TODO:
— find a way to get the perlin noise inside [-1; 1] or use another noise
— add something containing items to that buildings

View File

@ -7,36 +7,60 @@ local function table_contains(t, v)
return false
end
local teleportball_player
local creative = minetest.setting_getbool("creative_mode")
local function throw_pearl(item, player)
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()
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})
if not minetest.setting_getbool("creative_mode") then
obj:get_luaentity().player = player:get_player_name()
if not creative then
item:take_item()
end
teleportball_player = player
return item
end
end
local ENTITY = {
timer=0,
collisionbox = {0,0,0,0,0,0}, --not pointable
physical = false, -- Collides with things
textures = {"nether_pearl.png"},
lastpos={},
player = "",
}
local function get_node(pos)
local name = minetest.get_node(pos).name
if name == "ignore" then
minetest.get_voxel_manip():read_from_map(pos, pos)
name = minetest.get_node_or_nil(pos)
if not name then
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 nd2 = minetest.get_node(pos).name
local nd2 = is_soft(pos)
pos.y = pos.y+1
local nd3 = minetest.get_node(pos).name
if table_contains(allowed_nodes, nd2)
and table_contains(allowed_nodes, nd3) then
local nd3 = is_soft(pos)
if nd2
and nd3 then
pos.y = pos.y-1.4
player:moveto(pos)
pos.y = pos.y-0.6
@ -45,39 +69,108 @@ local function teleport_player(pos, player)
return false
end
ENTITY.on_step = function(self, 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
--[[
local delay = self.delay
if delay < 0.1 then
self.delay = delay+dtime
return
end
self.delay = 0]]
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), vector.round(pos)) then
and vector.equals(vector.round(lastpos), rpos) 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
minetest.log("error", "[nether] pearl: missing playername")
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)
if not free then
local nd1 = minetest.get_node(p).name
if not table_contains(allowed_nodes, nd1)
and nd1 ~= "ignore" then
player = minetest.get_player_by_name(player)
if not player then
minetest.log("error", "[nether] pearl: missing player")
self.object:remove()
minetest.after(0, function(p) --minetest.after us used that the sound is played after the teleportation
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 free, p = minetest.line_of_sight(lastpos, pos)
if free then
return
end
if is_soft(p) then
return
end
self.object:remove()
minetest.after(0, function(p) --minetest.after is used that the sound is played after the teleportation
minetest.sound_play("nether_pearl", {pos=p, max_hear_distance=10})
end, p)
p.y = p.y+1
@ -100,15 +193,6 @@ ENTITY.on_step = function(self, dtime)
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})

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,7 +84,7 @@ local function player_from_nether(player)
end
if damage_enabled then
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