[nether] Update

master
LeMagnesium 2016-01-10 19:29:06 +01:00
parent abc6833517
commit bb0387c7cd
18 changed files with 503 additions and 294 deletions

View File

@ -18,4 +18,5 @@ 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
— find a way to get the perlin noise inside [-1; 1] or use another noise
— add something containing items to that buildings

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

Before

Width:  |  Height:  |  Size: 319 B

After

Width:  |  Height:  |  Size: 319 B

View File

Before

Width:  |  Height:  |  Size: 452 B

After

Width:  |  Height:  |  Size: 452 B

View File

Before

Width:  |  Height:  |  Size: 572 B

After

Width:  |  Height:  |  Size: 572 B

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 762 B

After

Width:  |  Height:  |  Size: 762 B

View File

Before

Width:  |  Height:  |  Size: 574 B

After

Width:  |  Height:  |  Size: 574 B

View File

Before

Width:  |  Height:  |  Size: 612 B

After

Width:  |  Height:  |  Size: 612 B

View File

@ -2,5 +2,6 @@ default
glow
riesenpilz
stairs
vector_extras
fence_registration?
watershed?

View File

@ -55,6 +55,9 @@ local mushroom_rarity = 80
-- Frequency of trees in the nether forest (higher is less frequent)
local tree_rarity = 200
local abm_tree_interval = 864
local abm_tree_chance = 100
-- height of the nether generation's end
nether.start = f_h_max+100
@ -690,6 +693,10 @@ function nether.grow_netherstructure(pos, generated)
end
local set = vector.set_data_to_pos
local get = vector.get_data_from_pos
local remove = vector.remove_data_from_pos
local function soft_node(id)
return id == c.air or id == c.ignore
end
@ -699,7 +706,6 @@ local function update_minmax(min, max, p)
max.x = math.max(max.x, p.x)
min.z = math.min(min.z, p.z)
max.z = math.max(max.z, p.z)
return min, max
end
local fruit_chances = {}
@ -742,62 +748,69 @@ function nether.grow_tree(pos, generated)
local trunks = {}
local trunk_corners = {}
local h_stem = math.random(h_stem_min, h_stem_max)
local stems = {{x=pos.x, y=pos.y+h_stem, z=pos.z}}
local fi
while not fi do
for n,p in pairs(stems) do
local used_dirs = {}
for _,dir in pairs(dirs) do
if math.random(1,2) == 1 then
table.insert(used_dirs, dir)
end
local todo,n = {{x=pos.x, y=pos.y+h_stem, z=pos.z}},1
while n do
local p = todo[n]
todo[n] = nil
n = next(todo)
local used_dirs,u = {},1
for _,dir in pairs(dirs) do
if math.random(1,2) == 1 then
used_dirs[u] = dir
u = u+1
end
if not used_dirs[1] then
local dir1 = math.random(4)
local dir2 = math.random(3)
if dir1 <= dir2 then
dir2 = dir2+1
end
used_dirs[1] = dirs[dir1]
used_dirs[2] = dirs[dir2]
end
for _,dir in pairs(used_dirs) do
local p = vector.new(p)
local r = math.random(r_arm_min, r_arm_max)
for j = 1,r do
local x = p.x+j*dir[1]
local z = p.z+j*dir[2]
trunks[x.." "..p.y.." "..z] = dir[3]
end
r = r+1
p.x = p.x+r*dir[1]
p.z = p.z+r*dir[2]
trunk_corners[p.x.." "..p.y.." "..p.z] = dir[4] or dir[3]
local h = math.random(h_arm_min, h_arm_max)
for i = 1,h do
trunks[p.x.." "..p.y+i.." "..p.z] = true
end
p.y = p.y+h
table.insert(stems, p)
end
if p.y > pos.y+h_trunk_max then
fi = true
break
end
stems[n] = nil
end
if not used_dirs[1] then
local dir1 = math.random(4)
local dir2 = math.random(3)
if dir1 <= dir2 then
dir2 = dir2+1
end
used_dirs[1] = dirs[dir1]
used_dirs[2] = dirs[dir2]
end
for _,dir in pairs(used_dirs) do
local p = vector.new(p)
local r = math.random(r_arm_min, r_arm_max)
for j = 1,r do
local x = p.x+j*dir[1]
local z = p.z+j*dir[2]
set(trunks, z,p.y,x, dir[3])
end
r = r+1
p.x = p.x+r*dir[1]
p.z = p.z+r*dir[2]
set(trunk_corners, p.z,p.y,p.x, dir[4] or dir[3])
local h = math.random(h_arm_min, h_arm_max)
for i = 1,h do
set(trunks, p.z,p.y+i,p.x, true)
end
p.y = p.y+h
--n = #todo+1 -- caused small trees
todo[#todo+1] = p
end
if p.y > pos.y+h_trunk_max then
break
end
n = n or next(todo)
end
local leaves = {}
local fruits = {}
local trunk_ps = {}
local count = 0
for n,par in pairs(trunks) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
if par ~= true then
p.par = par
local ps, trmin, trmax, trunk_count = vector.get_data_pos_table(trunks)
update_minmax(min, max, trmin)
update_minmax(min, max, trmax)
for _,d in pairs(ps) do
if d[4] == true then
d[4] = nil
end
table.insert(trunk_ps, p)
trunk_ps[#trunk_ps+1] = d
local pz, py, px = unpack(d)
count = count+1
if count > leaf_thickness then
count = 0
@ -805,18 +818,21 @@ function nether.grow_tree(pos, generated)
local fruit_chance = fruit_chances[y]
for z = -2,2 do
for x = -2,2 do
local dist = math.sqrt(x*x+y*y+z*z)
if math.floor(dist) ~= 0
and math.random(1, dist) == 1 then
local pstr = p.x+x.." "..p.y+y.." "..p.z+z
if not trunks[pstr] then
if math.random(1, fruit_rarity) == 1
and fruit_chance
local distq = x*x+y*y+z*z
if distq ~= 0
and math.random(1, math.sqrt(distq)) == 1 then
local x = x+px
local y = y+py
local z = z+pz
if not get(trunks, z,y,x) then
if fruit_chance
and math.random(1, fruit_rarity) == 1
and math.random(1, fruit_chance) == 1 then
fruits[pstr] = true
set(fruits, z,y,x, true)
else
leaves[pstr] = true
set(leaves, z,y,x, true)
end
update_minmax(min, max, {x=x, z=z})
end
end
end
@ -825,37 +841,8 @@ function nether.grow_tree(pos, generated)
end
end
local leaf_ps = {}
for n,_ in pairs(leaves) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
table.insert(leaf_ps, p)
min, max = update_minmax(min, max, p)
end
for n,_ in pairs(trunks) do
local p = {}
p.x, _, p.z = unpack(string.split(n, " "))
min, max = update_minmax(min, max, p)
end
for i = -1,h_stem+1 do
table.insert(trunk_ps, {x=pos.x, y=pos.y+i, z=pos.z, par=0})
end
local trunk_corner_ps = {}
for n,par in pairs(trunk_corners) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
p.par = par
table.insert(trunk_corner_ps, p)
end
local fruit_ps = {}
for n,_ in pairs(fruits) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
table.insert(fruit_ps, p)
trunk_ps[#trunk_ps+1] = {pos.z, pos.y+i, pos.x, 0} -- par 0 because of leaves
end
local manip = minetest.get_voxel_manip()
@ -864,8 +851,8 @@ function nether.grow_tree(pos, generated)
local nodes = manip:get_data()
local param2s = manip:get_param2_data()
for _,p in pairs(leaf_ps) do
p = area:indexp(p)
for _,p in pairs(vector.get_data_pos_table(leaves)) do
p = area:index(p[3], p[2], p[1])
if soft_node(nodes[p]) then
nodes[p] = c.nether_leaves
param2s[p] = math.random(0,179)
@ -873,30 +860,28 @@ function nether.grow_tree(pos, generated)
end
end
for _,p in pairs(fruit_ps) do
p = area:indexp(p)
for _,p in pairs(vector.get_data_pos_table(fruits)) do
p = area:index(p[3], p[2], p[1])
if soft_node(nodes[p]) then
nodes[p] = c.nether_apple
end
end
for _,p in pairs(trunk_ps) do
local par = p.par
p = area:indexp(p)
local par = p[4]
p = area:index(p[3], p[2], p[1])
if par then
param2s[p] = par
end
nodes[p] = c.nether_tree
end
for _,p in pairs(trunk_corner_ps) do
local par = p.par
p = area:indexp(p)
nodes[p] = c.nether_tree_corner
param2s[p] = par
for _,p in pairs(vector.get_data_pos_table(trunk_corners)) do
local vi = area:index(p[3], p[2], p[1])
nodes[vi] = c.nether_tree_corner
param2s[vi] = p[4]
end
--calculating took ca. 0.07 - 0.18 [s]
manip:set_data(nodes)
manip:set_param2_data(param2s)
manip:write_to_map()
@ -904,7 +889,7 @@ function nether.grow_tree(pos, generated)
if generated then
spam = 3
end
nether:inform("a nether tree grew at ("..pos.x.."|"..pos.y.."|"..pos.z..")", spam, t1)
nether:inform("a nether tree with "..trunk_count.." branch trunk nodes grew at ("..pos.x.."|"..pos.y.."|"..pos.z..")", spam, t1)
if not generated then
local t1 = os.clock()
manip:update_map()
@ -933,8 +918,8 @@ minetest.register_abm({
minetest.register_abm({
nodenames = {"nether:tree_sapling"},
neighbors = {"group:nether_dirt"},
interval = 864,
chance = 100,
interval = abm_tree_interval,
chance = abm_tree_chance,
action = function(pos)
if minetest.get_node({x=pos.x, y=pos.y+2, z=pos.z}).name == "air"
and minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air" then

View File

@ -539,6 +539,7 @@ minetest.register_node("nether:leaves", {
inventory_image = "nether_leaves.png",
wield_image = "nether_leaves.png",
paramtype = "light",
paramtype2 = "degrotate",
is_ground_content = false,
groups = {snappy=3, leafdecay=3, leaves=1},
drop = {

View File

@ -7,108 +7,192 @@ 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()
return item
end
teleportball_player = player
return item
end
local ENTITY = {
timer=0,
local function get_node(pos)
local name = minetest.get_node(pos).name
if name ~= "ignore" then
return name
end
minetest.get_voxel_manip():read_from_map(pos, pos)
name = minetest.get_node_or_nil(pos)
if not name then
return
end
return name.name
end
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)
if not is_soft(pos) then
return false
end
if not is_soft({x=pos.x, y=pos.y+1, z=pos.z})
and not is_soft({x=pos.x, y=pos.y-1, z=pos.z}) then
return false
end
pos.y = pos.y+0.05
player:moveto(pos)
return true
end
--[[
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", {
collisionbox = {0,0,0,0,0,0}, --not pointable
visual_size = {x=0.1, y=0.1},
physical = false, -- Collides with things
textures = {"nether_pearl.png"},
lastpos={},
player = "",
}
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,
timer = 0,
on_step = function(self, dtime)
self.timer = self.timer+dtime
local allowed_nodes = {"air", "default:water_source"}
local function teleport_player(pos, player)
local nd2 = minetest.get_node(pos).name
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
pos.y = pos.y-1.4
player:moveto(pos)
pos.y = pos.y-0.6
return true
end
return false
end
--[[
local delay = self.delay
if delay < 0.1 then
self.delay = delay+dtime
return
end
self.delay = 0--]]
ENTITY.on_step = function(self, dtime)
self.timer=self.timer+dtime
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)
if not free then
local nd1 = minetest.get_node(p).name
if not table_contains(allowed_nodes, nd1)
and nd1 ~= "ignore" then
self.object:remove()
minetest.after(0, function(p) --minetest.after us 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
if teleport_player(p, player) then
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
if teleport_player(vector.new(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
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
end
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
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
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

@ -1,6 +1,10 @@
--code copied from Pilzadam's nether mod and edited
-- kills the player if he uses PilzAdam portal
local portal_target = nether.buildings+1
local damage_enabled = minetest.setting_getbool("enable_damage")
local nether_prisons = minetest.setting_getbool("enable_damage")
local obsidian_portal_kills = nether_prisons and true
local mclike_portal = false
local abm_allowed
minetest.after(5, function()
@ -17,12 +21,15 @@ table.icontains = table.icontains or function(t, v)
end
local players_in_nether = {}
local file = io.open(minetest.get_worldpath()..'/nether_players', "r")
if file then
local contents = file:read('*all')
io.close(file)
if contents then
players_in_nether = string.split(contents, " ")
-- only get info from file if nether prisons
if nether_prisons then
local file = io.open(minetest.get_worldpath()..'/nether_players', "r")
if file then
local contents = file:read('*all')
io.close(file)
if contents then
players_in_nether = string.split(contents, " ")
end
end
end
@ -37,7 +44,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")
@ -49,16 +56,59 @@ local update_background
-- function update_background()end
--end
-- returns nodename if area is generated, else calls generation function
local function generated_or_generate(pos)
local name = minetest.get_node(pos).name
if name ~= "ignore" then
return name
end
minetest.get_voxel_manip():read_from_map(pos, pos)
name = minetest.get_node_or_nil(pos)
if not name then
minetest.emerge_area(vector.subtract(pos, 80), vector.add(pos, 80))
return false
end
return name.name
end
-- where the player appears after dying
local function get_player_died_target(player)
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)
return target
end
-- used for obsidian portal
local function obsidian_teleport(player, pname)
minetest.chat_send_player(pname, "For any reason you arrived here. Type /nether_help to find out things like craft recipes.")
if obsidian_portal_kills then
player:set_hp(0)
return true
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
-- teleports players to nether or helps it
function nether.player_to_nether(player, safe)
local pname = player:get_player_name()
if table.icontains(players_in_nether, pname) then
return
end
table.insert(players_in_nether, pname)
players_in_nether[#players_in_nether+1] = pname
save_nether_players()
if not safe then
minetest.chat_send_player(pname, "For any reason you arrived here. Type /nether_help to find out things like craft recipes.")
player:set_hp(0)
if not nether_prisons then
player:moveto(get_player_died_target(player))
end
end
update_background(player, true)
end
@ -79,7 +129,6 @@ function nether.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
@ -128,69 +177,95 @@ minetest.register_chatcommand("from_hell", {
end
minetest.chat_send_player(pname, "You are free now")
player_from_nether(player)
local pos_togo = {x = 0, y = 35, z = -7}
if minetest.setting_getbool("static_spawnpoint") ~= nil then
local stsp_conf = minetest.setting_get("static_spawnpoint")
pos_togo = {x = stsp_conf:split(",")[1]+0,y = stsp_conf:split(",")[2]+0,z = stsp_conf:split(",")[3]+0}
end
player:moveto(pos_togo)
return true
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
if nether_prisons then
-- randomly set player position when he/she dies in nether
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 = get_player_died_target(player)
player:moveto(target)
minetest.after(0, function(pname, target)
-- fixes respawn bug
local player = minetest.get_player_by_name(pname)
if player then
player:moveto(target)
end
end, pname, target)
return true
end)
-- function for teleporting players where they belong to
local function update_players()
for _,player in pairs(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 function tick()
update_players()
minetest.after(2, tick)
end
tick()
minetest.register_on_joinplayer(function(player)
minetest.after(0, function(player)
if player:getpos().y < nether.start then
update_background(player, true)
-- fix wrong player positions
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)
-- set background when player joins
minetest.register_on_joinplayer(function(player)
minetest.after(0, function(player)
if player:getpos().y < nether.start then
update_background(player, true)
end
end, player)
end)
else
-- test if player is in nether when he/she joins
minetest.register_on_joinplayer(function(player)
minetest.after(0, function(player)
if player:getpos().y < nether.start then
if not table.icontains(players_in_nether, pname) then
players_in_nether[#players_in_nether+1] = pname
end
return
end
for i,name in pairs(players_in_nether) do
if name == pname then
players_in_nether[i] = nil
return
end
end
end, player)
end)
end
-- removes the violet stuff from the obsidian portal
local function remove_portal_essence(pos)
for z = -1,1 do
for y = -2,2 do
@ -204,6 +279,50 @@ local function remove_portal_essence(pos)
end
end
-- change parts of the particledefinition instead of recreating it every time
local particledef = {
amount = 32,
time = 4,
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,
}
-- teleports player to neter (obsidian portal)
local function obsi_teleport_player(player, pos, target)
local pname = player:get_player_name()
if table.icontains(players_in_nether, pname) then
return
end
local objpos = player: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
if not obsidian_teleport(player, pname) then
-- e.g. ungenerated area
return
end
players_in_nether[#players_in_nether+1] = pname
save_nether_players()
update_background(player, true)
remove_portal_essence(pos)
minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1})
--obj:setpos(target)
end
-- abm for particles of the obsidian portal essence and for teleporting
minetest.register_abm({
nodenames = {"nether:portal"},
interval = 1,
@ -213,45 +332,16 @@ minetest.register_abm({
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),
})
particledef.minpos = {x=pos.x-0.25, y=pos.y-0.5, z=pos.z-0.25}
particledef.maxpos = {x=pos.x+0.25, y=pos.y+0.34, z=pos.z+0.25}
particledef.texture = "nether_portal_particle.png^[transform"..math.random(0,7)
minetest.add_particlespawner(particledef)
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})
nether.player_to_nether(obj)
--obj:setpos(target)
end, obj, pos, target)
minetest.after(3, obsi_teleport_player, obj, pos, target)
end
end
end
@ -299,6 +389,7 @@ local function check_portal(p1, p2)
return true
end
-- tests if it's an obsidian portal
local function is_portal(pos)
for d=-3,3 do
for y=-4,4 do
@ -314,6 +405,15 @@ local function is_portal(pos)
end
end
-- put here the function for creating a second portal
local create_second_portal
if mclike_portal then
function create_second_portal(target)
-- change target here
end
end
-- adds the violet portal essence
local function make_portal(pos)
local p1, p2 = is_portal(pos)
if not p1
@ -322,7 +422,10 @@ local function make_portal(pos)
return false
end
if p1.y < nether.start then
local in_nether = p1.y < nether.start
if in_nether
and not mclike_portal then
print("[nether] aborted, obsidian portals can't be used to get out")
return
end
@ -350,7 +453,17 @@ local function make_portal(pos)
local target = {x=p1.x, y=p1.y, z=p1.z}
target.x = target.x + 1
target.y = portal_target + math.random(4)
if in_nether then
target.y = 0
create_second_portal(target)
else
target.y = portal_target + math.random(4)
end
if not generated_or_generate(target)
and mclike_portal then
return false
end
for d=0,3 do
for y=p1.y,p2.y do
@ -373,6 +486,7 @@ local function make_portal(pos)
return true
end
-- destroy the portal when destroying obsidian
minetest.override_item("default:obsidian", {
on_destruct = function(pos)
local meta = minetest.get_meta(pos)
@ -426,12 +540,13 @@ minetest.override_item("default:obsidian", {
end
})
-- override mese crystal fragment for making an obsidian portal
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")
--print("[nether] tries to enable a portal")
local done = make_portal(pt.under)
if done then
minetest.chat_send_player(
@ -447,9 +562,9 @@ minetest.after(0.1, function()
end
})
end)
--end
-- a not filled square
vector.square = vector.square or
function(r)
local tab, n = {}, 1
@ -464,20 +579,21 @@ function(r)
return tab
end
-- detects if it's a portal
local function netherport(pos)
local x, y, z = pos.x, pos.y, pos.z
for _,i in ipairs({-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
return
end
end
for _,sn in ipairs(vector.square(1)) do
for _,sn in pairs(vector.square(1)) do
if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "nether:netherrack"
or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "nether:blood_cooked" then
return
end
end
for _,sn in ipairs(vector.square(2)) do
for _,sn in pairs(vector.square(2)) do
if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "nether:netherrack_black"
or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "nether:wood_empty" then
return
@ -520,6 +636,7 @@ local function set_portal(t, z,x, y)
t[z][x] = y
end
-- used when a player eats that fruit in a portal
function nether_port(player, pos)
if not player
or not pos
@ -532,17 +649,37 @@ function nether_port(player, pos)
end
minetest.sound_play("nether_teleporter", {to_player=player:get_player_name()}) --MFF crabman (5/09/2015) fix positional sound don't work to player
minetest.sound_play("nether_teleporter", {pos=pos})
local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z})
if pos.y < nether.start then
nether.player_from_nether(player)
local pos_togo = {x = 0, y = 35, z = -7}
if minetest.setting_getbool("static_spawnpoint") ~= nil then
local stsp_conf = minetest.setting_get("static_spawnpoint")
pos_togo = minetest.string_to_pos(stsp_conf)
set_portal(known_portals_d, pos.z,pos.x, pos.y)
player_from_nether(player)
local my = tonumber(meta:get_string("y"))
local y = get_portal(known_portals_u, pos.z,pos.x)
if y then
if y ~= my then
meta:set_string("y", y)
end
else
y = my or 100
end
player:moveto(pos_togo)
pos.y = y
player:moveto(pos)
else
set_portal(known_portals_u, pos.z,pos.x, pos.y)
pos.y = get_portal(known_portals_d, pos.z,pos.x) or portal_target+math.random(4)
local my = tonumber(meta:get_string("y"))
local y = get_portal(known_portals_d, pos.z,pos.x)
if y then
if y ~= my then
meta:set_string("y", y)
end
else
y = my or portal_target+math.random(4)
end
pos.y = y
player:moveto(pos)
nether.player_to_nether(player, true)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B