create separate unassembled controller, make builder "read" work.

This commit is contained in:
FaceDeer 2019-08-31 11:50:51 -06:00
parent df4c7f7f38
commit 70e1649d71
4 changed files with 218 additions and 110 deletions

@ -51,7 +51,7 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
.. "position[0.025,0.1]"
.. "anchor[0,0]"
.. "container[0,0]"
.. "list[detached:" .. digtron_id .. ";"..inv_list..";0,0;8,4]" -- TODO: paging system for inventory
.. "list[detached:" .. digtron_id .. ";"..inv_list..";0,0;8,5]" -- TODO: paging system for inventory
.. "container_end[]"
.. "container[0,5]list[current_player;main;0,0;8,1;]list[current_player;main;0,1.25;8,3;8]container_end[]"
.. "listring[current_player;main]"
@ -64,10 +64,10 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
.. "container[0,0]"
.. "button[0,0;1,1;disassemble;Disassemble]"
.. "field[1.2,0.3;1.75,1;digtron_name;Digtron name;"
..minetest.formspec_escape(digtron.get_name(digtron_id)).."]"
.. minetest.formspec_escape(digtron.get_name(digtron_id)).."]"
.. "field_close_on_enter[digtron_name;false]"
.. "field[2.9,0.3;0.7,1;cycles;Cycles;1]" -- TODO persist, actually use
.. "button[3.2,0;1,1;test_dig;Execute]"
.. "button[3.2,0;1,1;execute;Execute]"
.. "container_end[]"
.. "container[0,1]"
@ -82,7 +82,7 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
.. "container_end[]"
.. "container[0.5,3.2]"
.. "box[0,0;3,2;#CCCCCC]"
.. "box[0,0;3,2;#DDDDDD]"
.. "label[1.3,0.825;Rotate]"
.. "button[0.1,0.1;1,1;rot_counterclockwise;Widdershins]"
.. "button[2.1,0.1;1,1;rot_clockwise;Clockwise]"
@ -174,7 +174,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
digtron.rotate(digtron_id, digtron.facedir_to_up(facedir), player_name)
end
if fields.test_dig then
if fields.execute then
digtron.execute_cycle(digtron_id, player_name)
end
@ -195,7 +195,19 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
end)
minetest.register_node("digtron:controller", {
-- Doesn't deep-copy
local combine_defs = function(base_def, override_content)
local out = {}
for key, value in pairs(base_def) do
out[key] = value
end
for key, value in pairs(override_content) do
out[key] = value
end
return out
end
local base_def = {
description = S("Digtron Control Module"),
_doc_items_longdesc = nil,
_doc_items_usagehelp = nil,
@ -231,6 +243,46 @@ minetest.register_node("digtron:controller", {
},
},
sounds = default.node_sound_metal_defaults(),
on_blast = digtron.on_blast,
}
minetest.register_node("digtron:controller_unassembled", combine_defs(base_def, {
_digtron_assembled_node = "digtron:controller",
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local returnstack, success = digtron.on_rightclick(pos, node, clicker, itemstack, pointed_thing)
if returnstack then
return returnstack, success
end
if clicker == nil then return end
local player_name = clicker:get_player_name()
local digtron_id = digtron.assemble(pos, player_name)
if digtron_id then
local meta = minetest.get_meta(pos)
meta:set_string("digtron_id", digtron_id)
meta:mark_as_private("digtron_id")
player_interacting_with_digtron_id[player_name] = {digtron_id = digtron_id}
minetest.show_formspec(player_name,
"digtron:controller_assembled",
get_controller_assembled_formspec(digtron_id, player_name))
end
end
}))
minetest.register_node("digtron:controller", combine_defs(base_def, {
tiles = {
"digtron_plate.png^[transformR90",
"digtron_plate.png^[transformR270",
"digtron_plate.png",
"digtron_plate.png^[transformR180",
"digtron_plate.png",
"digtron_plate.png^digtron_control.png^digtron_intermittent.png",
},
_digtron_disassembled_node = "digtron:controller_unassembled",
groups = {cracky = 3, oddly_breakable_by_hand = 3, not_in_creative_inventory = 1},
on_dig = function(pos, node, digger)
local player_name
@ -249,7 +301,7 @@ minetest.register_node("digtron:controller", {
if stack:get_count() > 0 then
minetest.add_item(pos, stack)
end
-- call on_dignodes callback
-- TODO call on_dignodes callback
if digtron_id ~= "" then
local removed = digtron.remove_from_world(digtron_id, player_name)
for _, removed_pos in ipairs(removed) do
@ -280,11 +332,6 @@ minetest.register_node("digtron:controller", {
local stack_meta = itemstack:get_meta()
local digtron_id = stack_meta:get_string("digtron_id")
if digtron_id ~= "" then
-- Test if Digtron will fit the surroundings
-- if not, try moving it up so that the lowest y-coordinate on the Digtron is
-- at the y-coordinate of the place clicked on and test again.
-- if that fails, show ghost of Digtron and fail to place.
local target_pos
local below_node = minetest.get_node(pointed_thing.under)
local below_def = minetest.registered_nodes[below_node.name]
@ -293,23 +340,36 @@ minetest.register_node("digtron:controller", {
else
target_pos = pointed_thing.above
end
-- TODO rotate layout based on player orientation
-- move up so that the lowest y-coordinate on the Digtron is
-- at the y-coordinate of the place clicked on and test again.
local bbox = digtron.get_bounding_box(digtron_id)
target_pos.y = target_pos.y + math.abs(bbox.minp.y)
if target_pos then
local success, succeeded, failed = digtron.is_buildable_to(digtron_id, nil, target_pos, player_name)
if success then
digtron.build_to_world(digtron_id, nil, target_pos, player_name)
local built_positions = digtron.build_to_world(digtron_id, nil, target_pos, player_name)
for _, built_pos in ipairs(built_positions) do
minetest.check_for_falling(built_pos)
end
minetest.sound_play("digtron_machine_assemble", {gain = 0.5, pos=target_pos})
-- Note: DO NOT RESPECT CREATIVE MODE here.
-- If we allow multiple copies of a Digtron running around with the same digtron_id,
-- human sacrifice, dogs and cats living together, mass hysteria
return ItemStack("")
else
-- if that fails, show ghost of Digtron and fail to place.
digtron.show_buildable_nodes(succeeded, failed)
minetest.sound_play("digtron_buzzer", {gain = 0.5, pos=target_pos})
end
end
return itemstack
else
-- Should be impossible to have a controller without an ID, but if it happens place an unassembled node
itemstack:set_name("digtron:controller_unassembled")
return minetest.item_place(itemstack, placer, pointed_thing)
end
end,
@ -336,29 +396,15 @@ minetest.register_node("digtron:controller", {
local meta = minetest.get_meta(pos)
local digtron_id = meta:get_string("digtron_id")
local player_name = clicker:get_player_name()
if digtron_id == "" then
local digtron_id = digtron.assemble(pos, player_name)
if digtron_id then
meta:set_string("digtron_id", digtron_id)
meta:mark_as_private("digtron_id")
player_interacting_with_digtron_id[player_name] = {digtron_id = digtron_id}
minetest.show_formspec(player_name,
"digtron:controller_assembled",
get_controller_assembled_formspec(digtron_id, player_name))
end
-- TODO: error message, fix digtron
else
-- initialized
local player_name = clicker:get_player_name()
player_interacting_with_digtron_id[player_name] = {digtron_id = digtron_id}
minetest.show_formspec(player_name,
"digtron:controller_assembled",
get_controller_assembled_formspec(digtron_id, player_name))
end
end,
on_timer = function(pos, elapsed)
end,
on_blast = digtron.on_blast,
})
}))

@ -24,8 +24,6 @@ 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 -- used by formspecs
--------------------------------------------------------------------------------------
local create_new_id = function()
@ -58,11 +56,11 @@ end
-- Name
-- Not bothering with a dynamic table store for names, they're just strings with no need for serialization or deserialization
digtron.get_name = function(digtron_id)
local get_name = function(digtron_id)
return mod_meta:get_string(digtron_id..":name")
end
digtron.set_name = function(digtron_id, digtron_name)
local set_name = function(digtron_id, digtron_name)
-- Don't allow a name to be set for a non-existent Digtron
if mod_meta:get(digtron_id..":layout") then
mod_meta:set_string(digtron_id..":name", digtron_name)
@ -109,8 +107,6 @@ end
local persist_layout, retrieve_layout = get_table_functions("layout")
local persist_pos, retrieve_pos, dispose_pos = get_table_functions("pos")
digtron.get_pos = retrieve_pos
-------------------------------------------------------------------------------------------------------
-- Layout creation helpers
@ -253,15 +249,9 @@ table.insert(dispose_callbacks, invalidate_layout_cache)
-- assemble and disassemble
-- Returns the id of the new Digtron record, or nil on failure
digtron.assemble = function(root_pos, player_name)
local node = minetest.get_node(root_pos)
-- TODO: a more generic test? Not needed with the more generic controller design, as far as I can tell. There's only going to be the one type of controller.
if node.name ~= "digtron:controller" then
-- Called on an incorrect node
minetest.log("error", "[Digtron] digtron.assemble called with pos " .. minetest.pos_to_string(root_pos)
.. " but the node at this location was " .. node.name)
return nil
end
local assemble = function(root_pos, player_name)
local root_node = minetest.get_node(root_pos)
local root_meta = minetest.get_meta(root_pos)
if root_meta:contains("digtron_id") then
-- Already assembled. TODO: validate that the digtron_id actually exists as well
@ -269,8 +259,18 @@ digtron.assemble = function(root_pos, player_name)
.. " but the controller at this location was already part of a assembled Digtron.")
return nil
end
local digtron_name = root_meta:get_string("infotext")
-- This should be called on an unassembled node.
if root_node.name ~= "digtron:controller_unassembled" then
-- Called on an incorrect node
minetest.log("error", "[Digtron] digtron.assemble called with pos " .. minetest.pos_to_string(root_pos)
.. " but the node at this location was " .. root_node.name)
return nil
end
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] = root_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.
-- There's a slight inefficiency in throwing away digtron_adjacent when retrieve_all_adjacent_pos could
@ -326,9 +326,9 @@ digtron.assemble = function(root_pos, player_name)
layout[relative_hash] = {meta = current_meta_table, node = node}
end
digtron.set_name(digtron_id, root_meta:get_string("infotext"))
persist_inventory(digtron_id)
persist_layout(digtron_id, layout)
set_name(digtron_id, digtron_name)
invalidate_layout_cache(digtron_id)
persist_pos(digtron_id, root_pos)
@ -394,8 +394,7 @@ local get_valid_data = function(digtron_id, root_pos, hash, data, function_name)
end
-- Turns the Digtron back into pieces
digtron.disassemble = function(digtron_id, player_name)
local bbox = retrieve_bounding_box(digtron_id)
local disassemble = function(digtron_id, player_name)
local root_pos = retrieve_pos(digtron_id)
if not root_pos then
minetest.log("error", "[Digtron] digtron.disassemble was unable to find a position for " .. digtron_id
@ -403,11 +402,8 @@ digtron.disassemble = function(digtron_id, player_name)
return
end
local root_meta = minetest.get_meta(root_pos)
root_meta:set_string("infotext", digtron.get_name(digtron_id))
local layout = retrieve_layout(digtron_id)
local inv = digtron.retrieve_inventory(digtron_id)
local inv = retrieve_inventory(digtron_id)
if not (layout and inv) then
minetest.log("error", "[Digtron] digtron.disassemble was unable to find either layout or inventory record for " .. digtron_id
@ -451,7 +447,16 @@ digtron.disassemble = function(digtron_id, player_name)
-- Clear digtron_id, this node is no longer part of an active digtron
node_meta:set_string("digtron_id", "")
end
end
end
-- replace the controller node with the disassembled version
local root_node = minetest.get_node(root_pos)
if root_node.name == "digtron:controller" then
root_node.name = "digtron:controller_disassembled"
minetest.set_node(root_pos, root_node)
end
local root_meta = minetest.get_meta(root_pos)
root_meta:set_string("infotext", get_name(digtron_id))
minetest.log("action", "Digtron " .. digtron_id .. " disassembled at " .. minetest.pos_to_string(root_pos)
.. " by " .. player_name)
@ -468,7 +473,7 @@ end
-- Removes the in-world nodes of a digtron
-- Does not destroy its layout info
-- returns a table of vectors of all the nodes that were removed
digtron.remove_from_world = function(digtron_id, player_name)
local remove_from_world = function(digtron_id, player_name)
local layout = retrieve_layout(digtron_id)
local root_pos = retrieve_pos(digtron_id)
@ -504,7 +509,7 @@ digtron.remove_from_world = function(digtron_id, player_name)
end
-- Tests if a Digtron can be built at the designated location
digtron.is_buildable_to = function(digtron_id, layout, root_pos, player_name, ignore_nodes, return_immediately_on_failure)
local is_buildable_to = function(digtron_id, layout, root_pos, player_name, ignore_nodes, return_immediately_on_failure)
-- 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_root_pos = retrieve_pos(digtron_id)
@ -557,10 +562,11 @@ digtron.is_buildable_to = function(digtron_id, layout, root_pos, player_name, ig
end
-- Places the Digtron into the world.
digtron.build_to_world = function(digtron_id, layout, root_pos, player_name)
local build_to_world = function(digtron_id, layout, root_pos, player_name)
if layout == nil then
layout = retrieve_layout(digtron_id)
end
local built_positions = {}
for hash, data in pairs(layout) do
-- 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)
@ -571,18 +577,19 @@ digtron.build_to_world = function(digtron_id, layout, root_pos, player_name)
end
meta:set_string("digtron_id", digtron_id)
meta:mark_as_private("digtron_id")
table.insert(built_positions, node_pos)
end
persist_pos(digtron_id, root_pos)
return true
return built_positions
end
digtron.move = function(digtron_id, dest_pos, player_name)
local move = function(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)
local permitted, succeeded, failed = is_buildable_to(digtron_id, layout, dest_pos, player_name)
if permitted then
local removed = digtron.remove_from_world(digtron_id, player_name)
digtron.build_to_world(digtron_id, layout, dest_pos, player_name)
local removed = remove_from_world(digtron_id, player_name)
build_to_world(digtron_id, layout, dest_pos, player_name)
minetest.sound_play("digtron_truck", {gain = 0.5, pos=dest_pos})
for _, removed_pos in ipairs(removed) do
minetest.check_for_falling(removed_pos)
@ -646,13 +653,13 @@ local rotate_layout = function(digtron_id, axis)
return rotated_layout
end
digtron.rotate = function(digtron_id, axis, player_name)
local rotate = function(digtron_id, axis, player_name)
local rotated_layout = rotate_layout(digtron_id, axis)
local root_pos = retrieve_pos(digtron_id)
local permitted, succeeded, failed = digtron.is_buildable_to(digtron_id, rotated_layout, root_pos, player_name)
local permitted, succeeded, failed = is_buildable_to(digtron_id, rotated_layout, root_pos, player_name)
if permitted then
local removed = digtron.remove_from_world(digtron_id, player_name)
digtron.build_to_world(digtron_id, rotated_layout, root_pos, player_name)
local removed = remove_from_world(digtron_id, player_name)
build_to_world(digtron_id, rotated_layout, root_pos, player_name)
minetest.sound_play("digtron_hydraulic", {gain = 0.5, pos=dest_pos})
persist_layout(digtron_id, rotated_layout)
-- Don't need to do fancy callback checking for digtron nodes since I made all those
@ -947,7 +954,7 @@ local insert_or_eject = function(digtron_id, item_list, pos)
end
end
digtron.execute_cycle = function(digtron_id, player_name)
local execute_cycle = function(digtron_id, player_name)
local old_root_pos = retrieve_pos(digtron_id)
local root_node = minetest.get_node(old_root_pos)
local root_facedir = root_node.param2
@ -1005,7 +1012,7 @@ end
-- If the digtron node has an assigned ID and a layout for that ID exists and
-- a matching node exists in the layout then don't let it be dug.
-- TODO: add protection check?
digtron.can_dig = function(pos, digger)
local can_dig = function(pos, digger)
local meta = minetest.get_meta(pos)
local digtron_id = meta:get_string("digtron_id")
if digtron_id == "" then
@ -1025,7 +1032,7 @@ digtron.can_dig = function(pos, digger)
minetest.log("error", "[Digtron] can_dig was called on a " .. node.name .. " at location "
.. minetest.pos_to_string(pos) .. " that claimed to belong to " .. digtron_id
.. ". However, layout and/or location data are missing: " .. missing)
-- May be better to do this to prevent node duplication. But we're already in bug land here so tread gently.
-- TODO May be better to do this to prevent node duplication. But we're already in bug land here so tread gently.
--minetest.remove_node(pos)
--return false
return true
@ -1053,7 +1060,7 @@ end
-- put this on all Digtron nodes. If other inventory types are added (eg, batteries)
-- update this.
digtron.on_blast = function(pos, intensity)
local on_blast = function(pos, intensity)
if intensity < 1.0 then return end -- The Almighty Digtron ignores weak-ass explosions
local meta = minetest.get_meta(pos)
@ -1079,7 +1086,7 @@ end
-- Use this inside other on_rightclicks for configuring Digtron nodes, this
-- overrides if you're right-clicking with another Digtron node and assumes
-- that you're trying to build it.
digtron.on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
local item_def = itemstack:get_definition()
if item_def.type == "node" and minetest.get_item_group(itemstack:get_name(), "digtron") > 0 then
local returnstack, success = minetest.item_place_node(itemstack, clicker, pointed_thing)
@ -1115,3 +1122,29 @@ if minetest.get_modpath("creative") then
end
end
end
---------------------------------------------------------------------------------------------------------------------------
-- External API
-- node definition methods
digtron.can_dig = can_dig
digtron.on_blast = on_blast
digtron.on_rightclick = on_rightclick
digtron.get_name = get_name
digtron.set_name = set_name
digtron.get_pos = retrieve_pos
digtron.get_bounding_box = retrieve_bounding_box
digtron.retrieve_inventory = retrieve_inventory -- used by formspecs
digtron.assemble = assemble
digtron.disassemble = disassemble
digtron.remove_from_world = remove_from_world
digtron.is_buildable_to = is_buildable_to
digtron.build_to_world = build_to_world
digtron.move = move
digtron.rotate = rotate
digtron.execute_cycle = execute_cycle

@ -1,6 +1,21 @@
digtron = {}
digtron.doc = {} -- TODO: move to doc file
-- A global dictionary is used here so that other substitutions can be added easily by other mods, if necessary
digtron.builder_read_item_substitutions = {
["default:torch_ceiling"] = "default:torch",
["default:torch_wall"] = "default:torch",
["default:dirt_with_grass"] = "default:dirt",
["default:dirt_with_grass_footsteps"] = "default:dirt",
["default:dirt_with_dry_grass"] = "default:dirt",
["default:dirt_with_rainforest_litter"] = "default:dirt",
["default:dirt_with_snow"] = "default:dirt",
["default:furnace_active"] = "default:furnace",
["farming:soil"] = "default:dirt",
["farming:soil_wet"] = "default:dirt",
["farming:desert_sand_soil"] = "default:desert_sand",
["farming:desert_sand_soil_wet"] = "default:desert_sand",
}
-- Sometimes we want builder heads to call an item's "on_place" method, other times we
-- don't want them to. There's no way to tell which situation is best programmatically

@ -23,17 +23,21 @@ local get_formspec = function(pos)
"listcolors[#00000069;#5A5A5A00;#141318;#30434C;#FFF]" ..
"list[detached:digtron:builder_item;main;0,0;1,1;]" ..
"field[1.3,0.8;1,0.1;extrusion;" .. S("Extrusion") .. ";" ..extrusion .. "]" ..
"field_close_on_enter[extrusion;false]" ..
"tooltip[extrusion;" .. S("Builder will extrude this many blocks in the direction it is facing.\nCan be set from 1 to @1.\nNote that Digtron won't build into unloaded map regions.", digtron.config.maximum_extrusion) .. "]" ..
"field[2.3,0.8;1,0.1;period;" .. S("Periodicity") .. ";".. period .. "]" ..
"field_close_on_enter[period;false]" ..
"tooltip[period;" .. S("Builder will build once every n steps.\nThese steps are globally aligned, so all builders with the\nsame period and offset will build on the same location.") .. "]" ..
"field[3.3,0.8;1,0.1;offset;" .. S("Offset") .. ";" .. offset .. "]" ..
"field_close_on_enter[offset;false]" ..
"tooltip[offset;" .. S("Offsets the start of periodicity counting by this amount.\nFor example, a builder with period 2 and offset 0 builds\nevery even-numbered block and one with period 2 and\noffset 1 builds every odd-numbered block.") .. "]" ..
"button[4.0,0.5;1,0.1;set;" .. S("Save &\nShow") .. "]" ..
"tooltip[set;" .. S("Saves settings") .. "]" ..
"tooltip[set;" .. S("Saves settings, closes interface, and shows the locations this builder will build to in-world.") .. "]" ..
"field[5.3,0.8;1,0.1;facing;" .. S("Facing") .. ";" .. facing .. "]" ..
"field_close_on_enter[facing;false]" ..
"tooltip[facing;" .. S("Value from 0-23. Not all block types make use of this.\nUse the 'Read & Save' button to copy the facing of the block\ncurrently in the builder output location.") .. "]" ..
"button[6.0,0.5;1,0.1;read;" .. S("Read &\nSave") .. "]" ..
"tooltip[read;" .. S("Reads the facing of the block currently in the build location,\nthen saves all settings.") .. "]" ..
"button[6.0,0.5;1,0.1;read;" .. S("Read") .. "]" ..
"tooltip[read;" .. S("Reads the facing of the block currently in the build location.") .. "]" ..
"list[current_player;main;0,1.3;8,1;]" ..
default.get_hotbar_bg(0,1.3) ..
"list[current_player;main;0,2.5;8,3;8]" ..
@ -44,6 +48,19 @@ end
----------------------------------------------------------------------
-- Detached inventory for setting the builder item
local is_item_allowed = function(item)
-- Ignore unknown items
if minetest.registered_items[item] == nil then return false end
local stack_def = minetest.registered_nodes[item]
if not stack_def and not digtron.whitelisted_on_place(item) then
return false -- don't allow craft items unless their on_place is whitelisted.
end
return true
end
local inv = minetest.create_detached_inventory("digtron:builder_item", {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return 0
@ -52,9 +69,10 @@ local inv = minetest.create_detached_inventory("digtron:builder_item", {
-- Always disallow put, but use this to read what the player *tried* adding and set the builder appropriately
local item = stack:get_name()
-- Ignore unknown items
if minetest.registered_items[item] == nil then return 0 end
if not is_item_allowed(item) then
return 0
end
local player_name = player:get_player_name()
local pos = player_interacting_with_builder_pos[player_name]
if pos == nil then
@ -78,11 +96,6 @@ local inv = minetest.create_detached_inventory("digtron:builder_item", {
return 0
end
local stack_def = minetest.registered_nodes[item]
if not stack_def and not digtron.whitelisted_on_place(item) then
return 0 -- don't allow craft items unless their on_place is whitelisted.
end
-- If we're adding a wallmounted item and the build facing is greater than 5, reset it to 0
if stack_def ~= nil and stack_def.paramtype2 == "wallmounted" and tonumber(meta:get_int("facing")) > 5 then
meta:set_int("facing", 0)
@ -97,12 +110,6 @@ local inv = minetest.create_detached_inventory("digtron:builder_item", {
allow_take = function(inv, listname, index, stack, player)
return 0
end,
-- on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
-- end,
-- on_take = function(inv, listname, index, stack, player)
-- end,
-- on_put = function(inv, listname, index, stack, player)
-- end
})
inv:set_size("main", 1)
@ -142,30 +149,31 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
.. " no position was recorded.")
return
end
local meta = minetest.get_meta(pos)
local period = tonumber(fields.period)
local offset = tonumber(fields.offset)
local facing = tonumber(fields.facing)
local extrusion = tonumber(fields.extrusion)
local item = meta:get_string("item")
local period = tonumber(fields.period)
if period and period > 0 then
meta:set_int("period", math.floor(period))
else
period = meta:get_int("period")
end
local offset = tonumber(fields.offset)
if offset then
meta:set_int("offset", math.floor(offset))
else
offset = meta:get_int("offset")
end
local facing = tonumber(fields.facing)
if facing and facing >= 0 and facing < 24 then
local target_item = ItemStack(item)
if target_item:get_definition().paramtype2 == "wallmounted" then
if facing < 6 then
meta:set_int("facing", facing)
meta:set_int("facing", math.floor(facing))
-- wallmounted facings only run from 0-5
end
else
@ -175,27 +183,32 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
facing = meta:get_int("facing")
end
local extrusion = tonumber(fields.extrusion)
if extrusion and extrusion > 0 and extrusion <= digtron.config.maximum_extrusion then
meta:set_int("extrusion", math.floor(extrusion))
else
extrusion = meta:get_int("extrusion")
end
-- if fields.set then
-- digtron.show_offset_markers(pos, offset, period)
--
-- elseif fields.read then
-- local facing = minetest.get_node(pos).param2
-- local buildpos = digtron.find_new_pos(pos, facing)
-- local target_node = minetest.get_node(buildpos)
-- if target_node.name ~= "air" and minetest.get_item_group(target_node.name, "digtron") == 0 then
-- local meta = minetest.get_meta(pos)
-- local inv = meta:get_inventory()
-- local target_name = digtron.builder_read_item_substitutions[target_node.name] or target_node.name
-- inv:set_stack("main", 1, target_name)
-- meta:set_int("facing", target_node.param2)
-- end
-- end
if fields.set then
--digtron.show_offset_markers(pos, offset, period)
end
if fields.read then
local builder_facing = minetest.get_node(pos).param2
local buildpos = vector.add(minetest.facedir_to_dir(builder_facing), pos)
local target_node = minetest.get_node(buildpos)
local target_name = target_node.name
if digtron.builder_read_item_substitutions[target_name] then
target_name = digtron.builder_read_item_substitutions[target_name]
end
if target_name ~= "air" and is_item_allowed(target_name) then
local meta = minetest.get_meta(pos)
item = target_name
meta:set_string("item", item)
meta:set_int("facing", target_node.param2)
end
end
if fields.help then
minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:builder", true)
@ -208,8 +221,9 @@ minetest.register_on_player_receive_fields(function(sender, formname, fields)
end
meta:set_string("infotext", S("Builder for @1\nperiod @2, offset @3, extrusion @4", item_desc, period, offset, extrusion))
digtron.update_builder_item(pos)
minetest.show_formspec(player_name, "digtron:builder", get_formspec(pos))
end)