mirror of
https://github.com/minetest-mods/digtron.git
synced 2024-08-20 04:44:05 +02:00
add sequencer tab. Digtron doesn't yet actually use the sequence set here.
This commit is contained in:
parent
70e1649d71
commit
7c08241c7d
206
controller.lua
206
controller.lua
@ -4,10 +4,150 @@ local S, NS = dofile(MP.."/intllib.lua")
|
|||||||
|
|
||||||
local listname_to_title =
|
local listname_to_title =
|
||||||
{
|
{
|
||||||
["main"] = "Main Inventory",
|
["main"] = S("Main Inventory"),
|
||||||
["fuel"] = "Fuel",
|
["fuel"] = S("Fuel"),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local sequencer_commands =
|
||||||
|
{
|
||||||
|
S("Sequence"),
|
||||||
|
S("Dig Move Build"),
|
||||||
|
S("Move Up"),
|
||||||
|
S("Move Down"),
|
||||||
|
S("Move Left"),
|
||||||
|
S("Move Right"),
|
||||||
|
S("Move Forward"),
|
||||||
|
S("Move Back"),
|
||||||
|
S("Yaw Left"),
|
||||||
|
S("Yaw Right"),
|
||||||
|
S("Pitch Up"),
|
||||||
|
S("Pitch Down"),
|
||||||
|
S("Roll Clockwise"),
|
||||||
|
S("Roll Widdershins"),
|
||||||
|
}
|
||||||
|
|
||||||
|
local sequencer_dropdown_list = table.concat(sequencer_commands, ",")
|
||||||
|
|
||||||
|
local sequencer_commands_reverse = {}
|
||||||
|
for i, command in ipairs(sequencer_commands) do
|
||||||
|
sequencer_commands_reverse[command] = i
|
||||||
|
end
|
||||||
|
|
||||||
|
local create_sequence_list
|
||||||
|
create_sequence_list = function(sequence_in, list_out, root_index, x, y)
|
||||||
|
root_index = root_index or ""
|
||||||
|
x = x or 0
|
||||||
|
y = y or 0
|
||||||
|
|
||||||
|
for i, val in ipairs(sequence_in) do
|
||||||
|
local index = root_index .. ":" .. i
|
||||||
|
local line = "dropdown[".. x ..","..y..";1.5;sequencer_com"..index..";"..sequencer_dropdown_list..";"..val[1]..
|
||||||
|
"]field[".. x+1.75 ..",".. y+0.25 ..";1,1;sequencer_cnt"..index..";;"..val[2].."]"..
|
||||||
|
"field_close_on_enter[sequencer_cnt_"..i..";false]"..
|
||||||
|
"button[".. x+ 2.375 .. ","..y-0.0625 ..";1,1;sequencer_del"..index..";Delete]"
|
||||||
|
if val[1] == 1 then
|
||||||
|
line = line .. "button[".. x+3.25 ..","..y-0.0625 ..";1,1;sequencer_ins"..index..";Insert]"
|
||||||
|
table.insert(list_out, line)
|
||||||
|
y = y + 0.8
|
||||||
|
y = create_sequence_list(val[3], list_out, index, x+0.5, y)
|
||||||
|
else
|
||||||
|
table.insert(list_out, line)
|
||||||
|
y = y + 0.8
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return y
|
||||||
|
end
|
||||||
|
|
||||||
|
-- all field prefixes in the above create_sequence_list should be of this length
|
||||||
|
local sequencer_field_length = string.len("sequencer_com:")
|
||||||
|
|
||||||
|
local find_item = function(field, sequence)
|
||||||
|
local index_list = field:sub(sequencer_field_length+1):split(":")
|
||||||
|
local target = {[3] = sequence}
|
||||||
|
for i = 1, #index_list do
|
||||||
|
target = target[3][tonumber(index_list[i])]
|
||||||
|
if target == nil then
|
||||||
|
minetest.log("error", "[Digtron] find_item failed to find a sequence item.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return target
|
||||||
|
end
|
||||||
|
|
||||||
|
local delete_item = function(field, sequence)
|
||||||
|
local index_list = field:sub(sequencer_field_length+1):split(":")
|
||||||
|
local target = {[3] = sequence}
|
||||||
|
for i = 1, #index_list-1 do
|
||||||
|
target = target[3][tonumber(index_list[i])]
|
||||||
|
if target == nil then
|
||||||
|
minetest.log("error", "[Digtron] delete_item failed to find a sequence item.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.remove(target[3], tonumber(index_list[#index_list]))
|
||||||
|
end
|
||||||
|
|
||||||
|
-- recurses through sequences ensuring there are tables for them
|
||||||
|
local clean_subsequences
|
||||||
|
clean_subsequences = function(sequence)
|
||||||
|
for i, val in ipairs(sequence) do
|
||||||
|
if val[1] == 1 then
|
||||||
|
if val[3] == nil then
|
||||||
|
val[3] = {}
|
||||||
|
else
|
||||||
|
clean_subsequences(val[3])
|
||||||
|
end
|
||||||
|
else
|
||||||
|
val[3] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local update_sequence = function(digtron_id, fields)
|
||||||
|
local sequence = digtron.get_sequence(digtron_id)
|
||||||
|
local delete_index = {}
|
||||||
|
local insert_index = {}
|
||||||
|
for field, value in pairs(fields) do
|
||||||
|
local command_type = field:sub(1,sequencer_field_length)
|
||||||
|
if command_type == "sequencer_com:" then
|
||||||
|
local seq_item = find_item(field, sequence)
|
||||||
|
seq_item[1] = sequencer_commands_reverse[value]
|
||||||
|
elseif command_type == "sequencer_cnt:" then
|
||||||
|
local val_int = tonumber(value)
|
||||||
|
if val_int then
|
||||||
|
val_int = math.floor(val_int)
|
||||||
|
local seq_item = find_item(field, sequence)
|
||||||
|
seq_item[2] = val_int
|
||||||
|
end
|
||||||
|
|
||||||
|
--Save these to do last so as to not invalidate indices
|
||||||
|
elseif command_type == "sequencer_del:" then
|
||||||
|
table.insert(delete_index, field)
|
||||||
|
elseif command_type == "sequencer_ins:" then
|
||||||
|
table.insert(insert_index, field)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, insert in ipairs(insert_index) do
|
||||||
|
local item = find_item(insert, sequence)
|
||||||
|
table.insert(item[3], {2,1})
|
||||||
|
end
|
||||||
|
for _, delete in ipairs(delete_index) do
|
||||||
|
delete_item(delete, sequence)
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.sequencer_insert_end then
|
||||||
|
table.insert(sequence, {2,1})
|
||||||
|
end
|
||||||
|
|
||||||
|
clean_subsequences(sequence)
|
||||||
|
digtron.set_sequence(digtron_id, sequence)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- This allows us to know which digtron the player has a formspec open for without
|
-- This allows us to know which digtron the player has a formspec open for without
|
||||||
-- sending the digtron_id over the network
|
-- sending the digtron_id over the network
|
||||||
local player_interacting_with_digtron_id = {}
|
local player_interacting_with_digtron_id = {}
|
||||||
@ -21,7 +161,7 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
|
|||||||
return ""
|
return ""
|
||||||
end
|
end
|
||||||
|
|
||||||
local inv = digtron.retrieve_inventory(digtron_id) -- ensures the detatched inventory exists and is populated
|
local inv = digtron.get_inventory(digtron_id) -- ensures the detatched inventory exists and is populated
|
||||||
|
|
||||||
-- TODO: will probably want a centralized cache for most of this, right now there's tons of redundancy
|
-- TODO: will probably want a centralized cache for most of this, right now there's tons of redundancy
|
||||||
if context.tabs == nil then
|
if context.tabs == nil then
|
||||||
@ -37,19 +177,17 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
|
|||||||
context.current_tab = 1
|
context.current_tab = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local tabs = ""
|
local position_and_anchor = "position[0.025,0.1]anchor[0,0]"
|
||||||
if next(context.tabs) ~= nil then
|
|
||||||
tabs = "tabheader[0,0;tab_header;Controls"
|
local tabs = "tabheader[0,0;tab_header;Controls,Sequence"
|
||||||
for _, tab in ipairs(context.tabs) do
|
for _, tab in ipairs(context.tabs) do
|
||||||
tabs = tabs .. "," .. listname_to_title[tab.listname] or tab.listname
|
tabs = tabs .. "," .. listname_to_title[tab.listname] or tab.listname
|
||||||
end
|
end
|
||||||
tabs = tabs .. ";" .. context.current_tab .. "]"
|
tabs = tabs .. ";" .. context.current_tab .. "]"
|
||||||
end
|
|
||||||
|
|
||||||
local inv_tab = function(inv_list)
|
local inv_tab = function(inv_list)
|
||||||
return "size[8,9]"
|
return "size[8,9]"
|
||||||
.. "position[0.025,0.1]"
|
.. position_and_anchor
|
||||||
.. "anchor[0,0]"
|
|
||||||
.. "container[0,0]"
|
.. "container[0,0]"
|
||||||
.. "list[detached:" .. digtron_id .. ";"..inv_list..";0,0;8,5]" -- TODO: paging system for inventory
|
.. "list[detached:" .. digtron_id .. ";"..inv_list..";0,0;8,5]" -- TODO: paging system for inventory
|
||||||
.. "container_end[]"
|
.. "container_end[]"
|
||||||
@ -58,9 +196,20 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
|
|||||||
.. "listring[detached:" .. digtron_id .. ";"..inv_list.."]"
|
.. "listring[detached:" .. digtron_id .. ";"..inv_list.."]"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local sequence_tab = function()
|
||||||
|
local sequence = digtron.get_sequence(digtron_id)
|
||||||
|
local list_out = {}
|
||||||
|
local y = create_sequence_list(sequence, list_out)
|
||||||
|
return "size[4.2,5]"
|
||||||
|
.. position_and_anchor
|
||||||
|
.. "container[0,0]"
|
||||||
|
.. table.concat(list_out)
|
||||||
|
.. "button[0,"..y-0.0625 ..";1,1;sequencer_insert_end;Insert]"
|
||||||
|
.. "container_end[]"
|
||||||
|
end
|
||||||
|
|
||||||
local controls = "size[4.2,5]"
|
local controls = "size[4.2,5]"
|
||||||
.. "position[0.025,0.1]"
|
.. position_and_anchor
|
||||||
.. "anchor[0,0]"
|
|
||||||
.. "container[0,0]"
|
.. "container[0,0]"
|
||||||
.. "button[0,0;1,1;disassemble;Disassemble]"
|
.. "button[0,0;1,1;disassemble;Disassemble]"
|
||||||
.. "field[1.2,0.3;1.75,1;digtron_name;Digtron name;"
|
.. "field[1.2,0.3;1.75,1;digtron_name;Digtron name;"
|
||||||
@ -84,8 +233,8 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
|
|||||||
.. "container[0.5,3.2]"
|
.. "container[0.5,3.2]"
|
||||||
.. "box[0,0;3,2;#DDDDDD]"
|
.. "box[0,0;3,2;#DDDDDD]"
|
||||||
.. "label[1.3,0.825;Rotate]"
|
.. "label[1.3,0.825;Rotate]"
|
||||||
.. "button[0.1,0.1;1,1;rot_counterclockwise;Widdershins]"
|
.. "button[0.1,0.1;1,1;rot_counterclockwise;Roll\nWiddershins]"
|
||||||
.. "button[2.1,0.1;1,1;rot_clockwise;Clockwise]"
|
.. "button[2.1,0.1;1,1;rot_clockwise;Roll\nClockwise]"
|
||||||
.. "button[1.1,0.1;1,1;rot_up;Pitch Up]"
|
.. "button[1.1,0.1;1,1;rot_up;Pitch Up]"
|
||||||
.. "button[1.1,1.1;1,1;rot_down;Pitch Down]"
|
.. "button[1.1,1.1;1,1;rot_down;Pitch Down]"
|
||||||
.. "button[0.1,1.1;1,1;rot_left;Yaw Left]"
|
.. "button[0.1,1.1;1,1;rot_left;Yaw Left]"
|
||||||
@ -94,8 +243,10 @@ local get_controller_assembled_formspec = function(digtron_id, player_name)
|
|||||||
|
|
||||||
if context.current_tab == 1 then
|
if context.current_tab == 1 then
|
||||||
return controls .. tabs
|
return controls .. tabs
|
||||||
|
elseif context.current_tab == 2 then
|
||||||
|
return sequence_tab() .. tabs
|
||||||
else
|
else
|
||||||
return inv_tab(context.tabs[context.current_tab - 1].listname) .. tabs
|
return inv_tab(context.tabs[context.current_tab - 2].listname) .. tabs
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -105,34 +256,36 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
|
-- Get and validate various values
|
||||||
local context = player_interacting_with_digtron_id[player_name]
|
local context = player_interacting_with_digtron_id[player_name]
|
||||||
if context == nil then
|
if context == nil then
|
||||||
minetest.chat_send_all("no context")
|
minetest.log("error", "[Digtron] player_interacting_with_digtron_id context not found for " .. player_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local digtron_id = context.digtron_id
|
local digtron_id = context.digtron_id
|
||||||
if digtron_id == nil then
|
if digtron_id == nil then
|
||||||
minetest.chat_send_all("no id")
|
minetest.log("error", "[Digtron] player_interacting_with_digtron_id context had no digtron id for " .. player_name)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos = digtron.get_pos(digtron_id)
|
local pos = digtron.get_pos(digtron_id)
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
minetest.chat_send_all("no pos")
|
minetest.log("error", "[Digtron] controller was unable to look up a position for digtron id for " .. digtron_id)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local node = minetest.get_node(pos)
|
local node = minetest.get_node(pos)
|
||||||
if node.name ~= "digtron:controller" then
|
if node.name ~= "digtron:controller" then
|
||||||
minetest.chat_send_all("not controller " .. node.name .. " " .. minetest.pos_to_string(pos))
|
minetest.log("error", "[Digtron] player " .. player_name .. " interacted with the controller for "
|
||||||
-- this happened somehow in testing, Digtron needs to be able to recover from this situation.
|
.. digtron_id .. " but the node at " .. minetest.pos_to_string(pos) .. " was a " ..node.name
|
||||||
-- TODO catch this on_rightclick and try remapping the layout to the new position.
|
.. " rather than a digtron:controller")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local current_tab = context.current_tab
|
||||||
local refresh = false
|
local refresh = false
|
||||||
if fields.tab_header then
|
if fields.tab_header then
|
||||||
local new_tab = tonumber(fields.tab_header)
|
local new_tab = tonumber(fields.tab_header)
|
||||||
if new_tab <= #(context.tabs) + 1 then
|
if new_tab <= #(context.tabs) + 2 then
|
||||||
context.current_tab = new_tab
|
context.current_tab = new_tab
|
||||||
refresh = true
|
refresh = true
|
||||||
else
|
else
|
||||||
@ -140,6 +293,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if current_tab == 1 then
|
||||||
|
-- Controls
|
||||||
if fields.disassemble then
|
if fields.disassemble then
|
||||||
local pos = digtron.disassemble(digtron_id, player_name)
|
local pos = digtron.disassemble(digtron_id, player_name)
|
||||||
minetest.close_formspec(player_name, formname)
|
minetest.close_formspec(player_name, formname)
|
||||||
@ -178,7 +333,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
digtron.execute_cycle(digtron_id, player_name)
|
digtron.execute_cycle(digtron_id, player_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
--TODO: this isn't recording the field when using ESC to exit the formspec
|
|
||||||
if fields.key_enter_field == "digtron_name" or fields.digtron_name then
|
if fields.key_enter_field == "digtron_name" or fields.digtron_name then
|
||||||
local pos = digtron.get_pos(digtron_id)
|
local pos = digtron.get_pos(digtron_id)
|
||||||
if pos then
|
if pos then
|
||||||
@ -188,6 +342,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
elseif current_tab == 2 then
|
||||||
|
--Sequencer
|
||||||
|
update_sequence(digtron_id, fields)
|
||||||
|
refresh = true
|
||||||
|
end
|
||||||
|
|
||||||
if refresh then
|
if refresh then
|
||||||
minetest.show_formspec(player_name,
|
minetest.show_formspec(player_name,
|
||||||
"digtron:controller_assembled",
|
"digtron:controller_assembled",
|
||||||
|
@ -91,6 +91,7 @@ local get_table_functions = function(identifier)
|
|||||||
end
|
end
|
||||||
return current
|
return current
|
||||||
end
|
end
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local dispose_func = function(digtron_id)
|
local dispose_func = function(digtron_id)
|
||||||
@ -106,6 +107,8 @@ end
|
|||||||
|
|
||||||
local persist_layout, retrieve_layout = get_table_functions("layout")
|
local persist_layout, retrieve_layout = get_table_functions("layout")
|
||||||
local persist_pos, retrieve_pos, dispose_pos = get_table_functions("pos")
|
local persist_pos, retrieve_pos, dispose_pos = get_table_functions("pos")
|
||||||
|
local persist_sequence, retrieve_sequence = get_table_functions("sequence")
|
||||||
|
local persist_step, retrieve_step = get_table_functions("step") -- actually just an integer, but table_functions works for that too
|
||||||
|
|
||||||
-------------------------------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------------------------------
|
||||||
-- Layout creation helpers
|
-- Layout creation helpers
|
||||||
@ -331,6 +334,7 @@ local assemble = function(root_pos, player_name)
|
|||||||
set_name(digtron_id, digtron_name)
|
set_name(digtron_id, digtron_name)
|
||||||
invalidate_layout_cache(digtron_id)
|
invalidate_layout_cache(digtron_id)
|
||||||
persist_pos(digtron_id, root_pos)
|
persist_pos(digtron_id, root_pos)
|
||||||
|
persist_sequence(digtron_id, {{2,1}}) -- TODO find a better place to set a default like this
|
||||||
|
|
||||||
-- Wipe out the inventories of all in-world nodes, it's stored in the mod_meta now.
|
-- Wipe out the inventories of all in-world nodes, it's stored in the mod_meta now.
|
||||||
-- Wait until now to do it in case the above loop fails partway through.
|
-- Wait until now to do it in case the above loop fails partway through.
|
||||||
@ -1138,7 +1142,13 @@ digtron.set_name = set_name
|
|||||||
digtron.get_pos = retrieve_pos
|
digtron.get_pos = retrieve_pos
|
||||||
digtron.get_bounding_box = retrieve_bounding_box
|
digtron.get_bounding_box = retrieve_bounding_box
|
||||||
|
|
||||||
digtron.retrieve_inventory = retrieve_inventory -- used by formspecs
|
-- used by formspecs
|
||||||
|
digtron.get_inventory = retrieve_inventory
|
||||||
|
digtron.set_sequence = persist_sequence
|
||||||
|
digtron.get_sequence = retrieve_sequence
|
||||||
|
digtron.set_step = persist_step
|
||||||
|
digtron.get_step = retrieve_step
|
||||||
|
|
||||||
|
|
||||||
digtron.assemble = assemble
|
digtron.assemble = assemble
|
||||||
digtron.disassemble = disassemble
|
digtron.disassemble = disassemble
|
||||||
|
Loading…
Reference in New Issue
Block a user