mirror of
https://github.com/minetest-mods/digtron.git
synced 2024-08-19 20:34:04 +02:00
IT DIGS
This commit is contained in:
parent
683b941622
commit
426cd4d82d
@ -260,10 +260,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if fields.test_dig then
|
if fields.test_dig then
|
||||||
local products, nodes_to_dig, cost = digtron.predict_dig(digtron_id, player_name)
|
digtron.execute_cycle(digtron_id, player_name)
|
||||||
minetest.chat_send_all("products: " .. dump(products))
|
|
||||||
minetest.chat_send_all("positions: " .. dump(nodes_to_dig))
|
|
||||||
minetest.chat_send_all("cost: " .. cost)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--TODO: this isn't recording the field when using ESC to exit the formspec
|
--TODO: this isn't recording the field when using ESC to exit the formspec
|
||||||
|
@ -19,7 +19,7 @@ local get_predictive_inventory = inventory_functions.get_predictive_inventory
|
|||||||
local commit_predictive_inventory = inventory_functions.commit_predictive_inventory
|
local commit_predictive_inventory = inventory_functions.commit_predictive_inventory
|
||||||
local clear_predictive_inventory = inventory_functions.clear_predictive_inventory
|
local clear_predictive_inventory = inventory_functions.clear_predictive_inventory
|
||||||
|
|
||||||
digtron.retrieve_inventory = retrieve_inventory
|
digtron.retrieve_inventory = retrieve_inventory -- used by formspecs
|
||||||
|
|
||||||
--------------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -135,6 +135,7 @@ for i, dir in ipairs(cardinal_dirs) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Given a facedir, returns an index into either cardinal_dirs or cardinal_dirs_hash that
|
-- Given a facedir, returns an index into either cardinal_dirs or cardinal_dirs_hash that
|
||||||
|
-- can be used to determine what this node is "aimed" at
|
||||||
local facedir_to_dir_index = function(param2)
|
local facedir_to_dir_index = function(param2)
|
||||||
return facedir_to_dir_map[param2 % 32]
|
return facedir_to_dir_map[param2 % 32]
|
||||||
end
|
end
|
||||||
@ -160,7 +161,7 @@ get_all_digtron_nodes = function(pos, digtron_nodes, digtron_adjacent, player_na
|
|||||||
get_all_digtron_nodes(test_pos, digtron_nodes, digtron_adjacent, player_name) -- recurse
|
get_all_digtron_nodes(test_pos, digtron_nodes, digtron_adjacent, player_name) -- recurse
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
-- don't record details, the content of this node will change as the digtron moves
|
-- don't record details, just keeping track of Digtron's borders
|
||||||
digtron_adjacent[test_hash] = true
|
digtron_adjacent[test_hash] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -267,7 +268,9 @@ digtron.assemble = function(root_pos, player_name)
|
|||||||
local root_hash = minetest.hash_node_position(root_pos)
|
local root_hash = minetest.hash_node_position(root_pos)
|
||||||
local digtron_nodes = {[root_hash] = node} -- Nodes that are part of Digtron.
|
local digtron_nodes = {[root_hash] = node} -- Nodes that are part of Digtron.
|
||||||
-- Initialize with the controller, it won't be added by get_all_adjacent_digtron_nodes
|
-- Initialize with the controller, it won't be added by get_all_adjacent_digtron_nodes
|
||||||
local digtron_adjacent = {} -- Nodes that are adjacent to Digtron but not a part of it
|
local digtron_adjacent = {} -- Nodes that are adjacent to Digtron but not a part of it.
|
||||||
|
-- There's a slight inefficiency in throwing away digtron_adjacent when retrieve_all_adjacent_pos could
|
||||||
|
-- use this info, but it's small and IMO not worth the complexity.
|
||||||
get_all_digtron_nodes(root_pos, digtron_nodes, digtron_adjacent, player_name)
|
get_all_digtron_nodes(root_pos, digtron_nodes, digtron_adjacent, player_name)
|
||||||
|
|
||||||
local digtron_id, digtron_inv = create_new_id(root_pos)
|
local digtron_id, digtron_inv = create_new_id(root_pos)
|
||||||
@ -352,7 +355,6 @@ digtron.assemble = function(root_pos, player_name)
|
|||||||
return digtron_id
|
return digtron_id
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Returns pos, node, and meta for the digtron node provided the in-world node matches the layout
|
-- Returns pos, node, and meta for the digtron node provided the in-world node matches the layout
|
||||||
-- returns nil otherwise
|
-- returns nil otherwise
|
||||||
local get_valid_data = function(digtron_id, root_hash, hash, data, function_name)
|
local get_valid_data = function(digtron_id, root_hash, hash, data, function_name)
|
||||||
@ -500,18 +502,22 @@ 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
|
||||||
--TODO implement ignore_nodes, needed for ignoring nodes that have been flagged as dug
|
|
||||||
digtron.is_buildable_to = function(digtron_id, root_pos, player_name, ignore_nodes, return_immediately_on_failure)
|
digtron.is_buildable_to = function(digtron_id, root_pos, player_name, ignore_nodes, return_immediately_on_failure)
|
||||||
local layout = retrieve_layout(digtron_id)
|
local layout = retrieve_layout(digtron_id)
|
||||||
|
|
||||||
-- 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_pos = retrieve_pos(digtron_id)
|
local old_pos = retrieve_pos(digtron_id)
|
||||||
local old_hashes = {}
|
local ignore_hashes = {}
|
||||||
if old_pos then
|
if old_pos then
|
||||||
local old_root_hash = minetest.hash_node_position(old_pos)
|
local old_root_hash = minetest.hash_node_position(old_pos)
|
||||||
for layout_hash, _ in pairs(layout) do
|
for layout_hash, _ in pairs(layout) do
|
||||||
old_hashes[layout_hash + old_root_hash] = true
|
ignore_hashes[layout_hash + old_root_hash] = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if ignore_nodes then
|
||||||
|
for _, ignore_pos in ipairs(ignore_nodes) do
|
||||||
|
ignore_hashes[minetest.hash_node_position(ignore_pos)] = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -529,7 +535,7 @@ digtron.is_buildable_to = function(digtron_id, root_pos, player_name, ignore_nod
|
|||||||
-- TODO: lots of testing needed here
|
-- TODO: lots of testing needed here
|
||||||
if not (
|
if not (
|
||||||
(node_def and node_def.buildable_to)
|
(node_def and node_def.buildable_to)
|
||||||
or old_hashes[node_hash]) or
|
or ignore_hashes[node_hash]) or
|
||||||
minetest.is_protected(target_pos, player_name)
|
minetest.is_protected(target_pos, player_name)
|
||||||
then
|
then
|
||||||
if return_immediately_on_failure then
|
if return_immediately_on_failure then
|
||||||
@ -568,7 +574,6 @@ 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)
|
||||||
minetest.chat_send_all("move attempt")
|
|
||||||
local permitted, succeeded, failed = digtron.is_buildable_to(digtron_id, dest_pos, player_name)
|
local permitted, succeeded, failed = digtron.is_buildable_to(digtron_id, 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)
|
||||||
@ -583,13 +588,18 @@ digtron.move = function(digtron_id, dest_pos, player_name)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
digtron.predict_dig = function(digtron_id, player_name)
|
local predict_dig = function(digtron_id, player_name)
|
||||||
|
local predictive_inv = get_predictive_inventory(digtron_id)
|
||||||
local layout = retrieve_layout(digtron_id)
|
local layout = retrieve_layout(digtron_id)
|
||||||
local root_pos = retrieve_pos(digtron_id)
|
local root_pos = retrieve_pos(digtron_id)
|
||||||
if not (layout and root_pos) then return end -- TODO error messages etc
|
if not (layout and root_pos and predictive_inv) then
|
||||||
|
minetest.log("error", "[Digtron] predict_dig failed to retrieve either "
|
||||||
|
.."a predictive inventory, a layout, or a root position for " .. digtron_id)
|
||||||
|
return
|
||||||
|
end
|
||||||
local root_hash = minetest.hash_node_position(root_pos)
|
local root_hash = minetest.hash_node_position(root_pos)
|
||||||
|
|
||||||
local products = {}
|
local leftovers = {}
|
||||||
local dug_positions = {}
|
local dug_positions = {}
|
||||||
local cost = 0
|
local cost = 0
|
||||||
|
|
||||||
@ -634,15 +644,45 @@ digtron.predict_dig = function(digtron_id, player_name)
|
|||||||
|
|
||||||
local drops = minetest.get_node_drops(target_name, "")
|
local drops = minetest.get_node_drops(target_name, "")
|
||||||
for _, drop in ipairs(drops) do
|
for _, drop in ipairs(drops) do
|
||||||
products[drop] = (products[drop] or 0) + 1
|
local leftover = predictive_inv:add_item("main", ItemStack(drop))
|
||||||
|
if leftover:get_count() > 0 then
|
||||||
|
table.insert(leftovers, leftover)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
table.insert(dug_positions, target_pos)
|
table.insert(dug_positions, target_pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return products, dug_positions, cost
|
return leftovers, dug_positions, cost
|
||||||
end
|
end
|
||||||
|
|
||||||
|
digtron.execute_cycle = function(digtron_id, player_name)
|
||||||
|
local leftovers, nodes_to_dig, cost = predict_dig(digtron_id, player_name)
|
||||||
|
local root_pos = retrieve_pos(digtron_id)
|
||||||
|
local root_node = minetest.get_node(root_pos)
|
||||||
|
local new_pos = vector.add(root_pos, cardinal_dirs[facedir_to_dir_index(root_node.param2)])
|
||||||
|
local buildable_to, succeeded, failed = digtron.is_buildable_to(digtron_id, new_pos, player_name, nodes_to_dig, return_immediately_on_failure)
|
||||||
|
|
||||||
|
if buildable_to then
|
||||||
|
local removed = digtron.remove_from_world(digtron_id, player_name)
|
||||||
|
minetest.bulk_set_node(nodes_to_dig, {name="air"})
|
||||||
|
digtron.build_to_world(digtron_id, new_pos, player_name)
|
||||||
|
minetest.sound_play("digtron_construction", {gain = 0.5, pos=new_pos})
|
||||||
|
for _, removed_pos in ipairs(removed) do
|
||||||
|
minetest.check_for_falling(removed_pos)
|
||||||
|
end
|
||||||
|
for _, dug_pos in ipairs(nodes_to_dig) do
|
||||||
|
-- TODO: other on-dug callbacks
|
||||||
|
minetest.check_for_falling(dug_pos)
|
||||||
|
end
|
||||||
|
commit_predictive_inventory(digtron_id)
|
||||||
|
else
|
||||||
|
digtron.show_buildable_nodes({}, failed)
|
||||||
|
minetest.sound_play("digtron_squeal", {gain = 0.5, pos=new_pos})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------
|
||||||
-- Node callbacks
|
-- Node callbacks
|
||||||
|
|
||||||
|
@ -110,40 +110,21 @@ local predictive_inventory = {}
|
|||||||
-- Copies digtron's inventory into a temporary location so that a dig cycle can be run
|
-- Copies digtron's inventory into a temporary location so that a dig cycle can be run
|
||||||
-- using it without affecting the actual inventory until everything's been confirmed to work
|
-- using it without affecting the actual inventory until everything's been confirmed to work
|
||||||
local get_predictive_inventory = function(digtron_id)
|
local get_predictive_inventory = function(digtron_id)
|
||||||
|
local existing = predictive_inventory[digtron_id]
|
||||||
|
if existing then return existing end
|
||||||
|
|
||||||
local predictive_inv = minetest.create_detached_inventory("digtron_predictive_"..digtron_id, detached_inventory_callbacks)
|
local predictive_inv = minetest.create_detached_inventory("digtron_predictive_"..digtron_id, detached_inventory_callbacks)
|
||||||
predictive_inventory[digtron_id] = predictive_inv
|
predictive_inventory[digtron_id] = predictive_inv
|
||||||
local source_inv = digtron.retrieve_inventory(digtron_id)
|
local source_inv = retrieve_inventory(digtron_id)
|
||||||
|
|
||||||
-- Populate predictive inventory with the digtron's contents
|
-- Populate predictive inventory with the digtron's contents
|
||||||
for _, listname in ipairs(source_inv:get_lists()) do
|
for listname, invlist in pairs(source_inv:get_lists()) do
|
||||||
predictive_inv:set_size(listname, source_inv:get_size(listname))
|
predictive_inv:set_size(listname, #invlist)
|
||||||
predictive_inv:set_list(listname, source_inv:get_list(listname))
|
predictive_inv:set_list(listname, invlist)
|
||||||
end
|
end
|
||||||
|
|
||||||
return predictive_inv
|
return predictive_inv
|
||||||
end
|
end
|
||||||
-- Copies the predictive inventory's contents into the actual digtron's inventory after success
|
|
||||||
local commit_predictive_inventory = function(digtron_id)
|
|
||||||
local predictive_inv = predictive_inventory[digtron_id]
|
|
||||||
if not predictive_inv then
|
|
||||||
minetest.log("error", "[Digtron] commit_predictive_inventory called for " .. digtron_id
|
|
||||||
.. " but predictive inventory did not exist")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local source_inv = digtron.retrieve_inventory(digtron_id)
|
|
||||||
for _, listname in ipairs(predictive_inv:get_lists()) do
|
|
||||||
source_inv:set_list(listname, predictive_inv:get_list(listname))
|
|
||||||
end
|
|
||||||
dirty_inventories[digtron_id] = true
|
|
||||||
|
|
||||||
minetest.remove_detached_inventory("digtron_predictive_"..digtron_id)
|
|
||||||
predictive_inventory[digtron_id] = nil
|
|
||||||
|
|
||||||
if not next(predictive_inventory) then
|
|
||||||
minetest.log("warning", "[Digtron] multiple predictive inventories were in existence, this shouldn't be happening. File an issue with Digtron programmers.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Wipes predictive inventory without committing it (eg, on failure of predicted operation)
|
-- Wipes predictive inventory without committing it (eg, on failure of predicted operation)
|
||||||
local clear_predictive_inventory = function(digtron_id)
|
local clear_predictive_inventory = function(digtron_id)
|
||||||
local predictive_inv = predictive_inventory[digtron_id]
|
local predictive_inv = predictive_inventory[digtron_id]
|
||||||
@ -160,6 +141,22 @@ local clear_predictive_inventory = function(digtron_id)
|
|||||||
minetest.log("warning", "[Digtron] multiple predictive inventories were in existence, this shouldn't be happening. File an issue with Digtron programmers.")
|
minetest.log("warning", "[Digtron] multiple predictive inventories were in existence, this shouldn't be happening. File an issue with Digtron programmers.")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-- Copies the predictive inventory's contents into the actual digtron's inventory and wipes the predictive inventory
|
||||||
|
local commit_predictive_inventory = function(digtron_id)
|
||||||
|
local predictive_inv = predictive_inventory[digtron_id]
|
||||||
|
if not predictive_inv then
|
||||||
|
minetest.log("error", "[Digtron] commit_predictive_inventory called for " .. digtron_id
|
||||||
|
.. " but predictive inventory did not exist")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local source_inv = retrieve_inventory(digtron_id)
|
||||||
|
for listname, invlist in pairs(predictive_inv:get_lists()) do
|
||||||
|
source_inv:set_list(listname, invlist)
|
||||||
|
end
|
||||||
|
dirty_inventories[digtron_id] = true
|
||||||
|
clear_predictive_inventory(digtron_id)
|
||||||
|
end
|
||||||
|
|
||||||
return {
|
return {
|
||||||
retrieve_inventory = retrieve_inventory,
|
retrieve_inventory = retrieve_inventory,
|
||||||
|
@ -24,7 +24,7 @@ minetest.register_node("digtron:inventory", {
|
|||||||
_doc_items_longdesc = digtron.doc.inventory_longdesc,
|
_doc_items_longdesc = digtron.doc.inventory_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.inventory_usagehelp,
|
_doc_items_usagehelp = digtron.doc.inventory_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 2, tubedevice = 1, tubedevice_receiver = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 2, tubedevice = 1, tubedevice_receiver = 1},
|
||||||
sounds = digtron.metal_sounds,
|
sounds = default.node_sound_metal_defaults(),
|
||||||
paramtype2= "facedir",
|
paramtype2= "facedir",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
node_box = {
|
node_box = {
|
||||||
@ -112,7 +112,7 @@ minetest.register_node("digtron:fuelstore", {
|
|||||||
_doc_items_longdesc = digtron.doc.fuelstore_longdesc,
|
_doc_items_longdesc = digtron.doc.fuelstore_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.fuelstore_usagehelp,
|
_doc_items_usagehelp = digtron.doc.fuelstore_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 5, tubedevice = 1, tubedevice_receiver = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 5, tubedevice = 1, tubedevice_receiver = 1},
|
||||||
sounds = digtron.metal_sounds,
|
sounds = default.node_sound_metal_defaults(),
|
||||||
paramtype2= "facedir",
|
paramtype2= "facedir",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
node_box = {
|
node_box = {
|
||||||
@ -220,7 +220,7 @@ minetest.register_node("digtron:combined_storage", {
|
|||||||
_doc_items_longdesc = digtron.doc.combined_storage_longdesc,
|
_doc_items_longdesc = digtron.doc.combined_storage_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.combined_storage_usagehelp,
|
_doc_items_usagehelp = digtron.doc.combined_storage_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 6, tubedevice = 1, tubedevice_receiver = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 6, tubedevice = 1, tubedevice_receiver = 1},
|
||||||
sounds = digtron.metal_sounds,
|
sounds = default.node_sound_metal_defaults(),
|
||||||
paramtype2= "facedir",
|
paramtype2= "facedir",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
node_box = {
|
node_box = {
|
||||||
|
Loading…
Reference in New Issue
Block a user