mirror of
https://github.com/minetest-mods/digtron.git
synced 2024-08-20 04:44:05 +02:00
add can-build check to rotation
This commit is contained in:
parent
e63f016fc3
commit
8ecc738f44
@ -347,9 +347,9 @@ minetest.register_node("digtron:controller", {
|
|||||||
end
|
end
|
||||||
|
|
||||||
if target_pos then
|
if target_pos then
|
||||||
local success, succeeded, failed = digtron.is_buildable_to(digtron_id, target_pos, player_name)
|
local success, succeeded, failed = digtron.is_buildable_to(digtron_id, nil, target_pos, player_name)
|
||||||
if success then
|
if success then
|
||||||
digtron.build_to_world(digtron_id, target_pos, player_name)
|
digtron.build_to_world(digtron_id, nil, target_pos, player_name)
|
||||||
minetest.sound_play("digtron_machine_assemble", {gain = 0.5, pos=target_pos})
|
minetest.sound_play("digtron_machine_assemble", {gain = 0.5, pos=target_pos})
|
||||||
-- Note: DO NOT RESPECT CREATIVE MODE here.
|
-- Note: DO NOT RESPECT CREATIVE MODE here.
|
||||||
-- If we allow multiple copies of a Digtron running around with the same digtron_id,
|
-- If we allow multiple copies of a Digtron running around with the same digtron_id,
|
||||||
|
@ -504,21 +504,18 @@ digtron.remove_from_world = function(digtron_id, player_name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Tests if a Digtron can be built at the designated location
|
-- Tests if a Digtron can be built at the designated location
|
||||||
digtron.is_buildable_to = function(digtron_id, root_pos, player_name, ignore_nodes, return_immediately_on_failure)
|
digtron.is_buildable_to = function(digtron_id, layout, root_pos, player_name, ignore_nodes, return_immediately_on_failure)
|
||||||
local layout = retrieve_layout(digtron_id)
|
|
||||||
if layout == nil then
|
|
||||||
minetest.log("error", "[Digtron] digtron.is_buildable_to called by " .. player_name
|
|
||||||
.. " for " .. digtron_id .. " at " .. minetest.pos_to_string(root_pos) .. " but no layout "
|
|
||||||
.. "could be retrieved.")
|
|
||||||
return false, {}, {}
|
|
||||||
end
|
|
||||||
|
|
||||||
-- If this digtron is already in-world, we're likely testing as part of a movement attempt.
|
-- If this digtron is already in-world, we're likely testing as part of a movement attempt.
|
||||||
-- Record its existing node locations, they will be treated as buildable_to
|
-- Record its existing node locations, they will be treated as buildable_to
|
||||||
local old_root_pos = retrieve_pos(digtron_id)
|
local old_root_pos = retrieve_pos(digtron_id)
|
||||||
|
local old_layout = retrieve_layout(digtron_id)
|
||||||
|
if layout == nil then
|
||||||
|
layout = old_layout
|
||||||
|
end
|
||||||
|
|
||||||
local ignore_hashes = {}
|
local ignore_hashes = {}
|
||||||
if old_root_pos then
|
if old_root_pos then
|
||||||
for hash, _ in pairs(layout) do
|
for hash, _ in pairs(old_layout) do
|
||||||
local old_hash = minetest.hash_node_position(vector.add(minetest.get_position_from_hash(hash), old_root_pos))
|
local old_hash = minetest.hash_node_position(vector.add(minetest.get_position_from_hash(hash), old_root_pos))
|
||||||
ignore_hashes[old_hash] = true
|
ignore_hashes[old_hash] = true
|
||||||
end
|
end
|
||||||
@ -560,9 +557,10 @@ digtron.is_buildable_to = function(digtron_id, root_pos, player_name, ignore_nod
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Places the Digtron into the world.
|
-- Places the Digtron into the world.
|
||||||
digtron.build_to_world = function(digtron_id, root_pos, player_name)
|
digtron.build_to_world = function(digtron_id, layout, root_pos, player_name)
|
||||||
local layout = retrieve_layout(digtron_id)
|
if layout == nil then
|
||||||
|
layout = retrieve_layout(digtron_id)
|
||||||
|
end
|
||||||
for hash, data in pairs(layout) do
|
for hash, data in pairs(layout) do
|
||||||
-- Don't use get_valid_data, the Digtron isn't in-world yet
|
-- Don't use get_valid_data, the Digtron isn't in-world yet
|
||||||
local node_pos = vector.add(minetest.get_position_from_hash(hash), root_pos)
|
local node_pos = vector.add(minetest.get_position_from_hash(hash), root_pos)
|
||||||
@ -580,10 +578,11 @@ digtron.build_to_world = function(digtron_id, root_pos, player_name)
|
|||||||
end
|
end
|
||||||
|
|
||||||
digtron.move = function(digtron_id, dest_pos, player_name)
|
digtron.move = function(digtron_id, dest_pos, player_name)
|
||||||
local permitted, succeeded, failed = digtron.is_buildable_to(digtron_id, dest_pos, player_name)
|
local layout = retrieve_layout(digtron_id)
|
||||||
|
local permitted, succeeded, failed = digtron.is_buildable_to(digtron_id, layout, dest_pos, player_name)
|
||||||
if permitted then
|
if permitted then
|
||||||
local removed = digtron.remove_from_world(digtron_id, player_name)
|
local removed = digtron.remove_from_world(digtron_id, player_name)
|
||||||
digtron.build_to_world(digtron_id, dest_pos, player_name)
|
digtron.build_to_world(digtron_id, layout, dest_pos, player_name)
|
||||||
minetest.sound_play("digtron_truck", {gain = 0.5, pos=dest_pos})
|
minetest.sound_play("digtron_truck", {gain = 0.5, pos=dest_pos})
|
||||||
for _, removed_pos in ipairs(removed) do
|
for _, removed_pos in ipairs(removed) do
|
||||||
minetest.check_for_falling(removed_pos)
|
minetest.check_for_falling(removed_pos)
|
||||||
@ -599,28 +598,41 @@ end
|
|||||||
------------------------------------------------------------------------
|
------------------------------------------------------------------------
|
||||||
-- Rotation
|
-- Rotation
|
||||||
|
|
||||||
|
local function deep_copy(table_in)
|
||||||
|
local table_out = {}
|
||||||
|
for index, value in pairs(table_in) do
|
||||||
|
if type(value) == "table" then
|
||||||
|
table_out[index] = deep_copy(value)
|
||||||
|
else
|
||||||
|
table_out[index] = value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return table_out
|
||||||
|
end
|
||||||
|
|
||||||
local rotate_layout = function(digtron_id, axis)
|
local rotate_layout = function(digtron_id, axis)
|
||||||
local layout = retrieve_layout(digtron_id)
|
local layout = retrieve_layout(digtron_id)
|
||||||
local axis_hash = minetest.hash_node_position(axis)
|
local axis_hash = minetest.hash_node_position(axis)
|
||||||
local rotated_layout = {}
|
local rotated_layout = {}
|
||||||
for hash, data in pairs(layout) do
|
for hash, data in pairs(layout) do
|
||||||
|
local duplicate_data = deep_copy(data)
|
||||||
-- Facings
|
-- Facings
|
||||||
local node_name = data.node.name
|
local node_name = duplicate_data.node.name
|
||||||
local node_def = minetest.registered_nodes[node_name]
|
local node_def = minetest.registered_nodes[node_name]
|
||||||
if node_def.paramtype2 == "wallmounted" then
|
if node_def.paramtype2 == "wallmounted" then
|
||||||
data.node.param2 = digtron.rotate_wallmounted(axis_hash, data.node.param2)
|
duplicate_data.node.param2 = digtron.rotate_wallmounted(axis_hash, duplicate_data.node.param2)
|
||||||
elseif node_def.paramtype2 == "facedir" then
|
elseif node_def.paramtype2 == "facedir" then
|
||||||
data.node.param2 = digtron.rotate_facedir(axis_hash, data.node.param2)
|
duplicate_data.node.param2 = digtron.rotate_facedir(axis_hash, duplicate_data.node.param2)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Rotate builder item facings
|
-- Rotate builder item facings
|
||||||
if minetest.get_item_group(node_name, "digtron") == 4 then
|
if minetest.get_item_group(node_name, "digtron") == 4 then
|
||||||
local build_item = data.meta.fields.item
|
local build_item = duplicate_data.meta.fields.item
|
||||||
local build_item_def = minetest.registered_items[build_item]
|
local build_item_def = minetest.registered_items[build_item]
|
||||||
if build_item_def.paramtype2 == "wallmounted" then
|
if build_item_def.paramtype2 == "wallmounted" then
|
||||||
data.meta.fields.facing = digtron.rotate_wallmounted(axis_hash, tonumber(data.meta.fields.facing))
|
duplicate_data.meta.fields.facing = digtron.rotate_wallmounted(axis_hash, tonumber(duplicate_data.meta.fields.facing))
|
||||||
elseif build_item_def.paramtype2 == "facedir" then
|
elseif build_item_def.paramtype2 == "facedir" then
|
||||||
data.meta.fields.facing = digtron.rotate_facedir(axis_hash, tonumber(data.meta.fields.facing))
|
duplicate_data.meta.fields.facing = digtron.rotate_facedir(axis_hash, tonumber(duplicate_data.meta.fields.facing))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -628,24 +640,29 @@ local rotate_layout = function(digtron_id, axis)
|
|||||||
local pos = minetest.get_position_from_hash(hash)
|
local pos = minetest.get_position_from_hash(hash)
|
||||||
pos = digtron.rotate_pos(axis_hash, pos)
|
pos = digtron.rotate_pos(axis_hash, pos)
|
||||||
local new_hash = minetest.hash_node_position(pos)
|
local new_hash = minetest.hash_node_position(pos)
|
||||||
rotated_layout[new_hash] = data
|
rotated_layout[new_hash] = duplicate_data
|
||||||
end
|
end
|
||||||
|
|
||||||
invalidate_layout_cache(digtron_id)
|
return rotated_layout
|
||||||
persist_layout(digtron_id, rotated_layout)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
digtron.rotate = function(digtron_id, axis, player_name)
|
digtron.rotate = function(digtron_id, axis, player_name)
|
||||||
-- TODO: rotation version of is_buildable_to
|
local rotated_layout = rotate_layout(digtron_id, axis)
|
||||||
local root_pos = retrieve_pos(digtron_id)
|
local root_pos = retrieve_pos(digtron_id)
|
||||||
local removed = digtron.remove_from_world(digtron_id, player_name)
|
local permitted, succeeded, failed = digtron.is_buildable_to(digtron_id, rotated_layout, root_pos, player_name)
|
||||||
rotate_layout(digtron_id, axis)
|
if permitted then
|
||||||
digtron.build_to_world(digtron_id, root_pos, player_name)
|
local removed = digtron.remove_from_world(digtron_id, player_name)
|
||||||
-- Don't need to do fancy callback checking for digtron nodes since I made all those
|
digtron.build_to_world(digtron_id, rotated_layout, root_pos, player_name)
|
||||||
-- nodes and I know they don't have anything that needs to be done for them.
|
persist_layout(digtron_id, rotated_layout)
|
||||||
-- Just check for falling nodes.
|
-- Don't need to do fancy callback checking for digtron nodes since I made all those
|
||||||
for _, removed_pos in ipairs(removed) do
|
-- nodes and I know they don't have anything that needs to be done for them.
|
||||||
minetest.check_for_falling(removed_pos)
|
-- Just check for falling nodes.
|
||||||
|
for _, removed_pos in ipairs(removed) do
|
||||||
|
minetest.check_for_falling(removed_pos)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
digtron.show_buildable_nodes({}, failed)
|
||||||
|
minetest.sound_play("digtron_squeal", {gain = 0.5, pos=root_pos})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -937,8 +954,9 @@ digtron.execute_cycle = function(digtron_id, player_name)
|
|||||||
|
|
||||||
local dig_leftovers, nodes_to_dig, dig_cost = predict_dig(digtron_id, player_name, controlling_coordinate)
|
local dig_leftovers, nodes_to_dig, dig_cost = predict_dig(digtron_id, player_name, controlling_coordinate)
|
||||||
local new_root_pos = vector.add(old_root_pos, digtron.facedir_to_dir(root_facedir))
|
local new_root_pos = vector.add(old_root_pos, digtron.facedir_to_dir(root_facedir))
|
||||||
|
local layout = retrieve_layout(digtron_id)
|
||||||
-- TODO: convert nodes_to_dig into a hash map here and pass that in to reduce duplication?
|
-- TODO: convert nodes_to_dig into a hash map here and pass that in to reduce duplication?
|
||||||
local buildable_to, succeeded, failed = digtron.is_buildable_to(digtron_id, new_root_pos, player_name, nodes_to_dig)
|
local buildable_to, succeeded, failed = digtron.is_buildable_to(digtron_id, layout, new_root_pos, player_name, nodes_to_dig)
|
||||||
local missing_items, built_nodes, build_cost = predict_build(digtron_id, new_root_pos, player_name, nodes_to_dig, controlling_coordinate)
|
local missing_items, built_nodes, build_cost = predict_build(digtron_id, new_root_pos, player_name, nodes_to_dig, controlling_coordinate)
|
||||||
|
|
||||||
if buildable_to and next(missing_items) == nil then
|
if buildable_to and next(missing_items) == nil then
|
||||||
@ -950,7 +968,7 @@ digtron.execute_cycle = function(digtron_id, player_name)
|
|||||||
log_dug_nodes(nodes_to_dig, digtron_id, old_root_pos, player_name)
|
log_dug_nodes(nodes_to_dig, digtron_id, old_root_pos, player_name)
|
||||||
|
|
||||||
-- Building new Digtron
|
-- Building new Digtron
|
||||||
digtron.build_to_world(digtron_id, new_root_pos, player_name)
|
digtron.build_to_world(digtron_id, layout, new_root_pos, player_name)
|
||||||
minetest.sound_play("digtron_construction", {gain = 0.5, pos=new_root_pos})
|
minetest.sound_play("digtron_construction", {gain = 0.5, pos=new_root_pos})
|
||||||
|
|
||||||
local build_leftovers, success_count = build_nodes(built_nodes, player_name)
|
local build_leftovers, success_count = build_nodes(built_nodes, player_name)
|
||||||
|
Loading…
Reference in New Issue
Block a user