mirror of
https://github.com/minetest-mods/digtron.git
synced 2024-10-05 17:13:08 +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
|
||||
|
||||
if fields.test_dig then
|
||||
local products, nodes_to_dig, cost = digtron.predict_dig(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)
|
||||
digtron.execute_cycle(digtron_id, player_name)
|
||||
end
|
||||
|
||||
--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 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
|
||||
|
||||
-- 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)
|
||||
return facedir_to_dir_map[param2 % 32]
|
||||
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
|
||||
end
|
||||
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
|
||||
end
|
||||
end
|
||||
@ -267,7 +268,9 @@ digtron.assemble = function(root_pos, player_name)
|
||||
local root_hash = minetest.hash_node_position(root_pos)
|
||||
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
|
||||
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)
|
||||
|
||||
local digtron_id, digtron_inv = create_new_id(root_pos)
|
||||
@ -352,7 +355,6 @@ digtron.assemble = function(root_pos, player_name)
|
||||
return digtron_id
|
||||
end
|
||||
|
||||
|
||||
-- Returns pos, node, and meta for the digtron node provided the in-world node matches the layout
|
||||
-- returns nil otherwise
|
||||
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
|
||||
|
||||
-- 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)
|
||||
local layout = retrieve_layout(digtron_id)
|
||||
|
||||
-- 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
|
||||
local old_pos = retrieve_pos(digtron_id)
|
||||
local old_hashes = {}
|
||||
local ignore_hashes = {}
|
||||
if old_pos then
|
||||
local old_root_hash = minetest.hash_node_position(old_pos)
|
||||
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
|
||||
|
||||
@ -529,7 +535,7 @@ digtron.is_buildable_to = function(digtron_id, root_pos, player_name, ignore_nod
|
||||
-- TODO: lots of testing needed here
|
||||
if not (
|
||||
(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)
|
||||
then
|
||||
if return_immediately_on_failure then
|
||||
@ -568,7 +574,6 @@ digtron.build_to_world = function(digtron_id, root_pos, player_name)
|
||||
end
|
||||
|
||||
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)
|
||||
if permitted then
|
||||
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
|
||||
|
||||
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 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 products = {}
|
||||
local leftovers = {}
|
||||
local dug_positions = {}
|
||||
local cost = 0
|
||||
|
||||
@ -634,15 +644,45 @@ digtron.predict_dig = function(digtron_id, player_name)
|
||||
|
||||
local drops = minetest.get_node_drops(target_name, "")
|
||||
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
|
||||
table.insert(dug_positions, target_pos)
|
||||
end
|
||||
end
|
||||
|
||||
return products, dug_positions, cost
|
||||
return leftovers, dug_positions, cost
|
||||
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
|
||||
|
||||
|
@ -110,40 +110,21 @@ local predictive_inventory = {}
|
||||
-- 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
|
||||
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)
|
||||
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
|
||||
for _, listname in ipairs(source_inv:get_lists()) do
|
||||
predictive_inv:set_size(listname, source_inv:get_size(listname))
|
||||
predictive_inv:set_list(listname, source_inv:get_list(listname))
|
||||
for listname, invlist in pairs(source_inv:get_lists()) do
|
||||
predictive_inv:set_size(listname, #invlist)
|
||||
predictive_inv:set_list(listname, invlist)
|
||||
end
|
||||
|
||||
return predictive_inv
|
||||
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)
|
||||
local clear_predictive_inventory = function(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.")
|
||||
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 {
|
||||
retrieve_inventory = retrieve_inventory,
|
||||
|
@ -24,7 +24,7 @@ minetest.register_node("digtron:inventory", {
|
||||
_doc_items_longdesc = digtron.doc.inventory_longdesc,
|
||||
_doc_items_usagehelp = digtron.doc.inventory_usagehelp,
|
||||
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",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
@ -112,7 +112,7 @@ minetest.register_node("digtron:fuelstore", {
|
||||
_doc_items_longdesc = digtron.doc.fuelstore_longdesc,
|
||||
_doc_items_usagehelp = digtron.doc.fuelstore_usagehelp,
|
||||
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",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
@ -220,7 +220,7 @@ minetest.register_node("digtron:combined_storage", {
|
||||
_doc_items_longdesc = digtron.doc.combined_storage_longdesc,
|
||||
_doc_items_usagehelp = digtron.doc.combined_storage_usagehelp,
|
||||
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",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
|
Loading…
Reference in New Issue
Block a user