diff --git a/mesecons_autowire/auto_delete.lua b/mesecons_autowire/auto_delete.lua index 9cb4370..59fb081 100644 --- a/mesecons_autowire/auto_delete.lua +++ b/mesecons_autowire/auto_delete.lua @@ -342,6 +342,23 @@ function delete(pos) end +local function delete_all_selection(pos1,pos2) + local xf = math.min(pos1.x,pos2.x) + local xt = math.max(pos1.x,pos2.x) + local zf = math.min(pos1.z,pos2.z) + local zt = math.max(pos1.z,pos2.z) + + for i=xf,xt do + for k = zf,zt do + local cur = { x=i,z=k,y=pos1.y} + minetest.set_node(cur,{name="air"}) + end + end + + +end + + minetest.register_craftitem("mesecons_autowire:delete", { description = "Tool Autodelete", inventory_image = "tool_autodelete.png", @@ -350,13 +367,25 @@ minetest.register_craftitem("mesecons_autowire:delete", { on_place = function(itemstack, user, pointed_thing) local pos = pointed_thing.under - - if( is_wire(pos) ) then - delete(pos) - elseif( is_sticky(pos) ) then - delete(pos) - end + if pointed_thing.type == "node" then + if( is_wire(pos) ) then + delete(pos) + elseif( is_sticky(pos) ) then + delete(pos) + end + end + + end, + on_secondary_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "nothing" then + if check_selection(mesecons_automove.pos1,mesecons_automove.pos2) then + delete_all_selection(mesecons_automove.pos1,mesecons_automove.pos2) + end + + end + end + }) diff --git a/mesecons_autowire/auto_move.lua b/mesecons_autowire/auto_move.lua index c92bf93..3b45fe1 100644 --- a/mesecons_autowire/auto_move.lua +++ b/mesecons_autowire/auto_move.lua @@ -30,7 +30,30 @@ local function sort_xz(p1,p2) return p1,p2 end -local function update_selection() +function update_selection() + if(mesecons_automove.pos1e ~= nil) then + mesecons_automove.pos1e:remove() + mesecons_automove.pos1e = nil + end + if(mesecons_automove.pos2e ~= nil) then + mesecons_automove.pos2e:remove() + mesecons_automove.pos2e = nil + end + + if(mesecons_automove.pos1 ~= nil ) then + mesecons_automove.pos1e = + minetest.add_entity(mesecons_automove.pos1,"mesecons_automove:pos1") + end + if(mesecons_automove.pos2 ~= nil ) then + mesecons_automove.pos2e = + minetest.add_entity(mesecons_automove.pos2,"mesecons_automove:pos2") + end + + +end + +--[[ +function update_selection() if( mesecons_automove.pos1 == nil ) or (mesecons_automove.pos2 == nil ) then return end if( mesecons_automove.pos1 ~= nil ) and (mesecons_automove.pos1e ~= nil ) then @@ -44,6 +67,8 @@ local function update_selection() end +]]-- + function radians_to_vectors(rad) local pi = math.pi if (rad>=0) and (rad<=pi/4) or (rad<=2*pi) and (rad>=(3/2+1/4)*pi) then @@ -518,7 +543,10 @@ minetest.register_tool("mesecons_autowire:select", { on_use = function(itemstack, user, pointed_thing) if pointed_thing == nil then return end if pointed_thing.type == "nothing" then - --move + --unselect + mesecons_automove.pos1 = nil + mesecons_automove.pos2 = nil + update_selection() return elseif pointed_thing.type == "node" then diff --git a/mesecons_autowire/auto_wire.lua b/mesecons_autowire/auto_wire.lua index afbd2e5..8f6e7bc 100644 --- a/mesecons_autowire/auto_wire.lua +++ b/mesecons_autowire/auto_wire.lua @@ -235,6 +235,8 @@ minetest.register_craftitem("mesecons_autowire:wire", { else mesecons_autowire.pos1 = pointed_thing.above end + + print("debug.DB="..dump(mesecons_autowire)) end, on_place = function(itemstack, user, pointed_thing) if not pointed_thing then return end diff --git a/mesecons_autowire/circuit.lua b/mesecons_autowire/circuit.lua new file mode 100644 index 0000000..74d3c6d --- /dev/null +++ b/mesecons_autowire/circuit.lua @@ -0,0 +1,485 @@ +-- support for MT game translation. +local S = default.get_translator + +--[[ +current = pos left bottom +posh = pos right bottom +posv = pos left top +depends where you look at +]]-- + +local function standarise_corners(pos1,pos2,direction) + --assert(pos1.y == pos2.y) TODO: how to solve the problem of selectin not flat region + + local x1,x2,z1,z2,y + y = pos1.y + + x1 = pos1.x + x2 = pos2.x + z1 = pos1.z + z2 = pos2.z + + x1,x2 = math.min(x1,x2), math.max(x1,x2) + z1,z2 = math.min(z1,z2), math.max(z1,z2) + + local p1,p2,p3,p4 + + p1 = { x=x1,y=y,z=z1 } + p2 = { x=x2,y=y,z=z1 } + p3 = { x=x1,y=y,z=z2 } + p4 = { x=x2,y=y,z=z2 } + + if( direction.x == -1 ) then + return p2,p4,p1 + elseif( direction.x == 1 ) then + return p3,p1,p4 + elseif( direction.z == -1 ) then + return p4,p3,p2 + else + return p1,p2,p3 + end +end + + + +local function iter_vectors(direction) + local dx = direction.x + local dz = direction.z + + if( direction.z == 1 ) then + return {x=1,z=0},{x=0,z=1} + elseif( direction.z == -1 ) then + return {x=-1,z=0},{x=0,z=-1} + elseif( direction.x == -1 ) then + return {x=0,z=1},{x=-1,z=0} + else + return {x=0,z=-1},{x=1,z=0} + end +end + + +function check_selection(pos1,pos2) + if( pos1 == nil ) then return false end + if( pos2 == nil ) then return false end + return true +end + +local function add_direct_to_pos(pos,direc) + return { x = pos.x + direc.x , y = pos.y, z = pos.z + direc.z } +end + + + + +local function store_nodes(p1,p2,direction) + + local pos1,pos2 = p1,p2 + local tab = {} + + if( check_selection(pos1,pos2) == false ) then + return nil + end + local corner, maxh, maxv = standarise_corners(pos1,pos2,direction) + local inch,incv = iter_vectors(direction) + + + local i,k = 1,1 + + local cur,curv,curh = corner,corner,corner + + while true do + i = 1 + tab[k] = {} + while true do + tab[k][i] = minetest.get_node(cur) + if( eq_pos(curh,maxh) ) then + break + end + curh = add_direct_to_pos(curh,inch) + cur = add_direct_to_pos(cur, inch) + i = i + 1 + end + + if( eq_pos(curv,maxv) ) then + break + end + curv = add_direct_to_pos(curv,incv) + cur = curv + curh = corner + k = k +1 + end + + --print("["..i.."]["..k.."]="..name) + --print("table = ".. dump(tab)) + return tab + +end + +local function radians_to_direction_looking_forward(rad) + local pi = math.pi + if (rad>=0) and (rad<=pi/4) or (rad<=2*pi) and (rad>=(3/2+1/4)*pi) then + return {x=0, z =1 } + elseif (rad >= 1/4*pi) and (rad <= (1/2+1/4)*pi) then + return {x=-1,z=0} + elseif (rad >= (1-1/4)*pi ) and (rad <= (3/2-1/4)*pi ) then + return {x=0,z=-1} + else + return {x=1,z=0} + end +end + + +local function store_nodes_from_selection(rad) + + local direction = radians_to_direction_looking_forward(rad) + return store_nodes(mesecons_automove.pos1, mesecons_automove.pos2,direction) +end + + + +local function circuit_on_place(itemstack, user, pointed_thing) + print("debug:on_plalce_circuit") +end + + + +local max_text_size = 10000 +local max_title_size = 80 +local short_title_size = 35 + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= "mesecons_autowire:circuit" then return end + + if( fields.save and fields.title ) then + local stack = player:get_wielded_item() + local inv = player:get_inventory() + local new_stack = nil + local meta = stack:get_meta() + local data = meta:to_table().fields + + + + -- if no nodes then save nodes + if not data.nodes then + local rad = player:get_look_horizontal() + local tab = store_nodes_from_selection(rad) + print("tab="..dump(tab)) + if( tab ) then + data.nodes = minetest.serialize(tab) + data.rad = rad + else + return + end + + end + + + print("debug.af="..dump(data)) + + + local count = stack:get_count() + if( count <= 0 ) then return end + if count == 1 then + inv:remove_item("main",stack) + else + stack:set_count(count - 1) + end + new_stack = ItemStack("mesecons_autowire:circuit_full") + + if not fields.text then fields.text = "" end + if not fields.title then fields.title = "" end + + data.title = fields.title:sub(1, max_title_size) + local short_title = data.title + -- Don't bother triming the title if the trailing dots would make it longer + if #short_title > short_title_size + 3 then + short_title = short_title:sub(1, short_title_size) .. "..." + end + data.description = S(short_title) + data.text = fields.text:sub(1, max_text_size) + data.text = data.text:gsub("\r\n", "\n"):gsub("\r", "\n") + + + if new_stack then + + new_stack:get_meta():from_table({ fields = data}) + + if inv:room_for_item("main", new_stack) then + inv:add_item("main", new_stack) + else + minetest.add_item(player:get_pos(), new_stack) + end + end + + + --debug + + + + + end +end) + + + + + +local function show_dialog(itemstack,user,pointed_thing) + local player_name = user:get_player_name() + local formspec + local esc = minetest.formspec_escape + + + local meta = itemstack:get_meta() + local data = meta:to_table().fields + local title, text = data.title or "", data.text or "" + + + + local nodes_string = "empty" + local nodes = minetest.deserialize(data.nodes) + if( nodes ) then + -- show nodes + nodes_string = "size = (".. #nodes[1] .. ","..#nodes .. ")" + + end + + + + formspec = "size[18,8]" .. + "field[0.5,0.5;7.5,1;title;"..S("Name")..";"..S(title).."]".. + "textarea[0.5,1.5;7.5,7;text;" .. esc(S("Description:")) .. ";" .. + esc(S(text)) .. "]" .. + "button_exit[2.5,7.5;3,1;save;" .. esc(S("Save")) .. "]" .. + "label[10,0.5;"..nodes_string.."]".. + "" + minetest.show_formspec(player_name, "mesecons_autowire:circuit", formspec) + return itemstack +end + + + +local function make_selection(nodes,pos,rad) + + if nodes == nil then return end + --if check_selection(mesecons_automove.pos1,mesecons_automove.pos2) == false then return end + + local vsize = #nodes + local hsize = #nodes[1] + + print("dump"..dump(nodes) .. "====" .. dump(pos) .. "===" .. vsize .. "=" .. hsize ) + + local direction = radians_to_direction_looking_forward(rad) + + mesecons_automove.pos1 = pos + + local dx,dz = 0,0 + + print("dumpsirection="..dump(direction)) + hsize = hsize -1 + vsize = vsize -1 + if direction.z == 1 then + dx,dz = hsize,vsize + elseif direction.z == -1 then + dx,dz = -hsize,-vsize + elseif direction.x == 1 then + dx,dz = vsize,-hsize + else + --dirextion.x == -1 + dx,dz = -vsize,hsize + end + + + + + mesecons_automove.pos2 = { x=pos.x + dx, y=pos.y, z = pos.z+dz } + mesecons_automove.rad = rad + + --print("debug.all="..dump(mesecons_automove)) + update_selection() + +end + + +local function direction_to_number(direction) + if( direction.z == 1 ) then + return 1 + elseif( direction.x == 1 ) then + return 2 + elseif(direction.z == -1 )then + return 3 + else + return 4 + end + +end + + +local rotate_exceptions = { + "mesecons_extrawires:crossover_off", + "mesecons_extrawires:crossover_on", + "mesecons_morewires:xjunction_on", + "mesecons_morewires:xjunction_off" +} + +local function is_exception(node) + for _,v in ipairs(rotate_exceptions) do + if( v == node.name ) then + return true + end + end + return false +end + + +local function special_case(node,rotate) + local new_node = node + local applied = false + if( node.name == "mesecons_extrawires:crossover_10") and (rotate % 2 == 1 ) then + new_node.name = "mesecons_extrawires:crossover_01" + new_node.param2 = 0 + return new_node + elseif (node.name == "mesecons_extrawires:crossover_10") and (rotate % 2 == 0 ) then + new_node.name = "mesecons_extrawires:crossover_10" + new_node.param2 = 0 + return new_node + elseif( node.name == "mesecons_extrawires:crossover_01" and (rotate % 2 == 1) ) then + new_node.name = "mesecons_extrawires:crossover_10" + new_node.param2 = 0 + return new_node + elseif ( node.name == "mesecons_extrawires:crossover_01" and (rotate % 2 == 0 ) ) then + new_node.name = "mesecons_extrawires:crossover_01" + new_node.param2 = 0 + return new_node + end + + return nil +end + + +local function rotate_node(node, saved_direction,direction) + if( is_exception(node) ) then return node end + + local values = + { + {0,1,2,3}, + {3,0,1,2}, + {2,3,0,1}, + {1,2,3,0} + } + + local rotate = + values[direction_to_number(saved_direction)][direction_to_number(direction)] + + local new_node = special_case(node,rotate) + if( new_node ~= nil ) then return new_node end + + + new_node = node + new_node.param2 = (node.param2+rotate)%4 + return new_node +end + +local function paste_nodes(nodes,saved_direction,direction) + local pos1,pos2 = mesecons_automove.pos1,mesecons_automove.pos2 + + if( check_selection(pos1,pos2) == false ) then + return nil + end + local corner, maxh, maxv = standarise_corners(pos1,pos2,direction) + local inch,incv = iter_vectors(direction) + + local tab = nodes + if tab == nil then return end + local maxi = #nodes[1] + local maxk = #nodes + + local i,k = 1,1 + + local cur,curv,curh = corner,corner,corner + + while true do + i = 1 + while true do + --tab[k][i] = minetest.get_node(cur) + if( i<=maxi) and (k<=maxk) then + local n = rotate_node(tab[k][i],saved_direction,direction) + minetest.set_node(cur,n) + end + + + + + + if( eq_pos(curh,maxh) ) then + break + end + curh = add_direct_to_pos(curh,inch) + cur = add_direct_to_pos(cur, inch) + i = i + 1 + end + + if( eq_pos(curv,maxv) ) then + break + end + curv = add_direct_to_pos(curv,incv) + cur = curv + curh = corner + k = k +1 + end + +end + + +local function on_use_circuit(itemstack, user, pointed_thing) + if( pointed_thing.type == "node" ) then + -- select region + local nodes = minetest.deserialize(itemstack:get_meta():to_table().fields.nodes) + + local sel_pos + if( is_circuit_element(pointed_thing.under) ) then + sel_pos = pointed_thing.under + else + sel_pos = pointed_thing.above + end + + make_selection(nodes,sel_pos,user:get_look_horizontal()) + else + -- show dialog + show_dialog(itemstack,user,pointed_thing); + end +end + +local function on_place_circuit(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + -- paste + + end + + local data = itemstack:get_meta():to_table() + local nodes = minetest.deserialize(data.fields.nodes) + local rad = tonumber( data.fields.rad ) + paste_nodes(nodes,radians_to_direction_looking_forward(rad), radians_to_direction_looking_forward(mesecons_automove.rad)) +end + + +minetest.register_craftitem("mesecons_autowire:circuit_empty", { + description = S("Circuit empty"), + inventory_image = "circuit_empty.png", + + on_use = on_use_circuit + + }) + +minetest.register_craftitem("mesecons_autowire:circuit_full", { + description = S("Circuit saved"), + inventory_image = "circuit_full.png", + groups = {not_in_creative_inventory = 1}, + stack_max = 1, + on_use = on_use_circuit, + on_place = on_place_circuit, + on_secondary_use = on_place_circuit + + + }) diff --git a/mesecons_autowire/init.lua b/mesecons_autowire/init.lua index 5c34f71..d638eb9 100644 --- a/mesecons_autowire/init.lua +++ b/mesecons_autowire/init.lua @@ -2,4 +2,5 @@ mesecons_autowire = {} dofile(minetest.get_modpath("mesecons_autowire").."/utils.lua"); dofile(minetest.get_modpath("mesecons_autowire").."/auto_delete.lua"); dofile(minetest.get_modpath("mesecons_autowire").."/auto_wire.lua"); -dofile(minetest.get_modpath("mesecons_autowire").."/auto_move.lua"); \ No newline at end of file +dofile(minetest.get_modpath("mesecons_autowire").."/auto_move.lua"); +dofile(minetest.get_modpath("mesecons_autowire").."/circuit.lua"); diff --git a/mesecons_autowire/textures/circuit_empty.png b/mesecons_autowire/textures/circuit_empty.png new file mode 100644 index 0000000..1623d00 Binary files /dev/null and b/mesecons_autowire/textures/circuit_empty.png differ diff --git a/mesecons_autowire/textures/circuit_full.png b/mesecons_autowire/textures/circuit_full.png new file mode 100644 index 0000000..dd73759 Binary files /dev/null and b/mesecons_autowire/textures/circuit_full.png differ diff --git a/mesecons_autowire/textures/picture.png b/mesecons_autowire/textures/picture.png new file mode 100644 index 0000000..702d63b Binary files /dev/null and b/mesecons_autowire/textures/picture.png differ diff --git a/mesecons_autowire/textures/picture_4bit_incrementer.png b/mesecons_autowire/textures/picture_4bit_incrementer.png new file mode 100644 index 0000000..78d447d Binary files /dev/null and b/mesecons_autowire/textures/picture_4bit_incrementer.png differ