mirror of
https://github.com/minetest-mods/digtron.git
synced 2025-01-03 09:37:27 +01:00
collectgarbage hammer fix, and add some asserts to crash before corrupting anything in impossible situations.
This commit is contained in:
parent
03beff0d33
commit
8ea6d7eb70
@ -16,8 +16,20 @@ local get_node_image = function(pos, node)
|
|||||||
node_image.meta.fields.formspec = node_def._digtron_formspec(pos, meta) -- causes formspec to be automatically upgraded whenever Digtron moves
|
node_image.meta.fields.formspec = node_def._digtron_formspec(pos, meta) -- causes formspec to be automatically upgraded whenever Digtron moves
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local group = minetest.get_item_group(node.name, "digtron")
|
||||||
|
-- group 1 has no special metadata
|
||||||
|
if group > 1 and group < 10 then
|
||||||
|
assert(node_image ~= nil and node_image.meta ~= nil, "[Digtron] Digtron failed to get a metadata table for a Digtron node in group "
|
||||||
|
.. tostring(group) .. ". This error should not be possible. Please see https://github.com/minetest/minetest/issues/8067")
|
||||||
|
-- These groups have inventories
|
||||||
|
if group == 2 or (group > 3 and group < 8) then
|
||||||
|
assert(node_image.meta.inventory ~= nil, "[Digtron] Digtron failed to get a metadata inventory table for a Digtron node in group "
|
||||||
|
.. tostring(group) .. ". This error should not be possible. Please see https://github.com/minetest/minetest/issues/8067")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Record what kind of thing we've got in a builder node so its facing can be rotated properly
|
-- Record what kind of thing we've got in a builder node so its facing can be rotated properly
|
||||||
if minetest.get_item_group(node.name, "digtron") == 4 then
|
if group == 4 then
|
||||||
local build_item = ""
|
local build_item = ""
|
||||||
if node_image.meta.inventory.main then
|
if node_image.meta.inventory.main then
|
||||||
build_item = node_image.meta.inventory.main[1]
|
build_item = node_image.meta.inventory.main[1]
|
||||||
@ -37,13 +49,13 @@ local to_test = Pointset.create()
|
|||||||
local tested = Pointset.create()
|
local tested = Pointset.create()
|
||||||
|
|
||||||
function DigtronLayout.create(pos, player)
|
function DigtronLayout.create(pos, player)
|
||||||
|
collectgarbage()
|
||||||
local self = {}
|
local self = {}
|
||||||
setmetatable(self, DigtronLayout)
|
setmetatable(self, DigtronLayout)
|
||||||
|
|
||||||
--initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
|
--initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
|
||||||
self.traction = 0
|
self.traction = 0
|
||||||
self.all = {}
|
self.all = {}
|
||||||
self.extents = {}
|
|
||||||
self.water_touching = false
|
self.water_touching = false
|
||||||
self.lava_touching = false
|
self.lava_touching = false
|
||||||
self.protected = Pointset.create() -- if any nodes we look at are protected, make note of that. That way we don't need to keep re-testing protection state later.
|
self.protected = Pointset.create() -- if any nodes we look at are protected, make note of that. That way we don't need to keep re-testing protection state later.
|
||||||
@ -54,12 +66,12 @@ function DigtronLayout.create(pos, player)
|
|||||||
|
|
||||||
table.insert(self.all, get_node_image(pos, minetest.get_node(pos))) -- We never visit the source node, so insert it into the all table a priori. Revisit this design decision if a controller node is created that contains fuel or inventory or whatever.
|
table.insert(self.all, get_node_image(pos, minetest.get_node(pos))) -- We never visit the source node, so insert it into the all table a priori. Revisit this design decision if a controller node is created that contains fuel or inventory or whatever.
|
||||||
|
|
||||||
self.extents.max_x = pos.x
|
self.extents_max_x = pos.x
|
||||||
self.extents.min_x = pos.x
|
self.extents_min_x = pos.x
|
||||||
self.extents.max_y = pos.y
|
self.extents_max_y = pos.y
|
||||||
self.extents.min_y = pos.y
|
self.extents_min_y = pos.y
|
||||||
self.extents.max_z = pos.z
|
self.extents_max_z = pos.z
|
||||||
self.extents.min_z = pos.z
|
self.extents_min_z = pos.z
|
||||||
|
|
||||||
tested:set(pos.x, pos.y, pos.z, true)
|
tested:set(pos.x, pos.y, pos.z, true)
|
||||||
to_test:set(pos.x + 1, pos.y, pos.z, true)
|
to_test:set(pos.x + 1, pos.y, pos.z, true)
|
||||||
@ -143,12 +155,12 @@ function DigtronLayout.create(pos, player)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- update extents
|
-- update extents
|
||||||
self.extents.max_x = math.max(self.extents.max_x, testpos.x)
|
self.extents_max_x = math.max(self.extents_max_x, testpos.x)
|
||||||
self.extents.min_x = math.min(self.extents.min_x, testpos.x)
|
self.extents_min_x = math.min(self.extents_min_x, testpos.x)
|
||||||
self.extents.max_y = math.max(self.extents.max_y, testpos.y)
|
self.extents_max_y = math.max(self.extents_max_y, testpos.y)
|
||||||
self.extents.min_y = math.min(self.extents.min_y, testpos.y)
|
self.extents_min_y = math.min(self.extents_min_y, testpos.y)
|
||||||
self.extents.max_z = math.max(self.extents.max_z, testpos.z)
|
self.extents_max_z = math.max(self.extents_max_z, testpos.z)
|
||||||
self.extents.min_z = math.min(self.extents.min_z, testpos.z)
|
self.extents_min_z = math.min(self.extents_min_z, testpos.z)
|
||||||
|
|
||||||
--queue up potential new test points adjacent to this digtron node
|
--queue up potential new test points adjacent to this digtron node
|
||||||
to_test:set_if_not_in(tested, testpos.x + 1, testpos.y, testpos.z, true)
|
to_test:set_if_not_in(tested, testpos.x + 1, testpos.y, testpos.z, true)
|
||||||
@ -302,6 +314,12 @@ local top = {
|
|||||||
}
|
}
|
||||||
-- Rotates 90 degrees widdershins around the axis defined by facedir (which in this case is pointing out the front of the node, so it needs to be converted into an upward-pointing axis internally)
|
-- Rotates 90 degrees widdershins around the axis defined by facedir (which in this case is pointing out the front of the node, so it needs to be converted into an upward-pointing axis internally)
|
||||||
function DigtronLayout.rotate_layout_image(self, facedir)
|
function DigtronLayout.rotate_layout_image(self, facedir)
|
||||||
|
|
||||||
|
if self == nil or self.all == nil or self.controller == nil or self.old_pos_pointset == nil then
|
||||||
|
-- this should not be possible, but if it is then abort.
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
-- To convert this into the direction the "top" of the axle node is pointing in:
|
-- To convert this into the direction the "top" of the axle node is pointing in:
|
||||||
-- 0, 1, 2, 3 == (0,1,0)
|
-- 0, 1, 2, 3 == (0,1,0)
|
||||||
-- 4, 5, 6, 7 == (0,0,1)
|
-- 4, 5, 6, 7 == (0,0,1)
|
||||||
@ -322,14 +340,12 @@ end
|
|||||||
-- Translation
|
-- Translation
|
||||||
|
|
||||||
function DigtronLayout.move_layout_image(self, dir)
|
function DigtronLayout.move_layout_image(self, dir)
|
||||||
local extents = self.extents
|
self.extents_max_x = self.extents_max_x + dir.x
|
||||||
|
self.extents_min_x = self.extents_min_x + dir.x
|
||||||
extents.max_x = extents.max_x + dir.x
|
self.extents_max_y = self.extents_max_y + dir.y
|
||||||
extents.min_x = extents.min_x + dir.x
|
self.extents_min_y = self.extents_min_y + dir.y
|
||||||
extents.max_y = extents.max_y + dir.y
|
self.extents_max_z = self.extents_max_z + dir.z
|
||||||
extents.min_y = extents.min_y + dir.y
|
self.extents_min_z = self.extents_min_z + dir.z
|
||||||
extents.max_z = extents.max_z + dir.z
|
|
||||||
extents.min_z = extents.min_z + dir.z
|
|
||||||
|
|
||||||
for k, node_image in pairs(self.all) do
|
for k, node_image in pairs(self.all) do
|
||||||
self.old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
self.old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
||||||
|
@ -43,7 +43,10 @@ minetest.register_node("digtron:axle", {
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local image = DigtronLayout.create(pos, clicker)
|
local image = DigtronLayout.create(pos, clicker)
|
||||||
image:rotate_layout_image(node.param2)
|
if image:rotate_layout_image(node.param2) == false then
|
||||||
|
-- This should be impossible, but if self-validation fails abort.
|
||||||
|
return
|
||||||
|
end
|
||||||
if image:can_write_layout_image() then
|
if image:can_write_layout_image() then
|
||||||
if image:write_layout_image(clicker) then
|
if image:write_layout_image(clicker) then
|
||||||
minetest.sound_play("whirr", {gain=1.0, pos=pos})
|
minetest.sound_play("whirr", {gain=1.0, pos=pos})
|
||||||
|
@ -72,9 +72,9 @@ end
|
|||||||
-- Checks if a player is within a layout's extents.
|
-- Checks if a player is within a layout's extents.
|
||||||
local function move_player_test(layout, player)
|
local function move_player_test(layout, player)
|
||||||
local player_pos = player:getpos()
|
local player_pos = player:getpos()
|
||||||
if player_pos.x >= layout.extents.min_x - 1 and player_pos.x <= layout.extents.max_x + 1 and
|
if player_pos.x >= layout.extents_min_x - 1 and player_pos.x <= layout.extents_max_x + 1 and
|
||||||
player_pos.y >= layout.extents.min_y - 1 and player_pos.y <= layout.extents.max_y + 1 and
|
player_pos.y >= layout.extents_min_y - 1 and player_pos.y <= layout.extents_max_y + 1 and
|
||||||
player_pos.z >= layout.extents.min_z - 1 and player_pos.z <= layout.extents.max_z + 1 then
|
player_pos.z >= layout.extents_min_z - 1 and player_pos.z <= layout.extents_max_z + 1 then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
|
Loading…
Reference in New Issue
Block a user