forked from Mineclonia/Mineclonia
optimize nether porticles
This commit is contained in:
parent
4cfb65003b
commit
22ec7a65d8
|
@ -29,6 +29,9 @@ if minetest.features.use_texture_alpha_string_modes then
|
||||||
PORTAL_ALPHA = nil
|
PORTAL_ALPHA = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local PORTICLE_DISTANCE = 15 --how far to send particle spawners for the portalnodes
|
||||||
|
local porticlespawners = {}
|
||||||
|
|
||||||
-- Table of objects (including players) which recently teleported by a
|
-- Table of objects (including players) which recently teleported by a
|
||||||
-- Nether portal. Those objects have a brief cooloff period before they
|
-- Nether portal. Those objects have a brief cooloff period before they
|
||||||
-- can teleport again. This prevents annoying back-and-forth teleportation.
|
-- can teleport again. This prevents annoying back-and-forth teleportation.
|
||||||
|
@ -59,6 +62,65 @@ local function nether_to_overworld(x)
|
||||||
return LIMIT - math.abs(((x * OVERWORLD_TO_NETHER_SCALE + LIMIT) % (LIMIT*4)) - (LIMIT*2))
|
return LIMIT - math.abs(((x * OVERWORLD_TO_NETHER_SCALE + LIMIT) % (LIMIT*4)) - (LIMIT*2))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function remove_particlespawner_at_position(playername,pos)
|
||||||
|
if not porticlespawners[minetest.pos_to_string(pos)] or porticlespawners[minetest.pos_to_string(pos)][playername] == nil then return end
|
||||||
|
minetest.delete_particlespawner(porticlespawners[minetest.pos_to_string(pos)][playername],playername)
|
||||||
|
porticlespawners[minetest.pos_to_string(pos)][playername]=nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local function add_particlespawner_at_position(player,pos,node)
|
||||||
|
if not porticlespawners[minetest.pos_to_string(pos)] then porticlespawners[minetest.pos_to_string(pos)] = {} end
|
||||||
|
if porticlespawners[minetest.pos_to_string(pos)][player:get_player_name()] ~= nil then return end
|
||||||
|
porticlespawners[minetest.pos_to_string(pos)][player:get_player_name()]=minetest.add_particlespawner({
|
||||||
|
amount = node_particles_allowed_level + 1,
|
||||||
|
minpos = vector.add(pos, vector.new(-3,-3,-3)),
|
||||||
|
maxpos = vector.add(pos, vector.new(3,3,3)),
|
||||||
|
minvel = vector.new(-0.5,-0.5,-0.5),
|
||||||
|
maxvel = vector.new(0.5,0.5,0.5),
|
||||||
|
minacc = vector.new(-0.5,-0.5,-0.5),
|
||||||
|
maxacc = vector.new(0.5,0.5,0.5),
|
||||||
|
minexptime = 0.1,
|
||||||
|
maxexptime = 2.4,
|
||||||
|
minsize = 0.3,
|
||||||
|
maxsize = 1.8,
|
||||||
|
time=0,
|
||||||
|
collisiondetection = false,
|
||||||
|
texture = "mcl_particles_nether_portal.png",
|
||||||
|
playername = player:get_player_name(),
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
local function add_porticlespawners(pos,node)
|
||||||
|
--Add particlespawners for all players in range
|
||||||
|
for _,obj in pairs(minetest.get_connected_players()) do
|
||||||
|
if vector.distance(obj:get_pos(),pos) <= PORTICLE_DISTANCE then
|
||||||
|
add_particlespawner_at_position(obj,pos,node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remove_porticlespawners(pos,force)
|
||||||
|
--Remove particlespawners for all players out of range
|
||||||
|
-- force removes all particlespawners for the given position regardless of range
|
||||||
|
if porticlespawners[minetest.pos_to_string(pos)] then
|
||||||
|
for k,v in pairs(porticlespawners[minetest.pos_to_string(pos)]) do
|
||||||
|
local p=minetest.get_player_by_name(k)
|
||||||
|
local dst=PORTICLE_DISTANCE+1 --if player is logged off remove the particlespawner
|
||||||
|
if p and p:is_player() then
|
||||||
|
dst=vector.distance(p:get_pos(),pos)
|
||||||
|
end
|
||||||
|
if dst > PORTICLE_DISTANCE or force then
|
||||||
|
remove_particlespawner_at_position(k,pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function check_porticlespawners(pos,node)
|
||||||
|
add_porticlespawners(pos,node)
|
||||||
|
remove_porticlespawners(pos)
|
||||||
|
end
|
||||||
|
|
||||||
-- Destroy portal if pos (portal frame or portal node) got destroyed
|
-- Destroy portal if pos (portal frame or portal node) got destroyed
|
||||||
local function destroy_nether_portal(pos)
|
local function destroy_nether_portal(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
|
@ -77,6 +139,7 @@ local function destroy_nether_portal(pos)
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
if node and (node.name == "mcl_portals:portal" and (orientation == nil or (node.param2 == orientation))) then
|
if node and (node.name == "mcl_portals:portal" and (orientation == nil or (node.param2 == orientation))) then
|
||||||
minetest.log("action", "[mcl_portal] Destroying Nether portal at " .. minetest.pos_to_string(pos))
|
minetest.log("action", "[mcl_portal] Destroying Nether portal at " .. minetest.pos_to_string(pos))
|
||||||
|
remove_porticlespawners(pos,true)
|
||||||
return minetest.remove_node(pos)
|
return minetest.remove_node(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -769,56 +832,16 @@ local function teleport(obj, portal_pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
label = "Nether portal teleportation and particles",
|
label = "Nether portal teleportation and particles",
|
||||||
nodenames = {"mcl_portals:portal"},
|
nodenames = {"mcl_portals:portal"},
|
||||||
interval = 1,
|
interval = 1,
|
||||||
chance = 1,
|
chance = 1,
|
||||||
action = function(pos, node)
|
action = function(pos, node)
|
||||||
local o = node.param2 -- orientation
|
|
||||||
local d = math.random(0, 1) -- direction
|
check_porticlespawners(pos)
|
||||||
local time = math.random() * 1.9 + 0.5
|
|
||||||
local velocity, acceleration
|
|
||||||
if o == 1 then
|
|
||||||
velocity = {x = math.random() * 0.7 + 0.3, y = math.random() - 0.5, z = math.random() - 0.5}
|
|
||||||
acceleration = {x = math.random() * 1.1 + 0.3, y = math.random() - 0.5, z = math.random() - 0.5}
|
|
||||||
else
|
|
||||||
velocity = {x = math.random() - 0.5, y = math.random() - 0.5, z = math.random() * 0.7 + 0.3}
|
|
||||||
acceleration = {x = math.random() - 0.5, y = math.random() - 0.5, z = math.random() * 1.1 + 0.3}
|
|
||||||
end
|
|
||||||
local distance = vector.add(vector.multiply(velocity, time), vector.multiply(acceleration, time * time / 2))
|
|
||||||
if d == 1 then
|
|
||||||
if o == 1 then
|
|
||||||
distance.x = -distance.x
|
|
||||||
velocity.x = -velocity.x
|
|
||||||
acceleration.x = -acceleration.x
|
|
||||||
else
|
|
||||||
distance.z = -distance.z
|
|
||||||
velocity.z = -velocity.z
|
|
||||||
acceleration.z = -acceleration.z
|
|
||||||
end
|
|
||||||
end
|
|
||||||
distance = vector.subtract(pos, distance)
|
|
||||||
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 15)) do
|
|
||||||
if obj:is_player() then
|
|
||||||
minetest.add_particlespawner({
|
|
||||||
amount = node_particles_allowed_level + 1,
|
|
||||||
minpos = distance,
|
|
||||||
maxpos = distance,
|
|
||||||
minvel = velocity,
|
|
||||||
maxvel = velocity,
|
|
||||||
minacc = acceleration,
|
|
||||||
maxacc = acceleration,
|
|
||||||
minexptime = time,
|
|
||||||
maxexptime = time,
|
|
||||||
minsize = 0.3,
|
|
||||||
maxsize = 1.8,
|
|
||||||
collisiondetection = false,
|
|
||||||
texture = "mcl_particles_nether_portal.png",
|
|
||||||
playername = obj:get_player_name(),
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do --maikerumine added for objects to travel
|
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do --maikerumine added for objects to travel
|
||||||
local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel
|
local lua_entity = obj:get_luaentity() --maikerumine added for objects to travel
|
||||||
if (obj:is_player() or lua_entity) and prevent_portal_chatter(obj) then
|
if (obj:is_player() or lua_entity) and prevent_portal_chatter(obj) then
|
||||||
|
|
Loading…
Reference in New Issue