2022-09-18 02:25:49 +00:00
local wea_c = worldeditadditions_core
2022-09-24 22:48:36 +00:00
local Vector3 = wea_c.Vector3
2022-09-18 02:25:49 +00:00
local positions_count_limit = 999
local positions = { }
2022-09-19 22:18:49 +00:00
--- Position manager.
-- @event set { player_name: string, i: number, pos: Vector3 } A new position has been set in a player's list at a specific position.
-- @event push { player_name: string, i: number, pos: Vector3 } A new position has been pushed onto a player's stack.
-- @event pop { player_name: string, i: number, pos: Vector3 } A new position has been pushed onto a player's stack.
-- @event clear { player_name: string } The positions for a player have been cleared.
2022-09-18 15:06:23 +00:00
local anchor = nil
2022-09-18 02:25:49 +00:00
2022-09-19 22:18:49 +00:00
--- Ensures that a table exists for the given player.
-- @param player_name string The name of the player to check.
2022-09-18 02:25:49 +00:00
local function ensure_player ( player_name )
2022-09-18 14:30:53 +00:00
if player_name == nil then
minetest.log ( " error " , " [wea core:pos:ensure_player] player_name is nil " )
end
2022-09-18 02:25:49 +00:00
if not positions [ player_name ] then
positions [ player_name ] = { }
end
end
--- Gets the position with the given index for the given player.
-- @param player_name string The name of the player to fetch the position for.
2022-09-19 22:18:49 +00:00
-- @param i number The index of the position to fetch.
-- @returns Vector3? The position requested, or nil if it doesn't exist.
2022-09-18 02:25:49 +00:00
local function get_pos ( player_name , i )
ensure_player ( player_name )
return positions [ player_name ] [ i ]
end
2022-09-19 22:18:49 +00:00
--- Convenience function that returns position 1 for the given player.
-- @param player_name string The name of the player to fetch the position for.
-- @returns Vector3? The position requested, or nil if it doesn't exist.
2022-09-18 02:25:49 +00:00
local function get_pos1 ( player_name ) return get_pos ( player_name , 1 ) end
2022-09-19 22:18:49 +00:00
--- Convenience function that returns position 1 for the given player.
-- @param player_name string The name of the player to fetch the position for.
-- @returns Vector3? The position requested, or nil if it doesn't exist.
2022-09-18 02:25:49 +00:00
local function get_pos2 ( player_name ) return get_pos ( player_name , 2 ) end
2022-09-19 22:18:49 +00:00
--- Gets a list of all the positions for the given player.
-- @param player_name string The name of the player to fetch the position for.
-- @returns Vector3[] A list of positions for the given player.
2022-09-18 02:25:49 +00:00
local function get_pos_all ( player_name )
ensure_player ( player_name )
2022-09-19 22:18:49 +00:00
return wea_c.table . deepcopy ( positions [ player_name ] )
2022-09-18 02:25:49 +00:00
end
2022-09-24 22:48:36 +00:00
--- Get a bounding box that encloses all the positions currently defined by a given player.
-- @param player_name string The name of the player to fetch the boudnign box for.
-- @returns nil|(Vector3,Vector3) 2 positions that define opposite corners of a region that fully encloses all the defined points for the given player, or nil ir the specified player has no points currently defined.
local function get_bounds ( player_name )
ensure_player ( player_name )
if # positions [ player_name ] < 1 then return nil end
local pos1 , pos2 = positions [ player_name ] [ 1 ] , positions [ player_name ] [ 1 ]
for _ , pos in pairs ( positions [ player_name ] ) do
pos1 , pos2 = Vector3.expand_region ( pos , pos1 , pos2 )
end
return pos1 , pos2
end
2022-09-19 22:18:49 +00:00
--- Counts the number of positioons registered to a given player.
-- @param player_name string The name of the player to fetch the position for.
-- @returns number The number of positions registered for the given player.
2022-09-18 02:25:49 +00:00
local function pos_count ( player_name )
ensure_player ( player_name )
2022-09-18 14:30:53 +00:00
return # positions [ player_name ]
2022-09-18 02:25:49 +00:00
end
2022-09-19 22:18:49 +00:00
--- Sets the position at the given index for the given player.
-- You probably want push_pos, not this function.
-- @param player_name string The name of the player to set the position for.
-- @param i number The index to set the position at.
-- @param pos Vector3 The position to set.
-- @returns bool Whether the operation was successful or not (players aren't allowed more than positions_count_limit number of positions at a time).
2022-09-18 02:25:49 +00:00
local function set_pos ( player_name , i , pos )
if i > positions_count_limit then return false end
ensure_player ( player_name )
positions [ player_name ] [ i ] = pos
2022-09-19 22:18:49 +00:00
anchor : emit ( " set " , { player_name = player_name , i = i , pos = pos } )
2022-09-18 02:25:49 +00:00
return true
end
2022-09-19 22:40:42 +00:00
--- Convenience function that set position 1 for the given player.
-- @param player_name string The name of the player to set pos1 for.
-- @param pos Vector3? The new Vector3 for pos1 to set.
-- @returns bool Whether the operation was successful or not, but in this case will always return true so can be ignored.
local function set_pos1 ( player_name , pos )
return set_pos ( player_name , 1 , pos )
end
--- Convenience function that set position 2 for the given player.
-- @param player_name string The name of the player to set pos1 for.
-- @param pos Vector3? The new Vector3 for pos2 to set.
-- @returns bool Whether the operation was successful or not, but in this case will always return true so can be ignored.
local function set_pos2 ( player_name , pos )
return set_pos ( player_name , 2 , pos )
end
2022-09-19 22:18:49 +00:00
--- Sets the all the positions for the given player.
-- You probably want push_pos, not this function.
-- @param player_name string The name of the player to set the positions for.
-- @param pos_list Vector3 The table of positions to set.
-- @returns bool Whether the operation was successful or not (players aren't allowed more than positions_count_limit number of positions at a time).
local function set_pos_all ( player_name , pos_list )
2022-09-18 02:25:49 +00:00
if # pos_list > positions_count_limit then return false end
positions [ player_name ] = pos_list
2022-09-19 22:18:49 +00:00
for i , pos_new in ipairs ( positions [ player_name ] ) do
anchor : emit ( " push " , { player_name = player_name , pos = pos_new , i = i } )
2022-09-18 15:06:23 +00:00
end
2022-09-19 22:18:49 +00:00
return true
2022-09-18 02:25:49 +00:00
end
2022-09-19 22:18:49 +00:00
--- Clears all the positions for the given player.
-- @param player_name string The name of the player to clear the positions for.
-- @returns void
2022-09-18 02:25:49 +00:00
local function clear ( player_name )
if positions [ player_name ] then
positions [ player_name ] = nil
end
2022-09-19 22:18:49 +00:00
anchor : emit ( " clear " , { player_name = player_name } )
2022-09-18 02:25:49 +00:00
end
2022-09-19 22:18:49 +00:00
--- Removes the last position from the for a given player and returns it.
-- @param player_name string The name of the player to pop the position for.
-- @returns Vector3? The position removed, or nil if it doesn't exist.
2022-09-18 14:30:53 +00:00
local function pop_pos ( player_name )
ensure_player ( player_name )
if # positions [ player_name ] <= 0 then return nil end
2022-09-19 22:18:49 +00:00
local count = # positions [ player_name ]
2022-09-18 15:06:23 +00:00
local last_pos = table.remove ( positions [ player_name ] )
2022-09-19 22:18:49 +00:00
anchor : emit ( " pop " , { player_name = player_name , pos = last_pos , i = count } )
2022-09-18 15:06:23 +00:00
return last_pos
2022-09-18 14:30:53 +00:00
end
2022-09-19 22:18:49 +00:00
--- Adds a position to the list for a given player.
-- @param player_name string The name of the player to add the position for.
-- @param pos Vector3 The position to add.
-- @returns number The new number of positions for that player.
2022-09-18 14:30:53 +00:00
local function push_pos ( player_name , pos )
ensure_player ( player_name )
table.insert ( positions [ player_name ] , pos )
2022-09-19 22:18:49 +00:00
anchor : emit ( " push " , { player_name = player_name , pos = pos , i = # positions [ player_name ] } )
return # positions [ player_name ]
2022-09-18 14:30:53 +00:00
end
2022-09-18 02:25:49 +00:00
2022-09-18 15:06:23 +00:00
anchor = wea_c.EventEmitter . new ( {
2022-09-18 02:25:49 +00:00
get = get_pos ,
get1 = get_pos1 ,
get2 = get_pos2 ,
get_all = get_pos_all ,
2022-09-24 22:48:36 +00:00
get_bounds = get_bounds ,
2022-09-18 14:30:53 +00:00
count = pos_count ,
clear = clear ,
pop = pop_pos ,
push = push_pos ,
2022-09-18 02:25:49 +00:00
set = set_pos ,
2022-09-19 22:40:42 +00:00
set_pos1 = set_pos1 ,
set_pos2 = set_pos2 ,
2022-09-18 15:06:23 +00:00
set_all = set_pos_all
} )
return anchor