Major refactor, pulling api functions out into a separate file to protect the internal data. Not backwards compatible.
This commit is contained in:
parent
ae4dc73fd8
commit
fc64db04c8
389
api.lua
Normal file
389
api.lua
Normal file
@ -0,0 +1,389 @@
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
-- pocket data tables have the following properties:
|
||||
-- pending = true -- pocket is being initialized, don't teleport there just yet
|
||||
-- destination = a vector relative to the pocket's minp that is where new arrivals teleport tonumber
|
||||
-- name = a name for the pocket.
|
||||
-- owner = if set, this pocket is "owned" by this particular player.
|
||||
-- protected = if true, this pocket is protected and only the owner can modify its contents
|
||||
-- minp = the lower corner of the pocket's region
|
||||
|
||||
local pockets_by_name = {}
|
||||
local player_origin = {}
|
||||
local pockets_deleted = {} -- record deleted pockets for possible later undeletion, indexed by hash
|
||||
local personal_pockets = {} -- to be filled out if personal pockets are enabled
|
||||
local protected_areas = AreaStore()
|
||||
|
||||
--The world is a cube of side length 61840. Coordinates go from -30912 to 30927 in any direction.
|
||||
--The side length is a multiple of 80
|
||||
--773 * 80 = 61840
|
||||
-- so there are 773 * 773 = 597529 chunk in a horizontal layer. Should be plenty for distributing these things in.
|
||||
local mapgen_chunksize = tonumber(minetest.get_mapgen_setting("chunksize"))
|
||||
local mapblock_size = mapgen_chunksize * 16 -- should be 80 in almost all cases, but avoiding hardcoding it for extensibility
|
||||
local block_grid_dimension = math.floor(61840 / mapblock_size) -- should be 773
|
||||
local min_coordinate = -30912
|
||||
|
||||
local layer_elevation = tonumber(minetest.settings:get("pocket_dimensions_altitude")) or 30000
|
||||
layer_elevation = math.floor(layer_elevation / mapblock_size) * mapblock_size - 32 -- round to mapblock boundary
|
||||
|
||||
pocket_dimensions.pocket_size = mapblock_size
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- Loading and saving data
|
||||
local filename = minetest.get_worldpath() .. "/pocket_dimensions_data.lua"
|
||||
|
||||
local load_data = function()
|
||||
local f, e = loadfile(filename)
|
||||
if f then
|
||||
local data = f()
|
||||
pockets_by_name = data.pockets_by_name
|
||||
player_origin = data.player_origin
|
||||
pockets_deleted = data.pockets_deleted
|
||||
if personal_pockets_enabled then
|
||||
for name, pocket_data in pairs(pockets_by_name) do
|
||||
if pocket_data.personal and pocket_data.owner then
|
||||
if personal_pockets[pocket_data.owner] then
|
||||
minetest.log("error", "[pocket_dimensions] "
|
||||
.. pocket_data.owner .. " owns multiple personal pockets, "
|
||||
.. personal_pockets[pocket_data.owner].name .. " and " .. pocket_data.name
|
||||
.. ".")
|
||||
end
|
||||
personal_pockets[pocket_data.owner] = pocket_data
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
-- add saved protected areas
|
||||
for name, pocket_data in pairs(pockets_by_name) do
|
||||
if pocket_data.protected then
|
||||
protected_areas:insert_area(pocket_data.minp, vector.add(pocket_data.minp, mapblock_size), pocket_data.owner)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local save_data = function()
|
||||
local data = {}
|
||||
data.pockets_by_name = pockets_by_name
|
||||
data.player_origin = player_origin
|
||||
data.pockets_deleted = pockets_deleted
|
||||
local file, e = io.open(filename, "w");
|
||||
if not file then
|
||||
return error(e);
|
||||
end
|
||||
file:write(minetest.serialize(data))
|
||||
file:close()
|
||||
end
|
||||
|
||||
load_data()
|
||||
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- protection
|
||||
|
||||
local old_is_protected = minetest.is_protected
|
||||
function minetest.is_protected(pos, name)
|
||||
if minetest.check_player_privs(name, "protection_bypass") then
|
||||
return false
|
||||
end
|
||||
local protection = protected_areas:get_areas_for_pos(pos, false, true)
|
||||
for _, area in pairs(protection) do
|
||||
if area.data ~= name then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return old_is_protected(pos, name)
|
||||
end
|
||||
|
||||
pocket_dimensions.set_protection = function(pocket_data, protection)
|
||||
pocket_data.protected = protection
|
||||
-- clear any existing protection
|
||||
protected = protected_areas:get_areas_for_pos(pocket_data.minp)
|
||||
for id, _ in pairs(protected) do -- there should only be one result
|
||||
protected_areas:remove_area(id)
|
||||
end
|
||||
-- add protection if warranted
|
||||
if pocket_data.protected then
|
||||
protected_areas:insert_area(pocket_data.minp, vector.add(pocket_data.minp, mapblock_size), pocket_data.owner or "")
|
||||
end
|
||||
minetest.log("action", "[pocket_dimensions] Protection ownership of pocket dimension " .. pocket_data.name .. " set to " .. tostring(pocket_data.protected))
|
||||
save_data()
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------------------------------------------
|
||||
-- check if players have got out of pocket dimensions by other means and clear their origin locations
|
||||
local since_last_check = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
since_last_check = since_last_check + dtime
|
||||
if since_last_check > 10 then
|
||||
for name, _ in pairs(player_origin) do
|
||||
local pos = minetest.get_player_by_name(name):get_pos()
|
||||
if pos.y < layer_elevation or pos.y > layer_elevation + mapblock_size then
|
||||
player_origin[name] = nil -- somehow, player escaped the pocket dimension layer
|
||||
since_last_check = 0 -- note that we changed data
|
||||
end
|
||||
end
|
||||
if since_last_check == 0 then
|
||||
save_data()
|
||||
return
|
||||
end
|
||||
since_last_check = 0
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
------------------------------------------------------------------------------------------------
|
||||
|
||||
pocket_dimensions.get_pocket = function(pocket_name)
|
||||
return pockets_by_name[string.lower(pocket_name)]
|
||||
end
|
||||
|
||||
pocket_dimensions.get_all_pockets = function()
|
||||
local ret = {}
|
||||
for name, def in pairs(pockets_by_name) do
|
||||
table.insert(ret, def)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
pocket_dimensions.get_deleted_pockets = function()
|
||||
local ret = {}
|
||||
for hash, def in pairs(pockets_deleted) do
|
||||
table.insert(ret, def)
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
pocket_dimensions.pocket_containing_pos = function(pos)
|
||||
for name, pocket_data in pairs(pockets_by_name) do
|
||||
local pos_diff = vector.subtract(pos, pocket_data.minp)
|
||||
if pos_diff.y >=0 and pos_diff.y <= mapblock_size and -- check y first to eliminate possibility player's not in a pocket dimension at all
|
||||
pos_diff.x >=0 and pos_diff.x <= mapblock_size and
|
||||
pos_diff.z >=0 and pos_diff.z <= mapblock_size then
|
||||
|
||||
return pocket_data
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pocket_dimensions.rename_pocket = function(old_name, new_name)
|
||||
local new_name_lower = string.lower(new_name)
|
||||
local old_name_lower = string.lower(old_name)
|
||||
if pockets_by_name[new_name_lower] or not pockets_by_name[old_name_lower] then
|
||||
return false
|
||||
end
|
||||
pockets_by_name[new_name_lower] = pocket_data
|
||||
pockets_by_name[old_name_lower] = nil
|
||||
pocket_data.name = new_name
|
||||
save_data()
|
||||
return true
|
||||
end
|
||||
|
||||
pocket_dimensions.set_destination = function(pocket_data, destination)
|
||||
local dest = vector.round(destination)
|
||||
assert(dest.x > pocket_data.minp.x and dest.y > pocket_data.minp.y and dest.z > pocket_data.minp.z
|
||||
and dest.x < pocket_data.minp.x + mapblock_size
|
||||
and dest.y < pocket_data.minp.y + mapblock_size
|
||||
and dest.z < pocket_data.minp.z + mapblock_size,
|
||||
"[pocket_dimensions] attempting to set destination point " ..
|
||||
minetest.pos_to_string(dest) ..
|
||||
" that wasn't within pocket dimension "..
|
||||
pocket_data.name)
|
||||
pocket_data.destination = dest
|
||||
save_data()
|
||||
end
|
||||
|
||||
---------------------------------------------------------------------------------
|
||||
-- entering and exiting
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
-- Teleport effects
|
||||
|
||||
local particle_node_pos_spread = vector.new(0.5,0.5,0.5)
|
||||
local particle_user_pos_spread = vector.new(0.5,1.5,0.5)
|
||||
local particle_speed_spread = vector.new(0.1,0.1,0.1)
|
||||
local particle_poof = function(pos)
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 0.1,
|
||||
minpos = vector.subtract(pos, particle_node_pos_spread),
|
||||
maxpos = vector.add(pos, particle_user_pos_spread),
|
||||
minvel = particle_speed_spread,
|
||||
maxvel = particle_speed_spread,
|
||||
minacc = {x=0, y=0, z=0},
|
||||
maxacc = {x=0, y=0, z=0},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 0.5,
|
||||
minsize = 1,
|
||||
maxsize = 1,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "pocket_dimensions_spark.png",
|
||||
})
|
||||
end
|
||||
local teleport_player = function(player, dest)
|
||||
local source_pos = player:get_pos()
|
||||
particle_poof(source_pos)
|
||||
minetest.sound_play({name="pocket_dimensions_teleport_from"}, {pos = source_pos}, true)
|
||||
player:set_pos(dest)
|
||||
particle_poof(dest)
|
||||
minetest.sound_play({name="pocket_dimensions_teleport_to"}, {pos = dest}, true)
|
||||
end
|
||||
|
||||
pocket_dimensions.teleport_player_to_pocket = function(player_name, pocket_name)
|
||||
local pocket_data = pocket_dimensions.get_pocket(pocket_name)
|
||||
if pocket_data == nil or pocket_data.pending then
|
||||
return false
|
||||
end
|
||||
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
if not player_origin[player_name] then
|
||||
player_origin[player_name] = player:get_pos()
|
||||
save_data()
|
||||
end
|
||||
teleport_player(player, pocket_data.destination)
|
||||
return true
|
||||
end
|
||||
|
||||
-- returns a place to put players if they have no origin recorded
|
||||
local get_fallback_origin = function()
|
||||
local spawnpoint = minetest.setting_get_pos("static_spawnpoint")
|
||||
if not spawnpoint then
|
||||
local x = math.random()*1000 - 500
|
||||
local z = math.random()*1000 - 500
|
||||
local y =minetest.get_spawn_level(x,z)
|
||||
spawnpoint = {x=x,y=y,z=z}
|
||||
end
|
||||
end
|
||||
|
||||
pocket_dimensions.return_player_to_origin = function(player_name)
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
local origin = player_origin[player_name]
|
||||
if origin then
|
||||
teleport_player(player, origin)
|
||||
player_origin[player_name] = nil
|
||||
save_data()
|
||||
return
|
||||
end
|
||||
-- If the player's lost their origin data somehow, dump them somewhere using the spawn system to find an adequate place.
|
||||
local spawnpoint = get_fallback_origin()
|
||||
minetest.log("error", "[pocket_dimensions] Somehow "..name.." was at "..minetest.pos_to_string(clicker:get_pos())..
|
||||
" inside a pocket dimension but they had no origin point recorded when they tried to leave. Sending them to "..
|
||||
minetest.pos_to_string(spawnpoint).." as a fallback.")
|
||||
teleport_player(clicker, spawnpoint)
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
-- pocket creation
|
||||
|
||||
local mapgens = {}
|
||||
pocket_dimensions.register_pocket_type = function(type_name, mapgen_callback)
|
||||
mapgens[type_name] = mapgen_callback
|
||||
end
|
||||
|
||||
local emerge_callback = function(blockpos, action, calls_remaining, pocket_data)
|
||||
local mapgen_callback = mapgens[pocket_data.type]
|
||||
assert(mapgen_callback, "[pocket_dimensions] pocket type " .. pocket_data.type .. " had no registered mapgen callback")
|
||||
local dest = mapgen_callback(pocket_data)
|
||||
pocket_dimensions.set_destination(pocket_data, dest)
|
||||
pocket_data.pending = nil
|
||||
save_data()
|
||||
minetest.log("action", "[pocket_dimensions] Finished initializing terrain map for pocket dimension " .. pocket_data.name)
|
||||
end
|
||||
|
||||
pocket_dimensions.create_pocket = function(pocket_name, pocket_data_override)
|
||||
pocket_data_override = pocket_data_override or {}
|
||||
pocket_data_override.type = pocket_data_override.type or "grassy"
|
||||
if pocket_name == nil or pocket_name == "" then
|
||||
return false, S("Please provide a name for the pocket dimension")
|
||||
end
|
||||
|
||||
local pocket_name_lower = string.lower(pocket_name)
|
||||
if pockets_by_name[pocket_name_lower] then
|
||||
return false, S("The name @1 is already in use.", pocket_name)
|
||||
end
|
||||
|
||||
local count = 0
|
||||
while count < 100 do
|
||||
local x = math.random(0, block_grid_dimension) * mapblock_size + min_coordinate
|
||||
local z = math.random(0, block_grid_dimension) * mapblock_size + min_coordinate
|
||||
local pos = {x=x, y=layer_elevation, z=z}
|
||||
if pocket_dimensions.pocket_containing_pos(pos) == nil then
|
||||
local pocket_data = {pending=true, minp=pos, name=pocket_name}
|
||||
pockets_by_name[pocket_name_lower] = pocket_data
|
||||
for key, value in pairs(pocket_data_override) do
|
||||
pocket_data[key] = value
|
||||
end
|
||||
minetest.emerge_area(pos, pos, emerge_callback, pocket_data)
|
||||
save_data()
|
||||
minetest.log("action", "[pocket_dimensions] Created a pocket dimension named " .. pocket_name .. " at " .. minetest.pos_to_string(pos))
|
||||
return true, S("Pocket dimension @1 created", pocket_name)
|
||||
end
|
||||
end
|
||||
|
||||
return false, S("Failed to find a new location for this pocket dimension.")
|
||||
end
|
||||
|
||||
pocket_dimensions.delete_pocket = function(pocket_data)
|
||||
local pocket_name_lower = string.lower(pocket_data.name)
|
||||
local pocket_hash = minetest.hash_node_position(pocket_data.minp)
|
||||
pockets_deleted[pocket_hash] = pocket_data
|
||||
pockets_by_name[pocket_name_lower] = nil
|
||||
for name, personal_pocket_data in pairs(personal_pockets) do
|
||||
if pocket_data == personal_pocket_data then
|
||||
-- we're deleting a personal pocket, remove its record
|
||||
personal_pockets[name] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
save_data()
|
||||
|
||||
minetest.log("action", "[pocket_dimensions] Deleted the pocket dimension " .. pocket_data.name .. " at " .. minetest.pos_to_string(pocket_data.minp))
|
||||
return true, S("Deleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.", pocket_data.name, minetest.pos_to_string(pocket_data.minp))
|
||||
end
|
||||
|
||||
pocket_dimensions.undelete_pocket = function(pocket_data)
|
||||
local pocket_hash = minetest.hash_node_position(pocket_data.minp)
|
||||
local pocket_name_lower = string.lower(pocket_data.name)
|
||||
if pockets_by_name[pocket_name_lower] then
|
||||
return false, S("Cannot undelete, a pocket dimension with the name @1 already exists", pocket_name)
|
||||
end
|
||||
pockets_deleted[pocket_hash] = nil
|
||||
pockets_by_name[pocket_name_lower] = pocket_data
|
||||
if pocket_data.personal and pocket_data.owner and not personal_pockets[pocket_data.owner] then
|
||||
-- it was a personal pocket and the player hasn't created a new one, so restore that association
|
||||
personal_pockets[pocket_data.owner] = pocket_data
|
||||
end
|
||||
save_data()
|
||||
|
||||
minetest.log("action", "[pocket_dimensions] Undeleted the pocket dimension " .. pocket_data.name .. " at " .. minetest.pos_to_string(pocket_data.minp))
|
||||
return true, S("Undeleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.", pocket_data.name, minetest.pos_to_string(pocket_data.minp))
|
||||
end
|
||||
|
||||
------------------------------------------------------------------
|
||||
|
||||
-- TODO: some cross-validation to ensure only owned pockets are personal and only one pocket is personal per player
|
||||
|
||||
pocket_dimensions.get_personal_pocket = function(player_name)
|
||||
return personal_pockets[player_name]
|
||||
end
|
||||
|
||||
pocket_dimensions.set_personal_pocket = function(pocket_data, player_name)
|
||||
if pocket_data.personal and not player_name then
|
||||
-- clear personal pocket
|
||||
personal_pockets[player] = nil
|
||||
pocket_data.personal = nil
|
||||
else
|
||||
pocket_data.personal = true
|
||||
pocket_data.owner = player_name
|
||||
personal_pockets[player_name] = pocket_data
|
||||
end
|
||||
save_data()
|
||||
end
|
||||
|
||||
pocket_dimensions.set_owner = function(pocket_data, player_name)
|
||||
pocket_data.owner = player_name
|
||||
save_data()
|
||||
end
|
515
init.lua
515
init.lua
@ -2,19 +2,27 @@ pocket_dimensions = {}
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||
dofile(MP.."/voxelarea_iterator.lua")
|
||||
dofile(MP.."/api.lua")
|
||||
|
||||
--The world is a cube of side length 61840. Coordinates go from -30912 to 30927 in any direction.
|
||||
--The side length is a multiple of 80
|
||||
--773 * 80 = 61840
|
||||
-- so there are 773 * 773 = 597529 chunk in a horizontal layer. Should be plenty for distributing these things in.
|
||||
-- API
|
||||
local get_pocket = pocket_dimensions.get_pocket
|
||||
local get_all_pockets = pocket_dimensions.get_all_pockets
|
||||
local get_deleted_pockets = pocket_dimensions.get_deleted_pockets
|
||||
local rename_pocket = pocket_dimensions.rename_pocket
|
||||
local register_pocket_type = pocket_dimensions.register_pocket_type
|
||||
local create_pocket = pocket_dimensions.create_pocket
|
||||
local delete_pocket = pocket_dimensions.delete_pocket
|
||||
local undelete_pocket = pocket_dimensions.undelete_pocket
|
||||
local set_protection = pocket_dimensions.set_protection
|
||||
local pocket_containing_pos = pocket_dimensions.pocket_containing_pos
|
||||
local set_destination = pocket_dimensions.set_destination
|
||||
local get_personal_pocket = pocket_dimensions.get_personal_pocket
|
||||
local set_personal_pocket = pocket_dimensions.set_personal_pocket
|
||||
local set_owner = pocket_dimensions.set_owner
|
||||
local teleport_player_to_pocket = pocket_dimensions.teleport_player_to_pocket
|
||||
local return_player_to_origin = pocket_dimensions.return_player_to_origin
|
||||
|
||||
local mapgen_chunksize = tonumber(minetest.get_mapgen_setting("chunksize"))
|
||||
local mapblock_size = mapgen_chunksize * 16 -- should be 80 in almost all cases, but avoiding hardcoding it for extensibility
|
||||
local block_grid_dimension = math.floor(61840 / mapblock_size) -- should be 773
|
||||
local min_coordinate = -30912
|
||||
|
||||
local layer_elevation = tonumber(minetest.settings:get("pocket_dimensions_altitude")) or 30000
|
||||
layer_elevation = math.floor(layer_elevation / mapblock_size) * mapblock_size - 32 -- round to mapblock boundary
|
||||
local pocket_size = pocket_dimensions.pocket_size
|
||||
|
||||
local personal_pockets_chat_command = minetest.settings:get_bool("pocket_dimensions_personal_pockets_chat_command", false)
|
||||
local personal_pockets_key = minetest.settings:get_bool("pocket_dimensions_personal_pockets_key", false)
|
||||
@ -50,155 +58,6 @@ if mcl_core_modpath then
|
||||
end
|
||||
|
||||
|
||||
-- pocket data tables have the following properties:
|
||||
-- pending = true -- pocket is being initialized, don't teleport there just yet
|
||||
-- destination = a vector relative to the pocket's minp that is where new arrivals teleport tonumber
|
||||
-- name = a name for the pocket.
|
||||
-- owner = if set, this pocket is "owned" by this particular player.
|
||||
-- protected = if true, this pocket is protected and only the owner can modify its contents
|
||||
-- minp = the lower corner of the pocket's region
|
||||
|
||||
local pockets_by_hash = {}
|
||||
local pockets_by_name = {}
|
||||
local player_origin = {}
|
||||
local pockets_deleted = {} -- record deleted pockets for possible later undeletion, indexed by hash
|
||||
local personal_pockets = {} -- to be filled out if personal pockets are enabled
|
||||
|
||||
local protected_areas = AreaStore()
|
||||
|
||||
-------------------------------------------------------------------------------------
|
||||
-- protection override
|
||||
local old_is_protected = minetest.is_protected
|
||||
function minetest.is_protected(pos, name)
|
||||
if minetest.check_player_privs(name, "protection_bypass") then
|
||||
return false
|
||||
end
|
||||
local protection = protected_areas:get_areas_for_pos(pos, false, true)
|
||||
for _, area in pairs(protection) do
|
||||
if area.data ~= name then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return old_is_protected(pos, name)
|
||||
end
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
-- Loading and saving data
|
||||
local filename = minetest.get_worldpath() .. "/pocket_dimensions_data.lua"
|
||||
|
||||
local load_data = function()
|
||||
local f, e = loadfile(filename)
|
||||
if f then
|
||||
local data = f()
|
||||
pockets_by_hash = data.pockets_by_hash
|
||||
pockets_by_name = {} -- to be filled from pockets_by_hash
|
||||
player_origin = data.player_origin
|
||||
pockets_deleted = data.pockets_deleted
|
||||
if personal_pockets_enabled then
|
||||
for hash, pocket_data in pairs(pockets_by_hash) do
|
||||
if pocket_data.personal then
|
||||
personal_pockets[pocket_data.personal] = pocket_data
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
-- validate and add saved protected areas
|
||||
for hash, pocket_data in pairs(pockets_by_hash) do
|
||||
if hash ~= minetest.hash_node_position(pocket_data.minp) then
|
||||
minetest.log("error", "[pocket_dimensions] Hash mismatch for " .. tostring(hash) .. ", " .. dump(pocket_data))
|
||||
pocket_data.minp = minetest.get_position_from_hash(hash)
|
||||
end
|
||||
pockets_by_name[string.lower(pocket_data.name)] = pocket_data
|
||||
if pocket_data.protected then
|
||||
protected_areas:insert_area(pocket_data.minp, vector.add(pocket_data.minp, mapblock_size), pocket_data.owner)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local save_data = function()
|
||||
local data = {}
|
||||
data.pockets_by_hash = pockets_by_hash
|
||||
data.player_origin = player_origin
|
||||
data.pockets_deleted = pockets_deleted
|
||||
local file, e = io.open(filename, "w");
|
||||
if not file then
|
||||
return error(e);
|
||||
end
|
||||
file:write(minetest.serialize(data))
|
||||
file:close()
|
||||
end
|
||||
|
||||
load_data()
|
||||
----------------------------------------------------------------------------------------
|
||||
|
||||
-- check if players have got out of pocket dimensions by other means and clear their origin locations
|
||||
local since_last_check = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
since_last_check = since_last_check + dtime
|
||||
if since_last_check > 10 then
|
||||
for name, _ in pairs(player_origin) do
|
||||
local pos = minetest.get_player_by_name(name):get_pos()
|
||||
if pos.y < layer_elevation or pos.y > layer_elevation + mapblock_size then
|
||||
player_origin[name] = nil -- somehow, player escaped the pocket dimension layer
|
||||
since_last_check = 0 -- note that we changed data
|
||||
end
|
||||
end
|
||||
if since_last_check == 0 then
|
||||
save_data()
|
||||
return
|
||||
end
|
||||
since_last_check = 0
|
||||
end
|
||||
end)
|
||||
|
||||
-- returns a place to put players if they have no origin recorded
|
||||
local get_fallback_origin = function()
|
||||
local spawnpoint = minetest.setting_get_pos("static_spawnpoint")
|
||||
if not spawnpoint then
|
||||
local x = math.random()*1000 - 500
|
||||
local z = math.random()*1000 - 500
|
||||
local y =minetest.get_spawn_level(x,z)
|
||||
spawnpoint = {x=x,y=y,z=z}
|
||||
end
|
||||
end
|
||||
|
||||
------------------------------------------------------------------------------------------
|
||||
-- Teleport effects
|
||||
|
||||
local particle_node_pos_spread = vector.new(0.5,0.5,0.5)
|
||||
local particle_user_pos_spread = vector.new(0.5,1.5,0.5)
|
||||
local particle_speed_spread = vector.new(0.1,0.1,0.1)
|
||||
local particle_poof = function(pos)
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 0.1,
|
||||
minpos = vector.subtract(pos, particle_node_pos_spread),
|
||||
maxpos = vector.add(pos, particle_user_pos_spread),
|
||||
minvel = particle_speed_spread,
|
||||
maxvel = particle_speed_spread,
|
||||
minacc = {x=0, y=0, z=0},
|
||||
maxacc = {x=0, y=0, z=0},
|
||||
minexptime = 0.1,
|
||||
maxexptime = 0.5,
|
||||
minsize = 1,
|
||||
maxsize = 1,
|
||||
collisiondetection = false,
|
||||
vertical = false,
|
||||
texture = "pocket_dimensions_spark.png",
|
||||
})
|
||||
end
|
||||
local teleport_player = function(player, dest)
|
||||
local source_pos = player:get_pos()
|
||||
particle_poof(source_pos)
|
||||
minetest.sound_play({name="pocket_dimensions_teleport_from"}, {pos = source_pos}, true)
|
||||
player:set_pos(dest)
|
||||
particle_poof(dest)
|
||||
minetest.sound_play({name="pocket_dimensions_teleport_to"}, {pos = dest}, true)
|
||||
end
|
||||
|
||||
-----------------------------------------------------------------
|
||||
-- Border materials
|
||||
|
||||
@ -220,24 +79,10 @@ local get_border_def = function(override)
|
||||
can_dig = function(pos, player) return false end,
|
||||
on_blast = function(pos, intensity) return false end,
|
||||
on_punch = function(pos, node, clicker, pointed_thing)
|
||||
local clicker_pos = clicker:get_pos()
|
||||
if vector.distance(pos, clicker_pos) > 2 then
|
||||
if vector.distance(pos, clicker:get_pos()) > 2 then
|
||||
return
|
||||
end
|
||||
local name = clicker:get_player_name()
|
||||
local origin = player_origin[name]
|
||||
if origin then
|
||||
teleport_player(clicker, origin)
|
||||
player_origin[name] = nil
|
||||
save_data()
|
||||
return
|
||||
end
|
||||
-- If the player's lost their origin data somehow, dump them somewhere using the spawn system to find an adequate place.
|
||||
local spawnpoint = get_fallback_origin()
|
||||
minetest.log("error", "[pocket_dimensions] Somehow "..name.." was at "..minetest.pos_to_string(clicker:get_pos())..
|
||||
" inside a pocket dimension but they had no origin point recorded when they tried to leave. Sending them to "..
|
||||
minetest.pos_to_string(spawnpoint).." as a fallback.")
|
||||
teleport_player(clicker, spawnpoint)
|
||||
return_player_to_origin(clicker:get_player_name())
|
||||
end,
|
||||
on_construct = function(pos)
|
||||
-- if somehow a player gets ahold of one of these, ensure they can't place it anywhere.
|
||||
@ -275,15 +120,14 @@ minetest.register_node("pocket_dimensions:border_gray", get_border_def({
|
||||
local c_border_gray = minetest.get_content_id("pocket_dimensions:border_gray")
|
||||
|
||||
---------------------------------------------------------------
|
||||
-- Pocket creation
|
||||
-- Pocket mapgens
|
||||
|
||||
local spread_magnitude = mapblock_size
|
||||
local scale_magnitude = 5
|
||||
|
||||
local perlin_params = {
|
||||
offset = 0,
|
||||
scale = scale_magnitude,
|
||||
spread = {x = spread_magnitude, y = spread_magnitude, z = spread_magnitude},
|
||||
spread = {x = pocket_size, y = pocket_size, z = pocket_size},
|
||||
seed = 577,
|
||||
octaves = 5,
|
||||
persist = 0.63,
|
||||
@ -297,16 +141,13 @@ local perlin_noise = PerlinNoise(perlin_params)
|
||||
-- is world-seeded. Nobody will ever notice.
|
||||
local terrain_map = PerlinNoiseMap(
|
||||
perlin_params,
|
||||
{x=mapblock_size, y=mapblock_size, z=mapblock_size}
|
||||
{x=pocket_size, y=pocket_size, z=pocket_size}
|
||||
)
|
||||
|
||||
-- Once the map block for the new pocket dimension is loaded, this initializes its node layout and finds a default spot for arrivals to teleport to
|
||||
local emerge_grassy_callback = function(blockpos, action, calls_remaining, pocket_data)
|
||||
if pocket_data.pending ~= true then
|
||||
return
|
||||
end
|
||||
local grassy_mapgen = function(pocket_data)
|
||||
local minp = pocket_data.minp
|
||||
local maxp = vector.add(minp, mapblock_size)
|
||||
local maxp = vector.add(minp, pocket_size)
|
||||
local vm = minetest.get_voxel_manip(minp, maxp)
|
||||
local emin, emax = vm:get_emerged_area()
|
||||
local data = vm:get_data()
|
||||
@ -315,7 +156,7 @@ local emerge_grassy_callback = function(blockpos, action, calls_remaining, pocke
|
||||
local terrain_values = terrain_map:get_2d_map(minp)
|
||||
|
||||
-- Default is down on the floor of the border walls, in case default mod isn't installed and no landscape is created
|
||||
local middlep = {x=minp.x + math.floor(mapblock_size/2), y=2, z=minp.z + math.floor(mapblock_size/2)}
|
||||
local middlep = {x=minp.x + math.floor(pocket_size/2), y=2, z=minp.z + math.floor(pocket_size/2)}
|
||||
|
||||
local tree_spots = {}
|
||||
for vi, x, y, z in area:iterp_xyz(minp, maxp) do
|
||||
@ -334,7 +175,7 @@ local emerge_grassy_callback = function(blockpos, action, calls_remaining, pocke
|
||||
end
|
||||
end
|
||||
if middlep.x == x and middlep.z == z then
|
||||
middlep.y = math.max(y + 1 - minp.y, mapblock_size/2) -- surface of the ground or water in the center of the block
|
||||
middlep.y = math.max(y + 1, minp.y + pocket_size/2) -- surface of the ground or water in the center of the block
|
||||
end
|
||||
elseif y == terrain_level - 1 then
|
||||
if below_water then
|
||||
@ -363,21 +204,14 @@ local emerge_grassy_callback = function(blockpos, action, calls_remaining, pocke
|
||||
end
|
||||
end
|
||||
|
||||
middlep.x = math.floor(mapblock_size/2)
|
||||
middlep.z = math.floor(mapblock_size/2)
|
||||
|
||||
pocket_data.pending = nil
|
||||
pocket_data.destination = middlep
|
||||
save_data()
|
||||
minetest.log("action", "[pocket_dimensions] Finished initializing terrain map for pocket dimension " .. pocket_data.name)
|
||||
return middlep
|
||||
end
|
||||
|
||||
local emerge_cave_callback = function(blockpos, action, calls_remaining, pocket_data)
|
||||
if pocket_data.pending ~= true then
|
||||
return
|
||||
end
|
||||
register_pocket_type("grassy", grassy_mapgen)
|
||||
|
||||
local cave_mapgen = function(pocket_data)
|
||||
local minp = pocket_data.minp
|
||||
local maxp = vector.add(minp, mapblock_size)
|
||||
local maxp = vector.add(minp, pocket_size)
|
||||
local vm = minetest.get_voxel_manip(minp, maxp)
|
||||
local emin, emax = vm:get_emerged_area()
|
||||
local data = vm:get_data()
|
||||
@ -385,7 +219,7 @@ local emerge_cave_callback = function(blockpos, action, calls_remaining, pocket_
|
||||
local terrain_values = terrain_map:get_3d_map(minp)
|
||||
|
||||
local nearest_to_center = vector.add(minp, 2) -- start off down in the corner
|
||||
local center = vector.add(minp, math.floor(mapblock_size/2))
|
||||
local center = vector.add(minp, math.floor(pocket_size/2))
|
||||
for vi, x, y, z in area:iterp_xyz(minp, maxp) do
|
||||
if x == minp.x or x == maxp.x or y == minp.y or y == maxp.y or z == minp.z or z == maxp.z then
|
||||
data[vi] = c_border_gray
|
||||
@ -411,76 +245,10 @@ local emerge_cave_callback = function(blockpos, action, calls_remaining, pocket_
|
||||
end
|
||||
nearest_to_center.y = nearest_to_center.y + 2
|
||||
|
||||
pocket_data.pending = nil
|
||||
pocket_data.destination = vector.subtract(nearest_to_center, minp)
|
||||
save_data()
|
||||
minetest.log("action", "[pocket_dimensions] Finished initializing map for pocket dimension " .. pocket_data.name)
|
||||
return nearest_to_center
|
||||
end
|
||||
|
||||
|
||||
local create_new_pocket = function(pocket_name, player_name, pocket_data_override)
|
||||
pocket_data_override = pocket_data_override or {}
|
||||
pocket_data_override.type = pocket_data_override.type or "grassy"
|
||||
if pocket_name == nil or pocket_name == "" then
|
||||
if player_name then
|
||||
minetest.chat_send_player(player_name, S("Please provide a name for the pocket dimension"))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if pockets_by_name[string.lower(pocket_name)] then
|
||||
if player_name then
|
||||
minetest.chat_send_player(player_name, S("The name @1 is already in use.", pocket_name))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local count = 0
|
||||
while count < 100 do
|
||||
local x = math.random(0, block_grid_dimension) * mapblock_size + min_coordinate
|
||||
local z = math.random(0, block_grid_dimension) * mapblock_size + min_coordinate
|
||||
local pos = {x=x, y=layer_elevation, z=z}
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
if pockets_by_hash[hash] == nil and pockets_deleted[hash] == nil then
|
||||
local pocket_data = {pending=true, minp=pos, name=pocket_name}
|
||||
pockets_by_hash[hash] = pocket_data
|
||||
pockets_by_name[string.lower(pocket_name)] = pocket_data
|
||||
for key, value in pairs(pocket_data_override) do
|
||||
pocket_data[key] = value
|
||||
end
|
||||
if pocket_data.type == "grassy" then
|
||||
minetest.emerge_area(pos, pos, emerge_grassy_callback, pocket_data)
|
||||
else
|
||||
minetest.emerge_area(pos, pos, emerge_cave_callback, pocket_data)
|
||||
end
|
||||
save_data()
|
||||
minetest.chat_send_player(player_name, S("Pocket dimension @1 created", pocket_name))
|
||||
minetest.log("action", "[pocket_dimensions] " .. player_name .. " Created a pocket dimension named " .. pocket_name .. " at " .. minetest.pos_to_string(pos))
|
||||
return pocket_data
|
||||
end
|
||||
end
|
||||
|
||||
if player_name then
|
||||
minetest.chat_send_player(player_name, S("Failed to find a new location for this pocket dimension."))
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local teleport_player_to_pocket = function(player_name, pocket_name)
|
||||
local pocket_data = pockets_by_name[string.lower(pocket_name)]
|
||||
if pocket_data == nil or pocket_data.pending then
|
||||
return false
|
||||
end
|
||||
|
||||
local dest = vector.add(pocket_data.minp, pocket_data.destination)
|
||||
local player = minetest.get_player_by_name(player_name)
|
||||
if not player_origin[player_name] then
|
||||
player_origin[player_name] = player:get_pos()
|
||||
save_data()
|
||||
end
|
||||
teleport_player(player, dest)
|
||||
return true
|
||||
end
|
||||
register_pocket_type("cave", cave_mapgen)
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
@ -495,7 +263,7 @@ local get_select_formspec = function(player_name)
|
||||
.."label[0.5,0.6;"..S("Link to pocket dimension:").."]dropdown[1,1;4,0.5;pocket_select;"
|
||||
}
|
||||
local names = {}
|
||||
for name, def in pairs(pockets_by_name) do
|
||||
for _, def in pairs(get_all_pockets()) do
|
||||
table.insert(names, minetest.formspec_escape(def.name))
|
||||
end
|
||||
table.sort(names)
|
||||
@ -530,7 +298,7 @@ minetest.register_node("pocket_dimensions:portal", {
|
||||
local meta = minetest.get_meta(pos)
|
||||
local pocket_dest = minetest.string_to_pos(meta:get_string("pocket_dest"))
|
||||
if pocket_dest then
|
||||
local pocket_data = pockets_by_hash[minetest.hash_node_position(pocket_dest)]
|
||||
local pocket_data = pocket_containing_pos(pocket_dest)
|
||||
if pocket_data then
|
||||
teleport_player_to_pocket(player_name, pocket_data.name)
|
||||
return
|
||||
@ -559,7 +327,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
if fields.pocket_select then
|
||||
for _, name in pairs(state.names) do
|
||||
if fields.pocket_select == name then
|
||||
local pocket_data = pockets_by_name[string.lower(name)] -- TODO: minetest.formspec_escape may screw up this lookup, do something different
|
||||
local pocket_data = get_pocket(name) -- TODO: minetest.formspec_escape may screw up this lookup, do something different
|
||||
if pocket_data then
|
||||
local meta = minetest.get_meta(state.pos)
|
||||
meta:set_string("pocket_dest", minetest.pos_to_string(pocket_data.minp))
|
||||
@ -575,18 +343,6 @@ end)
|
||||
-------------------------------------------------------------------------------
|
||||
-- Admin commands
|
||||
|
||||
local update_protected = function(pocket_data)
|
||||
-- clear any existing protection
|
||||
protected = protected_areas:get_areas_for_pos(pocket_data.minp)
|
||||
for id, _ in pairs(protected) do
|
||||
protected_areas:remove_area(id)
|
||||
end
|
||||
-- add protection if warranted
|
||||
if pocket_data.protected then
|
||||
protected_areas:insert_area(pocket_data.minp, vector.add(pocket_data.minp, mapblock_size), pocket_data.owner)
|
||||
end
|
||||
end
|
||||
|
||||
local formspec_state = {}
|
||||
local get_admin_formspec = function(player_name)
|
||||
formspec_state[player_name] = formspec_state[player_name] or {row_index=1}
|
||||
@ -601,32 +357,36 @@ local get_admin_formspec = function(player_name)
|
||||
formspec[#formspec+1] = "tablecolumns[text,tooltip="..S("Name")
|
||||
..";text,tooltip="..S("Owner")
|
||||
..";text,tooltip="..S("Protected")
|
||||
if personal_pockets then
|
||||
if personal_pockets_enabled then
|
||||
formspec[#formspec+1] = ";text,tooltip="..S("Personal")
|
||||
end
|
||||
formspec[#formspec+1] = "]table[0.5,1.0;7,5.75;pocket_table;"
|
||||
|
||||
local table_to_use = pockets_by_name
|
||||
local delete_label = S("Delete")
|
||||
local undelete_toggle = "false"
|
||||
local table_to_use
|
||||
local delete_label
|
||||
local undelete_toggle
|
||||
if state.undelete == "true" then
|
||||
table_to_use = pockets_deleted
|
||||
table_to_use = get_deleted_pockets()
|
||||
delete_label = S("Undelete")
|
||||
undelete_toggle = "true"
|
||||
else
|
||||
table_to_use = get_all_pockets()
|
||||
delete_label = S("Delete")
|
||||
undelete_toggle = "false"
|
||||
end
|
||||
|
||||
local i = 0
|
||||
for _, dimension_data in pairs(table_to_use) do
|
||||
for _, pocket_data in pairs(table_to_use) do
|
||||
i = i + 1
|
||||
if i == state.row_index then
|
||||
state.selected_data = dimension_data
|
||||
state.selected_data = pocket_data
|
||||
end
|
||||
local owner = dimension_data.owner or "<none>"
|
||||
formspec[#formspec+1] = minetest.formspec_escape(dimension_data.name)
|
||||
local owner = pocket_data.owner or "<none>"
|
||||
formspec[#formspec+1] = minetest.formspec_escape(pocket_data.name)
|
||||
..",".. minetest.formspec_escape(owner)
|
||||
..","..tostring(dimension_data.protected or "false")
|
||||
if personal_pockets then
|
||||
formspec[#formspec+1] = ","..tostring(dimension_data.personal)
|
||||
..","..tostring(pocket_data.protected or "false")
|
||||
if personal_pockets_enabled then
|
||||
formspec[#formspec+1] = ","..tostring(pocket_data.personal)
|
||||
end
|
||||
formspec[#formspec+1] = ","
|
||||
end
|
||||
@ -689,13 +449,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
end
|
||||
|
||||
if fields.rename and fields.pocket_name ~= pocket_data.name then
|
||||
if pockets_by_name[string.lower(fields.pocket_name)] then
|
||||
if not rename_pocket(pocket_data.name, fields.pocket_name)then
|
||||
minetest.chat_send_player(player_name, S("A pocket dimension with that name already exists"))
|
||||
else
|
||||
pockets_by_name[string.lower(fields.pocket_name)] = pocket_data
|
||||
pockets_by_name[string.lower(pocket_data.name)] = nil
|
||||
pocket_data.name = fields.pocket_name
|
||||
save_data()
|
||||
refresh=true
|
||||
end
|
||||
end
|
||||
@ -706,53 +462,27 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
end
|
||||
|
||||
if fields.create then
|
||||
if create_new_pocket(fields.pocket_name, player_name, {type=fields.create_type}) then
|
||||
local success, message = create_pocket(fields.pocket_name, {type=fields.create_type})
|
||||
if success then
|
||||
refresh = true
|
||||
end
|
||||
minetest.chat_send_player(player_name, message)
|
||||
end
|
||||
|
||||
if fields.delete then
|
||||
local pocket_hash = minetest.hash_node_position(pocket_data.minp)
|
||||
if state.undelete == "true" then
|
||||
if pockets_by_name[string.lower(pocket_data.name)] then
|
||||
minetest.chat_send_player(player_name, S("Cannot undelete, a pocket dimension with that name already exists"))
|
||||
else
|
||||
pockets_deleted[pocket_hash] = nil
|
||||
pockets_by_name[string.lower(pocket_data.name)] = pocket_data
|
||||
pockets_by_hash[pocket_hash] = pocket_data
|
||||
if pocket_data.personal and personal_pockets and not personal_pockets[pocket_data.personal] then
|
||||
-- it was a personal pocket and the player hasn't created a new one, so restore that association
|
||||
personal_pockets[pocket_data.personal] = pocket_data
|
||||
end
|
||||
minetest.chat_send_player(player_name, S("Undeleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.", pocket_data.name, minetest.pos_to_string(pocket_data.minp)))
|
||||
minetest.log("action", "[pocket_dimensions] " .. player_name .. " undeleted the pocket dimension " .. pocket_data.name .. " at " .. minetest.pos_to_string(pocket_data.minp))
|
||||
end
|
||||
local success, message = undelete_pocket(pocket_data)
|
||||
minetest.chat_send_player(player_name, message)
|
||||
else
|
||||
pockets_deleted[pocket_hash] = pocket_data
|
||||
pockets_by_name[string.lower(pocket_data.name)] = nil
|
||||
pockets_by_hash[pocket_hash] = nil
|
||||
if personal_pockets then
|
||||
for name, personal_pocket_data in pairs(personal_pockets) do
|
||||
if pocket_data == personal_pocket_data then
|
||||
-- we're deleting a personal pocket, remove its record
|
||||
personal_pockets[name] = nil
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
minetest.chat_send_player(player_name, S("Deleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.", pocket_data.name, minetest.pos_to_string(pocket_data.minp)))
|
||||
minetest.log("action", "[pocket_dimensions] " .. player_name .. " deleted the pocket dimension " .. pocket_data.name .. " at " .. minetest.pos_to_string(pocket_data.minp))
|
||||
local success, message = delete_pocket(pocket_data)
|
||||
minetest.chat_send_player(player_name, message)
|
||||
end
|
||||
save_data()
|
||||
state.row_index = 1
|
||||
refresh = true
|
||||
end
|
||||
|
||||
if fields.protect then
|
||||
pocket_data.protected = not pocket_data.protected
|
||||
update_protected(pocket_data)
|
||||
minetest.log("action", "[pocket_dimensions] " .. player_name .. " set protection ownership of pocket dimension " .. pocket_data.name .. " to " .. tostring(pocket_data.protected))
|
||||
save_data()
|
||||
set_protection(pocket_data, not pocket_data.protected)
|
||||
refresh = true
|
||||
end
|
||||
|
||||
@ -762,11 +492,10 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
|
||||
if fields.set_owner and pocket_data.owner ~= fields.owner then
|
||||
if fields.owner == "" then
|
||||
pocket_data.owner = nil
|
||||
set_owner(pocket_data, nil)
|
||||
else
|
||||
pocket_data.owner = fields.owner
|
||||
set_owner(pocket_data, fields.owner)
|
||||
end
|
||||
save_data()
|
||||
refresh = true
|
||||
end
|
||||
|
||||
@ -775,8 +504,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
end
|
||||
end)
|
||||
|
||||
-------------------------------------------------------------------------------------------------------
|
||||
-- Player commands
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
-- Personal pockets
|
||||
|
||||
if personal_pockets_enabled then
|
||||
function teleport_to_pending(pocket_name, player_name, count)
|
||||
@ -792,7 +521,7 @@ if personal_pockets_enabled then
|
||||
end
|
||||
|
||||
local teleport_to_personal_pocket = function(player_name)
|
||||
local pocket_data = personal_pockets[player_name]
|
||||
local pocket_data = get_personal_pocket(player_name)
|
||||
if pocket_data then
|
||||
teleport_player_to_pocket(player_name, pocket_data.name)
|
||||
return
|
||||
@ -800,21 +529,24 @@ if personal_pockets_enabled then
|
||||
|
||||
-- Find an unused default name
|
||||
local new_pocket_name = player_name
|
||||
if pockets_by_name[string.lower(new_pocket_name)] then
|
||||
if get_pocket(new_pocket_name) then
|
||||
local count = 1
|
||||
local new_pocket_name_prefix = new_pocket_name
|
||||
new_pocket_name = new_pocket_name_prefix .. " " .. count
|
||||
while pockets_by_name[string.lower(new_pocket_name)] do
|
||||
while get_pocket(new_pocket_name) do
|
||||
count = count + 1
|
||||
new_pocket_name = new_pocket_name_prefix .. " " .. count
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
pocket_data = create_new_pocket(new_pocket_name, player_name, {protected=true, owner=player_name, personal=player_name, type="grassy"})
|
||||
if pocket_data then
|
||||
personal_pockets[player_name] = pocket_data
|
||||
local success, message = create_pocket(new_pocket_name, {type="grassy"})
|
||||
if success then
|
||||
pocket_data = get_pocket(new_pocket_name)
|
||||
set_personal_pocket(pocket_data, player_name)
|
||||
set_protection(pocket_data, true)
|
||||
teleport_to_pending(new_pocket_name, player_name, 1)
|
||||
end
|
||||
minetest.chat_send_player(player_name, message)
|
||||
end
|
||||
|
||||
if personal_pockets_chat_command then
|
||||
@ -934,30 +666,26 @@ if personal_pockets_enabled then
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------------------------------
|
||||
-- Player commands
|
||||
|
||||
minetest.register_chatcommand("pocket_entry", {
|
||||
params = "",
|
||||
-- privs = {}, -- TODO a new privilege here?
|
||||
description = S("Set the entry point of the pocket dimension you're in to where you're standing."),
|
||||
func = function(player_name, param)
|
||||
local pos = minetest.get_player_by_name(player_name):get_pos()
|
||||
-- Find the pocket the player's in
|
||||
for hash, pocket_data in pairs(pockets_by_hash) do
|
||||
local pos_diff = vector.subtract(pos, pocket_data.minp)
|
||||
if pos_diff.y >=0 and pos_diff.y <= mapblock_size and -- check y first to eliminate possibility player's not in a pocket dimension at all
|
||||
pos_diff.x >=0 and pos_diff.x <= mapblock_size and
|
||||
pos_diff.z >=0 and pos_diff.z <= mapblock_size then
|
||||
|
||||
if player_name == pocket_data.owner or minetest.check_player_privs(player_name, "server") then
|
||||
pocket_data.destination = vector.round(pos_diff)
|
||||
save_data()
|
||||
minetest.chat_send_player(player_name, S("The entry point for pocket dimension @1 has been updated", pocket_data.name))
|
||||
else
|
||||
minetest.chat_send_player(player_name, S("You don't have permission to change the entry point of pocket dimension @1.", pocket_data.name))
|
||||
end
|
||||
return
|
||||
end
|
||||
local pocket_data = pocket_containing_pos(pos)
|
||||
if not pocket_data then
|
||||
minetest.chat_send_player(player_name, S("You're not inside a pocket dimension right now."))
|
||||
return
|
||||
end
|
||||
minetest.chat_send_player(player_name, S("You're not inside a pocket dimension right now."))
|
||||
if player_name ~= pocket_data.owner and not minetest.check_player_privs(player_name, "server") then
|
||||
minetest.chat_send_player(player_name, S("You don't have permission to change the entry point of pocket dimension @1.", pocket_data.name))
|
||||
return
|
||||
end
|
||||
set_destination(pocket_data, pos)
|
||||
minetest.chat_send_player(player_name, S("The entry point for pocket dimension @1 has been updated", pocket_data.name))
|
||||
end,
|
||||
})
|
||||
|
||||
@ -971,56 +699,35 @@ minetest.register_chatcommand("pocket_rename", {
|
||||
return
|
||||
end
|
||||
local pos = minetest.get_player_by_name(player_name):get_pos()
|
||||
-- Find the pocket the player's in
|
||||
for hash, pocket_data in pairs(pockets_by_hash) do
|
||||
local pos_diff = vector.subtract(pos, pocket_data.minp)
|
||||
if pos_diff.y >=0 and pos_diff.y <= mapblock_size and -- check y first to eliminate possibility player's not in a pocket dimension at all
|
||||
pos_diff.x >=0 and pos_diff.x <= mapblock_size and
|
||||
pos_diff.z >=0 and pos_diff.z <= mapblock_size then
|
||||
|
||||
if player_name == pocket_data.owner or minetest.check_player_privs(player_name, "server") then
|
||||
if pockets_by_name[string.lower(param)] then
|
||||
minetest.chat_send_player(player_name, S("A pocket dimension with that name already exists"))
|
||||
else
|
||||
minetest.chat_send_player(player_name, S("The name of pocket dimension @1 has been changed to \"@2\".", pocket_data.name, param))
|
||||
pockets_by_name[string.lower(pocket_data.name)] = nil
|
||||
pockets_by_name[string.lower(param)] = pocket_data
|
||||
pocket_data.name = param
|
||||
save_data()
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player_name, S("You don't have permission to change the name of pocket dimension @1.", pocket_data.name))
|
||||
end
|
||||
return
|
||||
end
|
||||
local pocket_data = pocket_containing_pos(pos)
|
||||
if not pocket_data then
|
||||
minetest.chat_send_player(player_name, S("You're not inside a pocket dimension right now."))
|
||||
return
|
||||
end
|
||||
if player_name ~= pocket_data.owner and not minetest.check_player_privs(player_name, "server") then
|
||||
minetest.chat_send_player(player_name, S("You don't have permission to change the name of pocket dimension @1.", pocket_data.name))
|
||||
return
|
||||
end
|
||||
local oldname = pocket_data.name
|
||||
if rename_pocket(oldname, param) then
|
||||
minetest.chat_send_player(player_name, S("The name of pocket dimension @1 has been changed to \"@2\".", oldname, param))
|
||||
else
|
||||
minetest.chat_send_player(player_name, S("A pocket dimension with that name already exists"))
|
||||
end
|
||||
minetest.chat_send_player(player_name, S("You're not inside a pocket dimension right now."))
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_chatcommand("pocket_name", {
|
||||
params = "",
|
||||
-- privs = {}, -- TODO a new privilege here?
|
||||
description = S("Finds the name of the pocket dimension you're inside right now."),
|
||||
func = function(player_name, param)
|
||||
local pos = minetest.get_player_by_name(player_name):get_pos()
|
||||
-- Find the pocket the player's in
|
||||
for hash, pocket_data in pairs(pockets_by_hash) do
|
||||
local pos_diff = vector.subtract(pos, pocket_data.minp)
|
||||
if pos_diff.y >=0 and pos_diff.y <= mapblock_size and -- check y first to eliminate possibility player's not in a pocket dimension at all
|
||||
pos_diff.x >=0 and pos_diff.x <= mapblock_size and
|
||||
pos_diff.z >=0 and pos_diff.z <= mapblock_size then
|
||||
|
||||
minetest.chat_send_player(player_name, S("You're inside pocket dimension \"@1\"", pocket_data.name))
|
||||
return
|
||||
end
|
||||
local pocket_data = pocket_containing_pos(pos)
|
||||
if pocket_data then
|
||||
minetest.chat_send_player(player_name, S("You're inside pocket dimension \"@1\"", pocket_data.name))
|
||||
else
|
||||
minetest.chat_send_player(player_name, S("You're not inside a pocket dimension right now."))
|
||||
end
|
||||
minetest.chat_send_player(player_name, S("You're not inside a pocket dimension right now."))
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
|
||||
pocket_dimensions.teleport_player_to_pocket = teleport_player_to_pocket
|
||||
|
||||
})
|
@ -2,13 +2,19 @@
|
||||
|
||||
|
||||
|
||||
### init.lua ###
|
||||
### api.lua ###
|
||||
|
||||
Boundary of a pocket dimension=
|
||||
Please provide a name for the pocket dimension=
|
||||
The name @1 is already in use.=
|
||||
Pocket dimension @1 created=
|
||||
Failed to find a new location for this pocket dimension.=
|
||||
Deleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.=
|
||||
Cannot undelete, a pocket dimension with the name @1 already exists=
|
||||
Undeleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.=
|
||||
|
||||
### init.lua ###
|
||||
|
||||
Boundary of a pocket dimension=
|
||||
Link to pocket dimension:=
|
||||
Pocket Dimension Access=
|
||||
Portal to @1=
|
||||
@ -16,8 +22,8 @@ Name=
|
||||
Owner=
|
||||
Protected=
|
||||
Personal=
|
||||
Delete=
|
||||
Undelete=
|
||||
Delete=
|
||||
Rename=
|
||||
Create=
|
||||
Teleport To=
|
||||
@ -27,9 +33,6 @@ Show deleted=
|
||||
Administrate pocket dimensions=
|
||||
This command is for server admins only.=
|
||||
A pocket dimension with that name already exists=
|
||||
Cannot undelete, a pocket dimension with that name already exists=
|
||||
Undeleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.=
|
||||
Deleted pocket dimension @1 at @2. Note that this doesn't affect the map, just moves this pocket dimension out of regular access and into the deleted list.=
|
||||
Teleport to personal pocket dimension @1 failed after @2 tries.=
|
||||
Teleport to your personal pocket dimension=
|
||||
This tool can be used @1 times before breaking.=
|
||||
@ -43,12 +46,12 @@ Entering the "/pocket_personal" chat command=
|
||||
You can return to this pocket dimension by:=
|
||||
You have spawned inside your own personal pocket dimension.@nTo leave, walk to within one meter of the pocket dimension's@nboundary and punch the barrier there.=
|
||||
Set the entry point of the pocket dimension you're in to where you're standing.=
|
||||
The entry point for pocket dimension @1 has been updated=
|
||||
You don't have permission to change the entry point of pocket dimension @1.=
|
||||
You're not inside a pocket dimension right now.=
|
||||
You don't have permission to change the entry point of pocket dimension @1.=
|
||||
The entry point for pocket dimension @1 has been updated=
|
||||
Renames the pocket dimension you're inside.=
|
||||
Please provide a name as a parameter to this command.=
|
||||
The name of pocket dimension @1 has been changed to "@2".=
|
||||
You don't have permission to change the name of pocket dimension @1.=
|
||||
The name of pocket dimension @1 has been changed to "@2".=
|
||||
Finds the name of the pocket dimension you're inside right now.=
|
||||
You're inside pocket dimension "@1"=
|
||||
|
Loading…
x
Reference in New Issue
Block a user