Fix regions not remembering their state and being unresettable

This fix means that wwe require minetest 5.2 as a minimum rather than 5.1
ref https://rubenwardy.com/minetest_modding_book/en/quality/common_mistakes.html#be-careful-when-storing-objectrefs-ie-players-or-entities
This commit is contained in:
Starbeamrainbowlabs 2023-07-18 00:35:07 +01:00
parent fd3ee43728
commit 5505575cf9
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
6 changed files with 120 additions and 20 deletions

View file

@ -4,6 +4,9 @@ It's about time I started a changelog! This will serve from now on as the main c
Note to self: See the bottom of this file for the release template text. Note to self: See the bottom of this file for the release template text.
## v1.14.3: The multipoint update, hotfix 3 (18th July 2023)
- Fix regions not remembering their state and being unresettable
## v1.14.2: The multipoint update, hotfix 2 (15th July 2023) ## v1.14.2: The multipoint update, hotfix 2 (15th July 2023)
- Fix crash in `//subdivide`, again due to the new position system - Fix crash in `//subdivide`, again due to the new position system

View file

@ -3,4 +3,4 @@ description = Extra tools and commands to extend WorldEdit. Currently has over 2
depends = worldedit depends = worldedit
optional_depends = bonemeal,cool_trees,default,moretrees,ethereal optional_depends = bonemeal,cool_trees,default,moretrees,ethereal
min_minetest_version = 5.1 min_minetest_version = 5.2

View file

