2023-06-27 22:45:48 +02:00
local wea_c = worldeditadditions_core
local EventEmitter = worldeditadditions_core.EventEmitter
local Vector3 = wea_c.Vector3
local anchor
local entity_wall_size = 10
local collision_thickness = 0.2
2023-07-01 02:11:56 +02:00
local last_reset = tostring ( wea_c.get_ms_time ( ) )
2023-06-27 22:45:48 +02:00
local WEAPositionMarkerWall = {
initial_properties = {
visual = " cube " ,
visual_size = { x = 1 , y = 1 , z = 1 } ,
collisionbox = { - 0.55 , - 0.55 , - 0.55 , 0.55 , 0.55 , 0.55 } ,
-- ^^ { xmin, ymin, zmin, xmax, ymax, zmax } relative to obj pos
physical = false ,
collide_with_objects = false ,
static_save = false ,
textures = {
" worldeditadditions_core_marker_wall.png " ,
" worldeditadditions_core_marker_wall.png " ,
" worldeditadditions_core_marker_wall.png " ,
" worldeditadditions_core_marker_wall.png " ,
" worldeditadditions_core_marker_wall.png " ,
" worldeditadditions_core_marker_wall.png " ,
}
} ,
on_activate = function ( self , staticdata )
2023-07-01 02:11:56 +02:00
if staticdata ~= last_reset then
2023-07-01 03:46:08 +02:00
-- print("DEBUG:marker_wall/remove staticdata", staticdata, "last_reset", last_reset)
2023-07-01 02:11:56 +02:00
self.object : remove ( )
2023-07-01 03:46:08 +02:00
-- else
-- print("DEBUG:marker_wall/ok staticdata", staticdata, "type", type(staticdata), "last_reset", last_reset, "type", type(last_reset))
2023-07-01 02:11:56 +02:00
end
2023-06-27 22:45:48 +02:00
end ,
on_punch = function ( self , _ )
anchor.delete ( self )
end ,
on_blast = function ( self , damage )
return false , false , { } -- Do not damage or knockback the player
end
}
2023-06-29 01:39:55 +02:00
minetest.register_entity (
" :worldeditadditions:marker_wall " ,
WEAPositionMarkerWall
)
2023-06-27 22:45:48 +02:00
--- Updates the properties of a single wall to match it's side and size
local function single_setup ( entity , size , side )
local new_props = {
2023-06-29 02:22:50 +02:00
visual_size = Vector3.min (
Vector3.new ( 10 , 10 , 10 ) ,
size : abs ( )
)
-- x = math.min(10, math.abs(size.x)),
-- y = math.min(10, math.abs(size.y)),
-- z = math.min(10, math.abs(size.z))
2023-06-27 22:45:48 +02:00
}
local cthick = Vector3.new (
collision_thickness ,
collision_thickness ,
collision_thickness
)
local cpos1 = Vector3.clone ( new_props.visual_size ) : multiply ( - 1 ) : divide ( 2 ) : add ( cthick )
local cpos2 = Vector3.clone ( new_props.visual_size ) : divide ( 2 ) : subtract ( cthick )
if side == " x " or side == " -x " then
2023-06-29 02:22:50 +02:00
new_props.visual_size = new_props.visual_size + Vector3.new (
collision_thickness - 0.1
)
2023-06-27 22:45:48 +02:00
cpos1.x = - collision_thickness
cpos2.x = collision_thickness
end
if side == " y " or side == " -y " then
new_props.visual_size . y = collision_thickness - 0.1
cpos1.y = - collision_thickness
cpos2.y = collision_thickness
end
if side == " z " or side == " -z " then
new_props.visual_size . z = collision_thickness - 0.1
cpos1.z = - collision_thickness
cpos2.z = collision_thickness
end
new_props.collisionbox = {
cpos1.x , cpos1.y , cpos1.z ,
cpos2.x , cpos2.y , cpos2.z
}
2023-06-29 01:39:55 +02:00
2023-07-01 03:46:08 +02:00
-- print("DEBUG:setup_single size", size, "side", side, "new_props", wea_c.inspect(new_props))
2023-06-29 01:39:55 +02:00
2023-06-27 22:45:48 +02:00
entity : set_properties ( new_props )
end
--- Creates a single marker wall entity.
-- @param player_name string The name of the player it should belong to.
-- @param pos1 Vector3 The pos1 corner of the area the SINGLE marker should cover.
-- @param pos2 Vector3 The pos2 corner of the area the SINGLE marker should cover.
-- @param side string The side that this wall is on. Valid values: x, -x, y, -y, z, -z.
-- @returns Entity<WEAPositionMarkerWall>
local function create_single ( player_name , pos1 , pos2 , side )
2023-06-29 01:39:55 +02:00
2023-06-29 02:49:15 +02:00
local pos_centre = ( ( pos2 - pos1 ) / 2 ) + pos1
2023-07-01 02:11:56 +02:00
local entity = minetest.add_entity ( pos_centre , " worldeditadditions:marker_wall " , last_reset )
2023-07-01 03:46:08 +02:00
-- print("DEBUG:marker_wall create_single --> START player_name", player_name, "pos1", pos1, "pos2", pos2, "side", side, "SPAWN", pos_centre, "last_reset", last_reset)
2023-06-27 22:45:48 +02:00
entity : get_luaentity ( ) . player_name = player_name
single_setup ( entity , pos2 - pos1 , side )
return entity
end
--- Creates a marker wall around the defined region.
-- @param player_name string The name of the player that the wall belongs to.
-- @param pos1 Vector3 pos1 of the defined region.
-- @param pos2 Vector3 pos2 of the defined region.
2023-06-30 03:08:46 +02:00
-- @param sides_to_display string The sides of the marker wall that should actually be displayed, squished together into a single string. Defaults to "+x-x+z-z". Use "+x-x+z-z+y-y" to display all sides; add and remove sides as desired.
2023-06-27 22:45:48 +02:00
-- @returns table<entitylist> A list of all created entities.
2023-06-30 03:08:46 +02:00
local function create_wall ( player_name , pos1 , pos2 , sides_to_display )
if not sides_to_display then
sides_to_display = " +x-x+z-z " -- this matches WorldEdit
-- To display all of them:
-- sides_to_display = "+x-x+z-z+y-y"
end
2023-07-01 03:46:08 +02:00
-- print("DEBUG:marker_wall create_wall --> START player_name", player_name, "pos1", pos1, "pos2", pos2)
2023-06-27 22:45:48 +02:00
local pos1s , pos2s = Vector3.sort ( pos1 , pos2 )
local entities = { }
-- local dim1, dim2
-- if side == "x" or side == "-x" then dim1, dim2 = size.z, size.y
-- elseif side == "z" or size == "-z" then dim1, dim2 = size.x, size.y
-- elseif side == "y" or size == "-y" then dim1, dim2 = size.x, size.z
-- end
-- x → z, y
-- z → x, y
-- y → x, z
-- ██ ██
-- ██ ██ ██
-- ██████ ███
-- ██ ██ ██
-- ██ ██
-- First, do positive x
2023-06-30 03:08:46 +02:00
if string.find ( sides_to_display , " +x " ) then
local posx_pos1 = Vector3.new (
math.max ( pos1s.x , pos2s.x ) + 0.5 ,
math.min ( pos1s.y , pos2s.y ) - 0.5 ,
math.min ( pos1s.z , pos2s.z ) - 0.5
)
local posx_pos2 = Vector3.new (
math.max ( pos1s.x , pos2s.x ) + 0.5 ,
math.max ( pos1s.y , pos2s.y ) + 0.5 ,
math.max ( pos1s.z , pos2s.z ) + 0.5
)
2023-07-01 03:46:08 +02:00
-- print("DEBUG ************ +X pos1", posx_pos1, "pos2", posx_pos2)
2023-06-29 02:22:50 +02:00
2023-06-30 03:08:46 +02:00
for z = posx_pos2.z , posx_pos1.z , - entity_wall_size do
for y = posx_pos2.y , posx_pos1.y , - entity_wall_size do
local single_pos1 = Vector3.new (
posx_pos1.x ,
y ,
z
)
local single_pos2 = Vector3.new (
posx_pos1.x ,
math.max ( y - entity_wall_size , posx_pos1.y ) ,
math.max ( z - entity_wall_size , posx_pos1.z )
)
2023-06-29 02:22:50 +02:00
2023-06-30 03:08:46 +02:00
local entity = create_single ( player_name ,
single_pos1 , single_pos2 ,
" x "
)
table.insert ( entities , entity )
end
2023-06-27 22:45:48 +02:00
end
2023-06-30 03:08:46 +02:00
2023-06-27 22:45:48 +02:00
end
2023-06-29 02:22:50 +02:00
-- ██ ██
-- ██ ██
-- ██████ ███
-- ██ ██
-- ██ ██
-- Now, do negative x
2023-06-30 03:08:46 +02:00
if string.find ( sides_to_display , " -x " ) then
local negx_pos1 = Vector3.new (
math.min ( pos1s.x , pos2s.x ) - 0.5 ,
math.min ( pos1s.y , pos2s.y ) - 0.5 ,
math.min ( pos1s.z , pos2s.z ) - 0.5
)
local negx_pos2 = Vector3.new (
math.min ( pos1s.x , pos2s.x ) - 0.5 ,
math.max ( pos1s.y , pos2s.y ) + 0.5 ,
math.max ( pos1s.z , pos2s.z ) + 0.5
)
2023-07-01 03:46:08 +02:00
-- print("DEBUG ************ -X pos1", negx_pos1, "pos2", negx_pos2)
2023-06-29 02:22:50 +02:00
2023-06-30 03:08:46 +02:00
for z = negx_pos2.z , negx_pos1.z , - entity_wall_size do
for y = negx_pos2.y , negx_pos1.y , - entity_wall_size do
local single_pos1 = Vector3.new (
negx_pos1.x ,
y ,
z
)
local single_pos2 = Vector3.new (
negx_pos1.x ,
math.max ( y - entity_wall_size , negx_pos1.y ) ,
math.max ( z - entity_wall_size , negx_pos1.z )
)
2023-06-29 02:22:50 +02:00
2023-06-30 03:08:46 +02:00
local entity = create_single ( player_name ,
single_pos1 , single_pos2 ,
" -x "
)
table.insert ( entities , entity )
end
2023-06-29 02:22:50 +02:00
end
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
end
2023-06-29 02:49:15 +02:00
-- ██ ██
-- ██ ██ ██
-- ██████ ████
-- ██ ██
-- ██
-- Now, positive y
2023-06-30 03:08:46 +02:00
if string.find ( sides_to_display , " +y " ) then
local posy_pos1 = Vector3.new (
math.min ( pos1s.x , pos2s.x ) - 0.5 ,
math.max ( pos1s.y , pos2s.y ) + 0.5 ,
math.min ( pos1s.z , pos2s.z ) - 0.5
)
local posy_pos2 = Vector3.new (
math.max ( pos1s.x , pos2s.x ) + 0.5 ,
math.max ( pos1s.y , pos2s.y ) + 0.5 ,
math.max ( pos1s.z , pos2s.z ) + 0.5
)
2023-06-29 02:49:15 +02:00
2023-07-01 03:46:08 +02:00
-- print("DEBUG ************ +Y pos1", posy_pos1, "pos2", posy_pos2)
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
for z = posy_pos2.z , posy_pos1.z , - entity_wall_size do
for x = posy_pos2.x , posy_pos1.x , - entity_wall_size do
local single_pos1 = Vector3.new (
x ,
posy_pos1.y ,
z
)
local single_pos2 = Vector3.new (
math.max ( x - entity_wall_size , posy_pos1.x ) ,
posy_pos1.y ,
math.max ( z - entity_wall_size , posy_pos1.z )
)
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
local entity = create_single ( player_name ,
single_pos1 , single_pos2 ,
" y "
)
table.insert ( entities , entity )
end
2023-06-29 02:49:15 +02:00
end
2023-06-30 03:08:46 +02:00
2023-06-29 02:49:15 +02:00
end
-- ██ ██
-- ██ ██
-- ██████ ████
-- ██
-- ██
-- Now, negative y
2023-06-30 03:08:46 +02:00
if string.find ( sides_to_display , " -y " ) then
local negy_pos1 = Vector3.new (
math.min ( pos1s.x , pos2s.x ) - 0.5 ,
math.min ( pos1s.y , pos2s.y ) - 0.5 ,
math.min ( pos1s.z , pos2s.z ) - 0.5
)
local negy_pos2 = Vector3.new (
math.max ( pos1s.x , pos2s.x ) + 0.5 ,
math.min ( pos1s.y , pos2s.y ) - 0.5 ,
math.max ( pos1s.z , pos2s.z ) + 0.5
)
2023-06-29 02:49:15 +02:00
2023-07-01 03:46:08 +02:00
-- print("DEBUG ************ -Y pos1", negy_pos1, "pos2", negy_pos2)
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
for z = negy_pos2.z , negy_pos1.z , - entity_wall_size do
for x = negy_pos2.x , negy_pos1.x , - entity_wall_size do
local single_pos1 = Vector3.new (
x ,
negy_pos1.y ,
z
)
local single_pos2 = Vector3.new (
math.max ( x - entity_wall_size , negy_pos1.x ) ,
negy_pos1.y ,
math.max ( z - entity_wall_size , negy_pos1.z )
)
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
local entity = create_single ( player_name ,
single_pos1 , single_pos2 ,
" -y "
)
table.insert ( entities , entity )
end
2023-06-29 02:49:15 +02:00
end
2023-06-30 03:08:46 +02:00
2023-06-29 02:49:15 +02:00
end
-- ███████
-- ██ ███
-- ██████ ███
-- ██ ███
-- ███████
-- Now, positive z. Almost there!
2023-06-30 03:08:46 +02:00
if string.find ( sides_to_display , " +z " ) then
local posz_pos1 = Vector3.new (
math.min ( pos1s.x , pos2s.x ) - 0.5 ,
math.min ( pos1s.y , pos2s.y ) - 0.5 ,
math.max ( pos1s.z , pos2s.z ) + 0.5
)
local posz_pos2 = Vector3.new (
math.max ( pos1s.x , pos2s.x ) + 0.5 ,
math.max ( pos1s.y , pos2s.y ) + 0.5 ,
math.max ( pos1s.z , pos2s.z ) + 0.5
)
2023-06-29 02:49:15 +02:00
2023-07-01 03:46:08 +02:00
-- print("DEBUG ************ +Z pos1", posz_pos1, "pos2", posz_pos2)
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
for x = posz_pos2.x , posz_pos1.x , - entity_wall_size do
for y = posz_pos2.y , posz_pos1.y , - entity_wall_size do
local single_pos1 = Vector3.new (
x ,
y ,
posz_pos1.z
)
local single_pos2 = Vector3.new (
math.max ( x - entity_wall_size , posz_pos1.x ) ,
math.max ( y - entity_wall_size , posz_pos1.y ) ,
posz_pos1.z
)
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
local entity = create_single ( player_name ,
single_pos1 , single_pos2 ,
" z "
)
table.insert ( entities , entity )
end
2023-06-29 02:49:15 +02:00
end
2023-06-30 03:08:46 +02:00
2023-06-29 02:49:15 +02:00
end
2023-06-30 03:08:46 +02:00
2023-06-29 02:49:15 +02:00
-- ███████
-- ███
-- ██████ ███
-- ███
-- ███████
-- Finally, negative z. Last one!
2023-06-30 03:08:46 +02:00
if string.find ( sides_to_display , " -z " ) then
local negz_pos1 = Vector3.new (
math.min ( pos1s.x , pos2s.x ) - 0.5 ,
math.min ( pos1s.y , pos2s.y ) - 0.5 ,
math.min ( pos1s.z , pos2s.z ) - 0.5
)
local negz_pos2 = Vector3.new (
math.max ( pos1s.x , pos2s.x ) + 0.5 ,
math.max ( pos1s.y , pos2s.y ) + 0.5 ,
math.min ( pos1s.z , pos2s.z ) - 0.5
)
2023-06-29 02:49:15 +02:00
2023-07-01 03:46:08 +02:00
-- print("DEBUG ************ -Z pos1", negz_pos1, "pos2", negz_pos2)
2023-06-29 02:49:15 +02:00
2023-06-30 03:08:46 +02:00
for x = negz_pos2.x , negz_pos1.x , - entity_wall_size do
for y = negz_pos2.y , negz_pos1.y , - entity_wall_size do
local single_pos1 = Vector3.new (
x ,
y ,
negz_pos1.z
)
local single_pos2 = Vector3.new (
math.max ( x - entity_wall_size , negz_pos1.x ) ,
math.max ( y - entity_wall_size , negz_pos1.y ) ,
negz_pos1.z
)
2023-06-29 02:22:50 +02:00
2023-06-30 03:08:46 +02:00
local entity = create_single ( player_name ,
single_pos1 , single_pos2 ,
" -z "
)
table.insert ( entities , entity )
end
2023-06-29 02:49:15 +02:00
end
2023-06-30 03:08:46 +02:00
2023-06-29 02:49:15 +02:00
end
2023-06-27 22:45:48 +02:00
-- TODO: All the other sides. For testing we're doing 1 side for now, so we can vaoid having to do everything all over again if we make a mistake.
-- for z = pos2.z, pos1.z, -entity_wall_size do
-- for y = pos2.y, pos1.y, -entity_wall_size do
-- for x = pos2.x, pos1.x, -entity_wall_size do
-- end
-- end
-- end
return entities
end
--- Deletes all entities in the given entity list
-- @param entitylist table<entity> A list of wall entities that make up the wall to delete.
local function delete ( entitylist )
2023-07-01 03:46:08 +02:00
-- print("DEBUG:marker_wall delete --> START with "..#entitylist.." entities")
2023-06-27 22:45:48 +02:00
local player_name
for _ , entity in ipairs ( entitylist ) do
if not entity.get_luaentity or not entity : get_luaentity ( ) then return end -- Ensure the entity is still valid
if not player_name then
player_name = entity : get_luaentity ( ) . player_name
end
2023-06-29 01:39:55 +02:00
entity : remove ( )
2023-06-27 22:45:48 +02:00
end
2023-07-01 02:11:56 +02:00
last_reset = tostring ( wea_c.get_ms_time ( ) )
2023-07-01 03:46:08 +02:00
-- print("DEBUG:marker_wall delete --> LAST_RESET is now", last_reset, "type", type(last_reset))
2023-07-01 02:11:56 +02:00
2023-06-27 22:45:48 +02:00
anchor : emit ( " delete " , {
player_name = player_name
} )
2023-07-01 02:11:56 +02:00
2023-06-27 22:45:48 +02:00
end
anchor = EventEmitter.new ( {
create = create_wall ,
delete = delete
} )
2023-06-29 01:39:55 +02:00
return anchor