Upgrade position system, add initial position markers

This commit is contained in:
Starbeamrainbowlabs 2022-09-19 23:18:49 +01:00
parent d9877b8c6c
commit 47b1c44b38
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
6 changed files with 190 additions and 14 deletions

View file

@ -0,0 +1,14 @@
-- ███████ ███ ██ ████████ ██ ████████ ██ ███████ ███████
-- ██ ████ ██ ██ ██ ██ ██ ██ ██
-- █████ ██ ██ ██ ██ ██ ██ ██ █████ ███████
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
-- ███████ ██ ████ ██ ██ ██ ██ ███████ ███████
--- Entities and functions to manage them.
-- @namespace worldeditadditions_core.entities
local wea_c = worldeditadditions_core
return {
pos_marker = dofile(wea_c.modpath.."/core/entities/pos_marker.lua"),
}

View file

@ -0,0 +1,81 @@
local wea_c = worldeditadditions_core
local EventEmitter = worldeditadditions_core.EventEmitter
local anchor
local WEAPositionMarker = {
initial_properties = {
visual = "cube",
visual_size = { x = 1.15, y = 1.1 },
collisionbox = { -0.55, -0.55, -0.55, 0.55, 0.55, 0.55 },
physical = false,
collide_with_objects = false,
static_save = false,
textures = {
"worldeditadditions_bg.png",
"worldeditadditions_bg.png",
"worldeditadditions_bg.png",
"worldeditadditions_bg.png",
"worldeditadditions_bg.png",
"worldeditadditions_bg.png",
}
},
on_activate = function(self, staticdata)
-- noop
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
}
minetest.register_entity(":worldeditadditions:position", WEAPositionMarker)
local function create(player_name, pos, display_number)
local entity = minetest.add_entity(pos, "worldeditadditions:position")
entity:get_luaentity().player_name = player_name
entity:get_luaentity().display_number = display_number
anchor.set_number(entity, display_number)
anchor:emit("create", {
player_name = player_name,
pos = pos,
display_number = display_number,
})
return entity
end
local function delete(entity)
local player_name = entity:get_luaentity().player_name
local display_number = entity:get_luaentity().display_number
entity:remove()
anchor:emit("delete", {
player_name = player_name,
display_number = display_number
})
end
local function set_number(entity, display_number)
if type(display_number) ~= "number" then return false, "Error: The 'display_number' property must be of type number, but received value of unexpected type '"..type(display_number).."'." end
-- marker:set_properties({ }) is our friend
print("DEBUG:pos_marker_set_number display_number", display_number)
print("DEBUG:pos_marker_set_number TODO_IMPLEMENT THIS. entity", wea_c.inspect(entity))
end
anchor = EventEmitter.new({
create = create,
delete = delete,
set_number = set_number
})
return anchor

View file

