From 5505575cf98af9250d91497c905bfe070b439ca1 Mon Sep 17 00:00:00 2001 From: Starbeamrainbowlabs Date: Tue, 18 Jul 2023 00:35:07 +0100 Subject: [PATCH] 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 --- CHANGELOG.md | 3 ++ modpack.conf | 2 +- .../core/entities/pos_marker.lua | 52 ++++++++++++++++--- .../core/entities/pos_marker_wall.lua | 51 ++++++++++++++---- .../core/pos_marker_manage.lua | 10 +++- .../core/pos_marker_wall_manage.lua | 22 ++++++++ 6 files changed, 120 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a4c36c..c60f871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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. +## 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) - Fix crash in `//subdivide`, again due to the new position system diff --git a/modpack.conf b/modpack.conf index 7175566..b5f25e4 100644 --- a/modpack.conf +++ b/modpack.conf @@ -3,4 +3,4 @@ description = Extra tools and commands to extend WorldEdit. Currently has over 2 depends = worldedit optional_depends = bonemeal,cool_trees,default,moretrees,ethereal -min_minetest_version = 5.1 +min_minetest_version = 5.2 diff --git a/worldeditadditions_core/core/entities/pos_marker.lua b/worldeditadditions_core/core/entities/pos_marker.lua index c12b129..aa8ed0c 100644 --- a/worldeditadditions_core/core/entities/pos_marker.lua +++ b/worldeditadditions_core/core/entities/pos_marker.lua @@ -4,6 +4,13 @@ local EventEmitter = worldeditadditions_core.EventEmitter 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 = { initial_properties = { visual = "cube", @@ -11,7 +18,6 @@ local WEAPositionMarker = { collisionbox = { -0.55, -0.55, -0.55, 0.55, 0.55, 0.55 }, physical = false, collide_with_objects = false, - static_save = false, textures = { "worldeditadditions_core_bg.png", @@ -24,25 +30,55 @@ local WEAPositionMarker = { }, 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, on_punch = function(self, _) anchor.delete(self) end, on_blast = function(self, damage) 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 } minetest.register_entity(":worldeditadditions:position", WEAPositionMarker) 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().display_number = display_number + -- entity:get_luaentity().player_name = player_name + -- entity:get_luaentity().display_number = display_number - anchor.set_number(entity, display_number) + -- anchor.set_number(entity, display_number) anchor:emit("create", { player_name = player_name, @@ -53,11 +89,13 @@ local function create(player_name, pos, display_number) end 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 display_number = entity:get_luaentity().display_number + last_reset = make_id() + entity:remove() anchor:emit("delete", { diff --git a/worldeditadditions_core/core/entities/pos_marker_wall.lua b/worldeditadditions_core/core/entities/pos_marker_wall.lua index 4fdbcaf..85ba671 100644 --- a/worldeditadditions_core/core/entities/pos_marker_wall.lua +++ b/worldeditadditions_core/core/entities/pos_marker_wall.lua @@ -7,7 +7,12 @@ local anchor local entity_wall_size = 10 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 = { initial_properties = { @@ -17,7 +22,6 @@ local WEAPositionMarkerWall = { -- ^^ { 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", @@ -30,18 +34,37 @@ local WEAPositionMarkerWall = { }, on_activate = function(self, staticdata) - if staticdata ~= last_reset then - -- print("DEBUG:marker_wall/remove staticdata", staticdata, "last_reset", last_reset) + local data = minetest.parse_json(staticdata) + if type(data) ~= "table" or data.id ~= last_reset then 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._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, on_punch = function(self, _) anchor.delete(self) end, on_blast = function(self, damage) 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 } @@ -109,12 +132,17 @@ local function create_single(player_name, pos1, pos2, side) 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) - 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 end @@ -438,7 +466,7 @@ local function delete(entitylist) entity:remove() 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)) anchor:emit("delete", { @@ -450,7 +478,8 @@ end anchor = EventEmitter.new({ create = create_wall, - delete = delete + delete = delete, + __single_setup = single_setup }) return anchor \ No newline at end of file diff --git a/worldeditadditions_core/core/pos_marker_manage.lua b/worldeditadditions_core/core/pos_marker_manage.lua index 8272292..b355e66 100644 --- a/worldeditadditions_core/core/pos_marker_manage.lua +++ b/worldeditadditions_core/core/pos_marker_manage.lua @@ -109,4 +109,12 @@ wea_c.pos:addEventListener("mark", function(event) pos = pos }) end -end) \ No newline at end of file +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) diff --git a/worldeditadditions_core/core/pos_marker_wall_manage.lua b/worldeditadditions_core/core/pos_marker_wall_manage.lua index 4e6c5da..26041b1 100644 --- a/worldeditadditions_core/core/pos_marker_wall_manage.lua +++ b/worldeditadditions_core/core/pos_marker_wall_manage.lua @@ -53,6 +53,26 @@ local function do_update(event) 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) if event.i > 2 then @@ -73,3 +93,5 @@ weac.pos:addEventListener("clear", do_delete) weac.pos:addEventListener("unmark", do_delete) weac.pos:addEventListener("mark", do_update) + +weac.entities.pos_marker_wall:addEventListener("update_entity", update_entity) \ No newline at end of file