2 minetest,vector,math,table,pairs,next
4 minetest,vector,math,table,pairs,next
7 local get_node = minetest.get_node
8 local get_item_group = minetest.get_item_group
9 local get_meta = minetest.get_meta
10 local facedir_to_dir = minetest.facedir_to_dir
11 local content_id = minetest.get_name_from_content_id
12 local get_content_id = minetest.get_content_id
13 local get_voxel_manip = minetest.get_voxel_manip
14 local after = minetest.after
16 local swap_node = minetest.swap_node
17 local registered_nodes
18 minetest.register_on_mods_loaded(function()
19 registered_nodes = minetest.registered_nodes
24 local floor = math.floor
27 local new_vec = vector.new
28 local add_vec = vector.add
29 local sub_vec = vector.subtract
30 local vector_distance = vector.distance
32 --this is written out manually so that
33 --math.abs is not needed
35 {x=1, y=0, z=0}, {x=-1, y=0, z= 0},
36 {x=0, y=0, z=1}, {x= 0, y=0, z=-1},
38 {x=0, y=1, z=0}, {x= 0, y=-1, z=0},
40 {x=1, y=1, z=0}, {x=-1, y=1, z= 0},
41 {x=0, y=1, z=1}, {x= 0, y=1, z=-1},
43 {x=1, y=-1, z=0}, {x=-1, y=-1, z= 0},
44 {x=0, y=-1, z=1}, {x= 0, y=-1, z=-1},
47 --thanks to RhodiumToad for helping me figure out a good method to do this
49 local pool = {} -- this holds all redstone data (literal 3d virtual memory map)
53 local function create_boundary_box(pos)
55 for x = pos.x-9,pos.x+9 do
57 for y = pos.y-9,pos.y+9 do
59 for z = pos.z-9,pos.z+9 do
60 temp_pool = pool[x][y][z]
62 if not table_3d[x] then table_3d[x] = {} end
63 if not table_3d[x][y] then table_3d[x][y] = {} end
65 if x == pos.x-9 or x == pos.x+9 or
66 y == pos.y-9 or y == pos.y+9 or
67 z == pos.z-9 or z == pos.z+9 then
68 if temp_pool.dust then
69 table_3d[x][y][z] = {torch=temp_pool.dust}
71 table_3d[x][y][z] = temp_pool
74 if temp_pool.dust then
75 table_3d[x][y][z] = {dust=0,origin=temp_pool.dust}
77 table_3d[x][y][z] = temp_pool
91 local function data_injection(pos,data)
92 -- add data into 3d memory
94 if not pool[pos.x] then pool[pos.x] = {} end
95 if not pool[pos.x][pos.y] then pool[pos.x][pos.y] = {} end
96 pool[pos.x][pos.y][pos.z] = data
97 --delete data from 3d memory
99 if pool and pool[pos.x] and pool[pos.x][pos.y] then
100 pool[pos.x][pos.y][pos.z] = data
102 --if not pool[pos.x][pos.y] then
103 -- pool[pos.x][pos.y] = nil
104 -- -- only run this if y axis is empty
105 -- if not pool[pos.x] then
117 local path = minetest.get_modpath("redstone")
118 --dofile(path.."/functions.lua")
119 --dofile(path.."/wire.lua")
120 dofile(path.."/torch.lua")
121 --dofile(path.."/lever.lua")
122 --dofile(path.."/button.lua")
123 --dofile(path.."/repeater.lua")
124 --dofile(path.."/light.lua")
125 --dofile(path.."/piston.lua")
126 --dofile(path.."/comparator.lua")
127 --dofile(path.."/craft.lua")
128 --dofile(path.."/ore.lua")
129 --dofile(path.."/inverter.lua")
130 --dofile(path.."/player_detector.lua")
131 --dofile(path.."/space_maker.lua")
132 --dofile(path.."/pressure_plate.lua")
135 --make redstone wire pass on current one level lower than it is
138 local passed_on_level
139 local function redstone_pathfinder(source,source_level,boundary,direction)
140 --directional torches
142 i = add_vec(source,facedir_to_dir(direction))
143 if boundary and boundary[i.x][i.y][i.z] then
144 index = boundary[i.x][i.y][i.z]
147 passed_on_level = source_level - 1
148 if passed_on_level > 0 then
149 boundary[i.x][i.y][i.z].dust = passed_on_level
150 redstone_pathfinder(i,passed_on_level,boundary,nil)
156 for _,order in pairs(order) do
157 i = add_vec(source,new_vec(order.x,order.y,order.z))
158 if i and boundary and boundary[i.x] and boundary[i.x][i.y] and boundary[i.x][i.y][i.z] then
159 index = boundary[i.x][i.y][i.z]
163 passed_on_level = source_level - 1
165 if passed_on_level > 0 and index.dust < source_level then
166 boundary[i.x][i.y][i.z].dust = passed_on_level
168 redstone_pathfinder(i,passed_on_level,boundary,nil)
179 --make all power sources push power out
185 local function calculate(pos)
187 boundary = create_boundary_box(pos)
188 --print(dump(boundary))
190 --pathfind through memory map
191 for x,index_x in pairs(boundary) do
192 for y,index_y in pairs(index_x) do
193 for z,data in pairs(index_y) do
194 --allow data values for torches
196 redstone_pathfinder(new_vec(x,y,z),data.torch,boundary)
197 boundary[x][y][z] = nil
198 elseif data.torch_directional then
199 redstone_pathfinder(new_vec(x,y,z),data.torch,boundary,data.dir)
200 boundary[x][y][z] = nil
206 --reassemble the table into a position list minetest can understand
207 --run through and set dust
208 for x,datax in pairs(boundary) do
209 for y,datay in pairs(datax) do
210 for z,data in pairs(datay) do
212 if data.dust and data.dust ~= data.origin then
213 --print("setting:" ..data.dust)
214 swap_node(new_vec(x,y,z),{name="redstone:dust_"..data.dust})
220 for x,datax in pairs(boundary) do
221 for y,datay in pairs(datax) do
222 for z,data in pairs(datay) do
223 --directional activators
224 if data.directional == true then
225 power = get_powered_state_directional(new_vec(x,y,z))
228 redstone_activate(new_vec(x,y,z),power)
229 elseif power == 0 then
230 redstone_deactivate(new_vec(x,y,z),power)
233 --non directional activators
235 power = get_local_power(new_vec(x,y,z))
239 redstone_activate(new_vec(x,y,z),power)
240 elseif power == 0 then
241 redstone_deactivate(new_vec(x,y,z),power)
250 for x,index_x in pairs(boundary) do
251 for y,index_y in pairs(index_x) do
252 for z,data in pairs(index_y) do
253 --write data back to memory pool
261 function redstone.inject(pos,data)
262 data_injection(pos,data)
266 function redstone.update(pos)
275 ----------------------------------------------------------------------------
309 minetest.register_craftitem("redstone:dust", {
310 description = "Redstone Dust",
311 inventory_image = "redstone_dust_item.png",
312 wield_image = "redstone_dust_item.png",
313 wield_scale = {x = 1, y = 1, z = 1 + 1/16},
314 liquids_pointable = false,
315 on_place = function(itemstack, placer, pointed_thing)
316 if not pointed_thing.type == "node" then
319 local sneak = placer:get_player_control().sneak
320 local noddef = registered_nodes[get_node(pointed_thing.under).name]
321 if not sneak and noddef.on_rightclick then
322 minetest.item_place(itemstack, placer, pointed_thing)
326 local _,worked = minetest.item_place(ItemStack("redstone:dust_0"), placer, pointed_thing)
328 itemstack:take_item()
333 --minetest.add_node(pointed_thing.above, {name="redstone:dust_0"})
334 --itemstack:take_item(1)
335 --minetest.sound_play("stone", {pos=pointed_thing.above})
341 --8 power levels 8 being the highest
344 local coloring = floor(color)
345 minetest.register_node("redstone:dust_"..i,{
346 description = "Redstone Dust",
347 wield_image = "redstone_dust_item.png",
349 "redstone_dust_main.png^[colorize:red:"..coloring, "redstone_turn.png^[colorize:red:"..coloring,
350 "redstone_t.png^[colorize:red:"..coloring, "redstone_cross.png^[colorize:red:"..coloring
353 drawtype = "raillike",
355 sunlight_propagates = true,
356 is_ground_content = false,
358 node_placement_prediction = "",
361 fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
363 sounds = main.stoneSound(),
364 groups={dig_immediate=1,attached_node=1,redstone_dust=1,redstone=1,redstone_power=i},
365 drop="redstone:dust",
366 on_construct = function(pos)
367 data_injection(pos,{dust=i})
370 after_destruct = function(pos)
371 data_injection(pos,nil)
374 connects_to = {"group:redstone"},