@ -2,8 +2,16 @@ local wea_c = worldeditadditions_core
local positions_count_limit = 999 local positions_count_limit = 999
local positions = {} local positions = {}
--- 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.
local anchor = nil local anchor = nil
--- Ensures that a table exists for the given player.
-- @param player_name string The name of the player to check.
local function ensure_player(player_name) local function ensure_player(player_name)
if player_name == nil then if player_name == nil then
minetest.log("error", "[wea core:pos:ensure_player] player_name is nil") minetest.log("error", "[wea core:pos:ensure_player] player_name is nil")
@ -15,55 +23,91 @@ end
--- Gets the position with the given index for the given player. --- 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. -- @param player_name string The name of the player to fetch the position for.
-- @param -- @param i number The index of the position to fetch.
-- @returns Vector3? The position requested, or nil if it doesn't exist.
local function get_pos(player_name, i) local function get_pos(player_name, i)
ensure_player(player_name) ensure_player(player_name)
return positions[player_name][i] return positions[player_name][i]
end end
--- 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.
local function get_pos1(player_name) return get_pos(player_name, 1) end local function get_pos1(player_name) return get_pos(player_name, 1) end
--- 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.
local function get_pos2(player_name) return get_pos(player_name, 2) end local function get_pos2(player_name) return get_pos(player_name, 2) end
--- 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.
local function get_pos_all(player_name) local function get_pos_all(player_name)
ensure_player(player_name) ensure_player(player_name)
return positions[player_name] return wea_c.table.deepcopy(positions[player_name])
end end
--- 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.
local function pos_count(player_name) local function pos_count(player_name)
ensure_player(player_name) ensure_player(player_name)
return #positions[player_name] return #positions[player_name]
end end
--- 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).
local function set_pos(player_name, i, pos) local function set_pos(player_name, i, pos)
if i > positions_count_limit then return false end if i > positions_count_limit then return false end
ensure_player(player_name) ensure_player(player_name)
positions[player_name][i] = pos positions[player_name][i] = pos
anchor:emit("set", { i = i, pos = pos }) anchor:emit("set", { player_name = player_name, i = i, pos = pos })
return true return true
end end
local function set_pos_all(player_name, i, pos_list) --- 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)
if #pos_list > positions_count_limit then return false end if #pos_list > positions_count_limit then return false end
positions[player_name] = pos_list positions[player_name] = pos_list
for _i,pos_new in ipairs(positions[player_name]) do for i,pos_new in ipairs(positions[player_name]) do
anchor:emit("push", { pos = pos_new }) anchor:emit("push", { player_name = player_name, pos = pos_new, i = i })
end end
return true
end end
--- Clears all the positions for the given player.
-- @param player_name string The name of the player to clear the positions for.
-- @returns void
local function clear(player_name) local function clear(player_name)
if positions[player_name] then if positions[player_name] then
positions[player_name] = nil positions[player_name] = nil
end end
anchor:emit("clear") anchor:emit("clear", { player_name = player_name })
end end
--- 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.
local function pop_pos(player_name) local function pop_pos(player_name)
ensure_player(player_name) ensure_player(player_name)
if #positions[player_name] <= 0 then return nil end if #positions[player_name] <= 0 then return nil end
local count = #positions[player_name]
local last_pos = table.remove(positions[player_name]) local last_pos = table.remove(positions[player_name])
anchor:emit("pop", { pos = last_pos }) anchor:emit("pop", { player_name = player_name, pos = last_pos, i = count })
return last_pos return last_pos
end end
--- 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.
local function push_pos(player_name, pos) local function push_pos(player_name, pos)
ensure_player(player_name) ensure_player(player_name)
table.insert(positions[player_name], pos) table.insert(positions[player_name], pos)
anchor:emit("push", { pos = pos }) anchor:emit("push", { player_name = player_name, pos = pos, i = #positions[player_name] })
return #positions[player_name]
end end

View file

@ -0,0 +1,36 @@
local wea_c = worldeditadditions_core
local position_entities = {}
--- Ensures that a table exists for the given player.
-- @param player_name string The name of the player to check.
local function ensure_player(player_name)
if player_name == nil then
minetest.log("error", "[wea core:pos_manage:ensure_player] player_name is nil")
end
if not position_entities[player_name] then
position_entities[player_name] = {}
end
end
wea_c.pos:addEventListener("push", function(event)
ensure_player(event.player_name)
local new_entity = wea_c.entities.pos_marker.create(
event.player_name,
event.pos,
event.i
)
position_entities[event.player_name][event.i] = new_entity
end)
wea_c.pos:addEventListener("pop", function(event)
ensure_player(event.player_name)
print("pos manage: pop", wea_c.inspect(event))
if not position_entities[event.player_name][event.i] then return end
wea_c.entities.pos_marker.delete(
position_entities[event.player_name][event.i]
)
position_entities[event.player_name][event.i] = nil
end)

View file

@ -58,11 +58,12 @@ dofile(wea_c.modpath.."/utils/player.lua") -- Player info functions
wea_c.pos = dofile(modpath.."/core/pos.lua") wea_c.pos = dofile(modpath.."/core/pos.lua") -- AFTER EventEmitter
wea_c.register_command = dofile(modpath.."/core/register_command.lua") wea_c.register_command = dofile(modpath.."/core/register_command.lua")
wea_c.fetch_command_def = dofile(modpath.."/core/fetch_command_def.lua") wea_c.fetch_command_def = dofile(modpath.."/core/fetch_command_def.lua")
wea_c.register_alias = dofile(modpath.."/core/register_alias.lua") wea_c.register_alias = dofile(modpath.."/core/register_alias.lua")
print("WEA_C pos", wea_c.pos.push) wea_c.entities = dofile(modpath.."/core/entities/init.lua") -- AFTER pos
dofile(modpath.."/core/pos_marker_manage.lua") -- AFTER pos, entities
-- Initialise WorldEdit stuff if the WorldEdit mod is not present -- Initialise WorldEdit stuff if the WorldEdit mod is not present
if minetest.global_exists("worldedit") then if minetest.global_exists("worldedit") then

View file

@ -1,6 +1,6 @@
--- Event manager object. --- Event manager object.
-- @class -- @class worldeditadditions_core.EventEmitter
local EventEmitter = {} local EventEmitter = {}
EventEmitter.__index = EventEmitter EventEmitter.__index = EventEmitter
EventEmitter.__name = "EventEmitter" -- A hack to allow identification in wea.inspect EventEmitter.__name = "EventEmitter" -- A hack to allow identification in wea.inspect
@ -18,7 +18,7 @@ end
--- Add a new listener to the given named event. --- Add a new listener to the given named event.
-- @param this EventEmitter The EventEmitter instance to add the listener to. -- @param this EventEmitter The EventEmitter instance to add the listener to.
-- @param event_name string The name of the event to listen on. -- @param event_name string The name of the event to listen on.
-- @param func function The callback function to call when the event is emitted. -- @param func function The callback function to call when the event is emitted. Will be passed a single argument - the object passed as the second argument to .emit().
-- @returns number The number of listeners attached to that event. -- @returns number The number of listeners attached to that event.
function EventEmitter.addEventListener(this, event_name, func) function EventEmitter.addEventListener(this, event_name, func)
if this.events[event_name] == nil then this.events[event_name] = {} end if this.events[event_name] == nil then this.events[event_name] = {} end