@ -4,6 +4,13 @@ local EventEmitter = worldeditadditions_core.EventEmitter
local anchor local anchor
local function make_id()
return tostring(wea_c.get_ms_time()) .. "_" .. tostring(math.floor(math.random() * 1000000))
end
local last_reset = make_id()
local WEAPositionMarker = { local WEAPositionMarker = {
initial_properties = { initial_properties = {
visual = "cube", visual = "cube",
@ -11,7 +18,6 @@ local WEAPositionMarker = {
collisionbox = { -0.55, -0.55, -0.55, 0.55, 0.55, 0.55 }, collisionbox = { -0.55, -0.55, -0.55, 0.55, 0.55, 0.55 },
physical = false, physical = false,
collide_with_objects = false, collide_with_objects = false,
static_save = false,
textures = { textures = {
"worldeditadditions_core_bg.png", "worldeditadditions_core_bg.png",
@ -24,25 +30,55 @@ local WEAPositionMarker = {
}, },
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
-- noop local data = minetest.parse_json(staticdata)
if type(data) ~= "table" or data.id ~= last_reset then
-- print("DEBUG:marker_wall/remove staticdata", staticdata, "last_reset", last_reset)
self.object:remove()
-- else
-- print("DEBUG:marker_wall/ok staticdata", staticdata, "type", type(staticdata), "last_reset", last_reset, "type", type(last_reset))
return
end
self.__id = data.id
self.player_name = data.player_name
self.display_number = data.display_number
anchor:emit("update_entity", {
entity = self.object,
id = self.__id,
player_name = self.player_name,
i = self.display_number
})
anchor.set_number(self.object, self.display_number)
end, end,
on_punch = function(self, _) on_punch = function(self, _)
anchor.delete(self) anchor.delete(self)
end, end,
on_blast = function(self, damage) on_blast = function(self, damage)
return false, false, {} -- Do not damage or knockback the player return false, false, {} -- Do not damage or knockback the player
end,
get_staticdata = function(self)
return minetest.write_json({
id = self.__id,
display_number = self.display_number,
player_name = self.player_name
})
end end
} }
minetest.register_entity(":worldeditadditions:position", WEAPositionMarker) minetest.register_entity(":worldeditadditions:position", WEAPositionMarker)
local function create(player_name, pos, display_number) local function create(player_name, pos, display_number)
local entity = minetest.add_entity(pos, "worldeditadditions:position") local entity = minetest.add_entity(pos, "worldeditadditions:position", minetest.write_json({
id = last_reset,
display_number = display_number,
player_name = player_name
}))
entity:get_luaentity().player_name = player_name -- entity:get_luaentity().player_name = player_name
entity:get_luaentity().display_number = display_number -- entity:get_luaentity().display_number = display_number
anchor.set_number(entity, display_number) -- anchor.set_number(entity, display_number)
anchor:emit("create", { anchor:emit("create", {
player_name = player_name, player_name = player_name,
@ -53,11 +89,13 @@ local function create(player_name, pos, display_number)
end end
local function delete(entity) local function delete(entity)
if not entity.get_luaentity or not entity:get_luaentity() then return end -- Ensure the entity is still valid if not entity or not entity.get_luaentity or not entity:get_luaentity() then return end -- Ensure the entity is still valid
local player_name = entity:get_luaentity().player_name local player_name = entity:get_luaentity().player_name
local display_number = entity:get_luaentity().display_number local display_number = entity:get_luaentity().display_number
last_reset = make_id()
entity:remove() entity:remove()
anchor:emit("delete", { anchor:emit("delete", {

View file

@ -7,7 +7,12 @@ local anchor
local entity_wall_size = 10 local entity_wall_size = 10
local collision_thickness = 0.2 local collision_thickness = 0.2
local last_reset = tostring(wea_c.get_ms_time()) local function make_id()
return tostring(wea_c.get_ms_time()) .. "_" .. tostring(math.floor(math.random() * 1000000))
end
local last_reset = make_id()
local WEAPositionMarkerWall = { local WEAPositionMarkerWall = {
initial_properties = { initial_properties = {
@ -17,7 +22,6 @@ local WEAPositionMarkerWall = {
-- ^^ { xmin, ymin, zmin, xmax, ymax, zmax } relative to obj pos -- ^^ { xmin, ymin, zmin, xmax, ymax, zmax } relative to obj pos
physical = false, physical = false,
collide_with_objects = false, collide_with_objects = false,
static_save = false,
textures = { textures = {
"worldeditadditions_core_marker_wall.png", "worldeditadditions_core_marker_wall.png",
@ -30,18 +34,37 @@ local WEAPositionMarkerWall = {
}, },
on_activate = function(self, staticdata) on_activate = function(self, staticdata)
if staticdata ~= last_reset then local data = minetest.parse_json(staticdata)
-- print("DEBUG:marker_wall/remove staticdata", staticdata, "last_reset", last_reset) if type(data) ~= "table" or data.id ~= last_reset then
self.object:remove() self.object:remove()
-- else return
-- print("DEBUG:marker_wall/ok staticdata", staticdata, "type", type(staticdata), "last_reset", last_reset, "type", type(last_reset))
end end
self.__id = data.id
self._size = Vector3.clone(data.size)
self._side = data.side
self.player_name = data.player_name
anchor.__single_setup(self.object, self._size, self._side)
anchor:emit("update_entity", {
entity = self.object,
player_name = self.player_name
})
end, end,
on_punch = function(self, _) on_punch = function(self, _)
anchor.delete(self) anchor.delete(self)
end, end,
on_blast = function(self, damage) on_blast = function(self, damage)
return false, false, {} -- Do not damage or knockback the player return false, false, {} -- Do not damage or knockback the player
end,
get_staticdata = function(self)
return minetest.write_json({
id = self.__id,
size = self._size,
side = self._side,
player_name = self.player_name
})
end end
} }
@ -109,12 +132,17 @@ local function create_single(player_name, pos1, pos2, side)
local pos_centre = ((pos2 - pos1) / 2) + pos1 local pos_centre = ((pos2 - pos1) / 2) + pos1
local entity = minetest.add_entity(pos_centre, "worldeditadditions:marker_wall", last_reset) local entity = minetest.add_entity(pos_centre, "worldeditadditions:marker_wall", minetest.write_json({
id = last_reset,
size = pos2 - pos1,
side = side,
player_name = player_name
}))
-- print("DEBUG:marker_wall create_single --> START player_name", player_name, "pos1", pos1, "pos2", pos2, "side", side, "SPAWN", pos_centre, "last_reset", last_reset) -- print("DEBUG:marker_wall create_single --> START player_name", player_name, "pos1", pos1, "pos2", pos2, "side", side, "SPAWN", pos_centre, "last_reset", last_reset)
entity:get_luaentity().player_name = player_name -- entity:get_luaentity().player_name = player_name
single_setup(entity, pos2 - pos1, side) -- single_setup(entity, pos2 - pos1, side)
return entity return entity
end end
@ -438,7 +466,7 @@ local function delete(entitylist)
entity:remove() entity:remove()
end end
last_reset = tostring(wea_c.get_ms_time()) last_reset = make_id()
-- print("DEBUG:marker_wall delete --> LAST_RESET is now", last_reset, "type", type(last_reset)) -- print("DEBUG:marker_wall delete --> LAST_RESET is now", last_reset, "type", type(last_reset))
anchor:emit("delete", { anchor:emit("delete", {
@ -450,7 +478,8 @@ end
anchor = EventEmitter.new({ anchor = EventEmitter.new({
create = create_wall, create = create_wall,
delete = delete delete = delete,
__single_setup = single_setup
}) })
return anchor return anchor

View file

@ -109,4 +109,12 @@ wea_c.pos:addEventListener("mark", function(event)
pos = pos pos = pos
}) })
end end
end) end)
wea_c.entities.pos_marker:addEventListener("update_entity", function(event)
wea_c.entities.pos_marker.delete(
position_entities[event.player_name][event.i]
)
position_entities[event.player_name][event.i] = event.entity
end)

View file

@ -53,6 +53,26 @@ local function do_update(event)
end end
local function garbage_collect(player_name)
if not wall_entity_lists[player_name] then return end -- Nothing to do
for i, entity in ipairs(wall_entity_lists[player_name]) do
if not entity:get_pos() then
table.remove(wall_entity_lists[player_name], i)
end
end
end
local function update_entity(event)
print("DEBUG:pos_marker_wall_manage UPDATE_ENTITY event", weac.inspect(event))
garbage_collect(event.player_name)
ensure_player(event.player_name)
table.insert(
wall_entity_lists[event.player_name],
event.entity
)
end
local function needs_update(event) local function needs_update(event)
if event.i > 2 then if event.i > 2 then
@ -73,3 +93,5 @@ weac.pos:addEventListener("clear", do_delete)
weac.pos:addEventListener("unmark", do_delete) weac.pos:addEventListener("unmark", do_delete)
weac.pos:addEventListener("mark", do_update) weac.pos:addEventListener("mark", do_update)
weac.entities.pos_marker_wall:addEventListener("update_entity", update_entity)