simpleworldborder/init.lua

109 lines
2.8 KiB
Lua

-- Defines the border of a world
local world_border = tonumber(minetest.settings:get("world_border")) or 500
-- Stop sign entities
local north = nil
local south = nil
local west = nil
local east = nil
-- add_remove_border (stop sign)
-- Adds entity if within 10 blocks of the player position
function add_remove_border(entity, player_pos, entity_pos, is_rotated)
if vector.distance(player_pos, entity_pos) < 10 then
if not entity then
entity = minetest.add_entity(entity_pos, "simpleworldborder:border", nil)
if is_rotated then entity:set_rotation({x = 0, y = math.pi/2, z = 0 }) end
else
-- within range but entity already exists
end
else
-- out of range
if entity then
-- remove entity
entity:remove()
return nil
end
end
return entity
end
-- worldborder:border item
-- represents "stop sign" for border
minetest.register_entity("simpleworldborder:border", {
initial_properties = {
collide_with_objects = false,
is_visible = true,
visual = "upright_sprite",
textures = {
"simpleworldborder_stopsign.png",
"simpleworldborder_stopsign.png"
},
visual_size = {
x = 10,
y = 10
},
backface_culling = false,
glow = -1,
shaded = false,
static_save = false,
use_texture_alpha = true
}
})
minetest.register_globalstep(function(dtime)
local players = minetest.get_connected_players()
for i, player in ipairs(players) do
local has_player_moved = false
local name = player:get_player_name()
local pos = vector.round(player:getpos())
-- Check if player is close world border. If so, spawn worldborder entity!
local northpos = vector.new(pos.x, pos.y, world_border)
local southpos = vector.new(pos.x, pos.y, -world_border)
local eastpos = vector.new(world_border, pos.y, pos.z)
local westpos = vector.new(-world_border, pos.y, pos.z)
north = add_remove_border(north, pos, northpos, false)
south = add_remove_border(south, pos, southpos, false)
east = add_remove_border(east, pos, eastpos, true)
west = add_remove_border(west, pos, westpos, true)
-- calculate new position of player
if pos.x > world_border then
pos.x = world_border
has_player_moved = true
elseif pos.x < -world_border then
pos.x = -world_border
has_player_moved = true
end
if pos.z > world_border then
pos.z = world_border
has_player_moved = true
elseif pos.z < -world_border then
pos.z = -world_border
has_player_moved = true
end
-- move player if needed
if pos and has_player_moved then
player:setpos(pos)
end
-- move stop sign entities
if east then
east:moveto({x = world_border + 1, y = pos.y, z = pos.z})
end
if west then
west:moveto({x = -world_border - 1, y = pos.y, z = pos.z})
end
if north then
north:moveto({x = pos.x, y = pos.y, z = world_border + 1})
end
if south then
south:moveto({x = pos.x, y = pos.y, z = -world_border - 1})
end
end
end)