init.lua 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. -- naming scheme: wire:(xp)(zp)(xm)(zm)(xpyp)(zpyp)(xmyp)(zmyp)_on/off
  2. -- where x= x direction, z= z direction, y= y direction, p = +1, m = -1, e.g. xpym = {x=1, y=-1, z=0}
  3. -- The (xp)/(zpyp)/.. statements shall be replaced by either 0 or 1
  4. -- Where 0 means the wire has no visual connection to that direction and
  5. -- 1 means that the wire visually connects to that other node.
  6. -- #######################
  7. -- ## Update wire looks ##
  8. -- #######################
  9. -- self_pos = pos of any mesecon node, from_pos = pos of conductor to getconnect for
  10. local wire_getconnect = function (from_pos, self_pos)
  11. local node = minetest.get_node(self_pos)
  12. if minetest.registered_nodes[node.name]
  13. and minetest.registered_nodes[node.name].mesecons then
  14. -- rules of node to possibly connect to
  15. local rules = {}
  16. if (minetest.registered_nodes[node.name].mesecon_wire) then
  17. rules = mesecon.rules.default
  18. else
  19. rules = mesecon.get_any_rules(node)
  20. end
  21. for _, r in ipairs(mesecon.flattenrules(rules)) do
  22. if (vector.equals(vector.add(self_pos, r), from_pos)) then
  23. return true
  24. end
  25. end
  26. end
  27. return false
  28. end
  29. -- Update this node
  30. local wire_updateconnect = function (pos)
  31. local connections = {}
  32. for _, r in ipairs(mesecon.rules.default) do
  33. if wire_getconnect(pos, vector.add(pos, r)) then
  34. table.insert(connections, r)
  35. end
  36. end
  37. local nid = {}
  38. for _, vec in ipairs(connections) do
  39. -- flat component
  40. if vec.x == 1 then nid[0] = "1" end
  41. if vec.z == 1 then nid[1] = "1" end
  42. if vec.x == -1 then nid[2] = "1" end
  43. if vec.z == -1 then nid[3] = "1" end
  44. -- slopy component
  45. if vec.y == 1 then
  46. if vec.x == 1 then nid[4] = "1" end
  47. if vec.z == 1 then nid[5] = "1" end
  48. if vec.x == -1 then nid[6] = "1" end
  49. if vec.z == -1 then nid[7] = "1" end
  50. end
  51. end
  52. local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0")
  53. ..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0")
  54. local state_suffix = string.find(minetest.get_node(pos).name, "_off") and "_off" or "_on"
  55. minetest.set_node(pos, {name = "mesecons:wire_"..nodeid..state_suffix})
  56. end
  57. local update_on_place_dig = function (pos, node)
  58. -- Update placed node (get_node again as it may have been dug)
  59. local nn = minetest.get_node(pos)
  60. if (minetest.registered_nodes[nn.name])
  61. and (minetest.registered_nodes[nn.name].mesecon_wire) then
  62. wire_updateconnect(pos)
  63. end
  64. -- Update nodes around it
  65. local rules = {}
  66. if minetest.registered_nodes[node.name]
  67. and minetest.registered_nodes[node.name].mesecon_wire then
  68. rules = mesecon.rules.default
  69. else
  70. rules = mesecon.get_any_rules(node)
  71. end
  72. if (not rules) then return end
  73. for _, r in ipairs(mesecon.flattenrules(rules)) do
  74. local np = vector.add(pos, r)
  75. if minetest.registered_nodes[minetest.get_node(np).name]
  76. and minetest.registered_nodes[minetest.get_node(np).name].mesecon_wire then
  77. wire_updateconnect(np)
  78. end
  79. end
  80. end
  81. mesecon.register_autoconnect_hook("wire", update_on_place_dig)
  82. -- ############################
  83. -- ## Wire node registration ##
  84. -- ############################
  85. -- Nodeboxes:
  86. local box_center = {-1/16, -.5, -1/16, 1/16, -.5+1/16, 1/16}
  87. local box_bump1 = { -2/16, -8/16, -2/16, 2/16, -13/32, 2/16 }
  88. local nbox_nid =
  89. {
  90. [0] = {1/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}, -- x positive
  91. [1] = {-1/16, -.5, 1/16, 1/16, -.5+1/16, 8/16}, -- z positive
  92. [2] = {-8/16, -.5, -1/16, -1/16, -.5+1/16, 1/16}, -- x negative
  93. [3] = {-1/16, -.5, -8/16, 1/16, -.5+1/16, -1/16}, -- z negative
  94. [4] = {.5-1/16, -.5+1/16, -1/16, .5, .4999+1/16, 1/16}, -- x positive up
  95. [5] = {-1/16, -.5+1/16, .5-1/16, 1/16, .4999+1/16, .5}, -- z positive up
  96. [6] = {-.5, -.5+1/16, -1/16, -.5+1/16, .4999+1/16, 1/16}, -- x negative up
  97. [7] = {-1/16, -.5+1/16, -.5, 1/16, .4999+1/16, -.5+1/16} -- z negative up
  98. }
  99. local tiles_off = { "mesecons_wire_off.png" }
  100. local tiles_on = { "mesecons_wire_on.png" }
  101. local selectionbox =
  102. {
  103. type = "fixed",
  104. fixed = {-.5, -.5, -.5, .5, -.5+4/16, .5}
  105. }
  106. -- go to the next nodeid (ex.: 01000011 --> 01000100)
  107. local nid_inc = function() end
  108. nid_inc = function (nid)
  109. local i = 0
  110. while nid[i-1] ~= 1 do
  111. nid[i] = (nid[i] ~= 1) and 1 or 0
  112. i = i + 1
  113. end
  114. -- BUT: Skip impossible nodeids:
  115. if ((nid[0] == 0 and nid[4] == 1) or (nid[1] == 0 and nid[5] == 1)
  116. or (nid[2] == 0 and nid[6] == 1) or (nid[3] == 0 and nid[7] == 1)) then
  117. return nid_inc(nid)
  118. end
  119. return i <= 8
  120. end
  121. local function register_wires()
  122. local nid = {}
  123. while true do
  124. -- Create group specifiction and nodeid string (see note above for details)
  125. local nodeid = (nid[0] or "0")..(nid[1] or "0")..(nid[2] or "0")..(nid[3] or "0")
  126. ..(nid[4] or "0")..(nid[5] or "0")..(nid[6] or "0")..(nid[7] or "0")
  127. -- Calculate nodebox
  128. local nodebox = {type = "fixed", fixed={box_center}}
  129. for i=0,7 do
  130. if nid[i] == 1 then
  131. table.insert(nodebox.fixed, nbox_nid[i])
  132. end
  133. end
  134. -- Add bump to nodebox if curved
  135. if (nid[0] == 1 and nid[1] == 1) or (nid[1] == 1 and nid[2] == 1)
  136. or (nid[2] == 1 and nid[3] == 1) or (nid[3] == 1 and nid[0] == 1) then
  137. table.insert(nodebox.fixed, box_bump1)
  138. end
  139. -- If nothing to connect to, still make a nodebox of a straight wire
  140. if nodeid == "00000000" then
  141. nodebox.fixed = {-8/16, -.5, -1/16, 8/16, -.5+1/16, 1/16}
  142. end
  143. local rules = {}
  144. if (nid[0] == 1) then table.insert(rules, vector.new( 1, 0, 0)) end
  145. if (nid[1] == 1) then table.insert(rules, vector.new( 0, 0, 1)) end
  146. if (nid[2] == 1) then table.insert(rules, vector.new(-1, 0, 0)) end
  147. if (nid[3] == 1) then table.insert(rules, vector.new( 0, 0, -1)) end
  148. if (nid[0] == 1) then table.insert(rules, vector.new( 1, -1, 0)) end
  149. if (nid[1] == 1) then table.insert(rules, vector.new( 0, -1, 1)) end
  150. if (nid[2] == 1) then table.insert(rules, vector.new(-1, -1, 0)) end
  151. if (nid[3] == 1) then table.insert(rules, vector.new( 0, -1, -1)) end
  152. if (nid[4] == 1) then table.insert(rules, vector.new( 1, 1, 0)) end
  153. if (nid[5] == 1) then table.insert(rules, vector.new( 0, 1, 1)) end
  154. if (nid[6] == 1) then table.insert(rules, vector.new(-1, 1, 0)) end
  155. if (nid[7] == 1) then table.insert(rules, vector.new( 0, 1, -1)) end
  156. local meseconspec_off = { conductor = {
  157. rules = rules,
  158. state = mesecon.state.off,
  159. onstate = "mesecons:wire_"..nodeid.."_on"
  160. }}
  161. local meseconspec_on = { conductor = {
  162. rules = rules,
  163. state = mesecon.state.on,
  164. offstate = "mesecons:wire_"..nodeid.."_off"
  165. }}
  166. local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1,
  167. not_in_creative_inventory = 1}
  168. local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1}
  169. if nodeid ~= "00000000" then
  170. groups_off["not_in_creative_inventory"] = 1
  171. end
  172. mesecon.register_node(":mesecons:wire_"..nodeid, {
  173. description = "Mesecon",
  174. drawtype = "nodebox",
  175. inventory_image = "mesecons_wire_inv.png",
  176. wield_image = "mesecons_wire_inv.png",
  177. paramtype = "light",
  178. paramtype2 = "facedir",
  179. is_ground_content = false,
  180. sunlight_propagates = true,
  181. selection_box = selectionbox,
  182. node_box = nodebox,
  183. walkable = false,
  184. drop = "mesecons:wire_00000000_off",
  185. mesecon_wire = true,
  186. on_rotate = false,
  187. }, {tiles = tiles_off, mesecons = meseconspec_off, groups = groups_off},
  188. {tiles = tiles_on, mesecons = meseconspec_on, groups = groups_on})
  189. if (nid_inc(nid) == false) then return end
  190. end
  191. end
  192. register_wires()
  193. -- ##############
  194. -- ## Crafting ##
  195. -- ##############
  196. minetest.register_craft({
  197. type = "cooking",
  198. output = "mesecons:wire_00000000_off 2",
  199. recipe = "default:mese_crystal_fragment",
  200. cooktime = 3,
  201. })
  202. minetest.register_craft({
  203. type = "cooking",
  204. output = "mesecons:wire_00000000_off 18",
  205. recipe = "default:mese_crystal",
  206. cooktime = 15,
  207. })
  208. minetest.register_craft({
  209. type = "cooking",
  210. output = "mesecons:wire_00000000_off 162",
  211. recipe = "default:mese",
  212. cooktime = 30,
  213. })