Maciej 'agaran' Pijanka
2017-03-15 10307f23a78b33af50dc4a5f3d1baafb4ee4b0d9
commit | author | age
ee0765 1
be2f30 2 local S = technic.getter
ee0765 3
83c649 4 local cable_tier = {}
S 5
6 function technic.is_tier_cable(name, tier)
7     return cable_tier[name] == tier
8 end
9
10 function technic.get_cable_tier(name)
11     return cable_tier[name]
12 end
13
c4acb7 14 local function check_connections(pos)
CK 15     -- Build a table of all machines
16     local machines = {}
17     for tier,list in pairs(technic.machines) do
18         for k,v in pairs(list) do
19             machines[k] = v
20         end
21     end
22     local connections = {}
d3f40e 23     local positions = {
CK 24         {x=pos.x+1, y=pos.y,   z=pos.z},
25         {x=pos.x-1, y=pos.y,   z=pos.z},
26         {x=pos.x,   y=pos.y+1, z=pos.z},
27         {x=pos.x,   y=pos.y-1, z=pos.z},
28         {x=pos.x,   y=pos.y,   z=pos.z+1},
29         {x=pos.x,   y=pos.y,   z=pos.z-1}}
30     for _,connected_pos in pairs(positions) do
c4acb7 31         local name = minetest.get_node(connected_pos).name
CK 32         if machines[name] or technic.get_cable_tier(name) then
33             table.insert(connections,connected_pos)
34         end
35     end
36     return connections
37 end
38
39 local function clear_networks(pos)
40     local node = minetest.get_node(pos)
41     local meta = minetest.get_meta(pos)
42     local placed = node.name ~= "air"
43     local positions = check_connections(pos)
44     if #positions < 1 then return end
45     local dead_end = #positions == 1
46     for _,connected_pos in pairs(positions) do
088eea 47         local net = technic.cables[minetest.hash_node_position(connected_pos)]
CK 48         if net and technic.networks[net] then
c4acb7 49             if dead_end and placed then
CK 50                 -- Dead end placed, add it to the network
51                 -- Get the network
52                 local network_id = technic.cables[minetest.hash_node_position(positions[1])]
53                 if not network_id then
54                     -- We're evidently not on a network, nothing to add ourselves to
55                     return
56                 end
57                 local sw_pos = minetest.get_position_from_hash(network_id)
58                 sw_pos.y = sw_pos.y + 1
59                 local network = technic.networks[network_id]
60                 local tier = network.tier
61
62                 -- Actually add it to the (cached) network
63                 -- This is similar to check_node_subp
64                 technic.cables[minetest.hash_node_position(pos)] = network_id
65                 pos.visited = 1
66                 if technic.is_tier_cable(name, tier) then
67                     table.insert(network.all_nodes,pos)
68                 elseif technic.machines[tier][node.name] then
69                     meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
70                     if     technic.machines[tier][node.name] == technic.producer then
71                         table.insert(network.PR_nodes,pos)
72                     elseif technic.machines[tier][node.name] == technic.receiver then
73                         table.insert(network.RE_nodes,pos)
74                     elseif technic.machines[tier][node.name] == technic.producer_receiver then
75                         table.insert(network.PR_nodes,pos)
76                         table.insert(network.RE_nodes,pos)
77                     elseif technic.machines[tier][node.name] == "SPECIAL" and
78                             (pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
79                             from_below then
80                         table.insert(network.SP_nodes,pos)
81                     elseif technic.machines[tier][node.name] == technic.battery then
82                         table.insert(network.BA_nodes,pos)
83                     end
84                 end
85             elseif dead_end and not placed then
86                 -- Dead end removed, remove it from the network
87                 -- Get the network
88                 local network_id = technic.cables[minetest.hash_node_position(positions[1])]
89                 if not network_id then
90                     -- We're evidently not on a network, nothing to add ourselves to
91                     return
92                 end
93                 local network = technic.networks[network_id]
94
95                 -- Search for and remove machine
96                 technic.cables[minetest.hash_node_position(pos)] = nil
97                 for tblname,table in pairs(network) do
98                     if tblname ~= "tier" then
99                         for machinenum,machine in pairs(table) do
100                             if machine.x == pos.x
101                             and machine.y == pos.y
102                             and machine.z == pos.z then
103                                 table[machinenum] = nil
104                             end
105                         end
106                     end
107                 end
108             else
109                 -- Not a dead end, so the whole network needs to be recalculated
110                 for _,v in pairs(technic.networks[net].all_nodes) do
111                     local pos1 = minetest.hash_node_position(v)
112                     technic.cables[pos1] = nil
113                 end
114                 technic.networks[net] = nil
088eea 115             end
d3f40e 116         end
CK 117     end
83c649 118 end
ee0765 119
S 120 function technic.register_cable(tier, size)
121     local ltier = string.lower(tier)
83c649 122     cable_tier["technic:"..ltier.."_cable"] = tier
ee0765 123
83c649 124     local groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2}
ee0765 125
83c649 126     local node_box = {
S 127         type = "connected",
128         fixed          = {-size, -size, -size, size,  size, size},
129         connect_top    = {-size, -size, -size, size,  0.5,  size}, -- y+
130         connect_bottom = {-size, -0.5,  -size, size,  size, size}, -- y-
131         connect_front  = {-size, -size, -0.5,  size,  size, size}, -- z-
132         connect_back   = {-size, -size,  size, size,  size, 0.5 }, -- z+
133         connect_left   = {-0.5,  -size, -size, size,  size, size}, -- x-
134         connect_right  = {-size, -size, -size, 0.5,   size, size}, -- x+
135     }
ee0765 136
83c649 137     minetest.register_node("technic:"..ltier.."_cable", {
S 138         description = S("%s Cable"):format(tier),
139         tiles = {"technic_"..ltier.."_cable.png"},
140         inventory_image = "technic_"..ltier.."_cable_wield.png",
141         wield_image = "technic_"..ltier.."_cable_wield.png",
142         groups = groups,
143         sounds = default.node_sound_wood_defaults(),
144         drop = "technic:"..ltier.."_cable",
145         paramtype = "light",
146         sunlight_propagates = true,
147         drawtype = "nodebox",
148         node_box = node_box,
149         connects_to = {"technic:"..ltier.."_cable",
150             "group:technic_"..ltier, "group:technic_all_tiers"},
151         on_construct = clear_networks,
152         on_destruct = clear_networks,
153     })
ee0765 154 end
S 155
83c649 156
S 157 local function clear_nets_if_machine(pos, node)
ee0765 158     for tier, machine_list in pairs(technic.machines) do
18cae7 159         if machine_list[node.name] ~= nil then
d3f40e 160             return clear_networks(pos)
ee0765 161         end
S 162     end
163 end
164
83c649 165 minetest.register_on_placenode(clear_nets_if_machine)
S 166 minetest.register_on_dignode(clear_nets_if_machine)
ee0765 167