]> git.lizzy.rs Git - Crafter.git/blobdiff - mods/redstone/init.lua
Fix possible crashes if null activator index
[Crafter.git] / mods / redstone / init.lua
index 2bb0d25cf0cfe3e7b2782936bda52be08e4cd072..74c4f34f5a593cb1c8703a5a8a9387515999b06a 100644 (file)
@@ -1,3 +1,5 @@
+--if you attempt to read this, god bless you
+
 local 
 minetest,vector,math,table,pairs,next
 =
@@ -22,18 +24,31 @@ end)
 -- math class
 local abs   = math.abs
 local floor = math.floor
+local ceil   = math.ceil
 
 -- vector library
 local new_vec         = vector.new
 local add_vec         = vector.add
 local sub_vec         = vector.subtract
 local vector_distance = vector.distance
+local vec_equals      = vector.equals
 
 local activator_table = {} -- this holds the translation data of activator tables (activator functions)
+local capacitor_table = {}
+local player_detection_table = {}
 
 -- redstone class
 redstone = {}
 
+redstone.player_detector_add = function(pos)
+       player_detection_table[minetest.serialize(pos)] = pos
+end
+
+redstone.player_detector_remove = function(pos)
+       player_detection_table[minetest.serialize(pos)] = nil
+end
+
+
 -- enables mods to create data functions
 function redstone.register_activator(data)
        activator_table[data.name] = {
@@ -42,27 +57,38 @@ function redstone.register_activator(data)
        }
 end
 
+-- enables mods to create data functions
+function redstone.register_capacitor(data)
+       capacitor_table[data.name] = {
+               off = data.off,
+               on  = data.on
+       }
+end
+
 local path = minetest.get_modpath("redstone")
---dofile(path.."/functions.lua")
---dofile(path.."/wire.lua")
+dofile(path.."/functions.lua")
 dofile(path.."/torch.lua")
 dofile(path.."/lever.lua")
 dofile(path.."/button.lua")
 dofile(path.."/repeater.lua")
 dofile(path.."/light.lua")
---dofile(path.."/piston.lua")
+dofile(path.."/piston.lua")
 --dofile(path.."/comparator.lua")
---dofile(path.."/craft.lua")
+dofile(path.."/craft.lua")
 --dofile(path.."/ore.lua")
 dofile(path.."/inverter.lua")
---dofile(path.."/player_detector.lua")
---dofile(path.."/space_maker.lua")
+dofile(path.."/player_detector.lua")
+dofile(path.."/space_maker.lua")
 --dofile(path.."/pressure_plate.lua")
+dofile(path.."/capacitors.lua")
+dofile(path.."/breaker.lua")
 
 
 --this is written out manually so that
 --math.abs is not needed
 local order = {
+       {x=0,y=0,z=0},
+
        {x=1, y=0, z=0}, {x=-1, y=0, z= 0},
        {x=0, y=0, z=1}, {x= 0, y=0, z=-1},
 
@@ -79,23 +105,69 @@ local order = {
 
 local pool = {} -- this holds all redstone data (literal 3d virtual memory map)
 
+
+local function data_injection(pos,data)
+       -- add data into 3d memory
+       if data then
+               if not pool[pos.x] then pool[pos.x] = {} end
+               if not pool[pos.x][pos.y] then pool[pos.x][pos.y] = {} end
+               pool[pos.x][pos.y][pos.z] = data
+       --delete data from 3d memory
+       else
+               if pool and pool[pos.x] and pool[pos.x][pos.y] then
+                       pool[pos.x][pos.y][pos.z] = data
+                       if pool[pos.x][pos.y] and not next(pool[pos.x][pos.y]) then
+                               pool[pos.x][pos.y] = nil
+                               -- only run this if y axis is empty
+                               if pool[pos.x] and not next(pool[pos.x]) then
+                                       pool[pos.x] = nil
+                               end
+                       end
+               end
+       end
+end
+
+--[[
+                                         _ __
+        ___                             | '  \
+   ___  \ /  ___         ,'\_           | .-. \        /|
+   \ /  | |,'__ \  ,'\_  |   \          | | | |      ,' |_   /|
+ _ | |  | |\/  \ \ |   \ | |\_|    _    | |_| |   _ '-. .-',' |_   _
+// | |  | |____| | | |\_|| |__    //    |     | ,'_`. | | '-. .-',' `. ,'\_
+\\_| |_,' .-, _  | | |   | |\ \  //    .| |\_/ | / \ || |   | | / |\  \|   \
+ `-. .-'| |/ / | | | |   | | \ \//     |  |    | | | || |   | | | |_\ || |\_|
+   | |  | || \_| | | |   /_\  \ /      | |`    | | | || |   | | | .---'| |
+   | |  | |\___,_\ /_\ _      //       | |     | \_/ || |   | | | |  /\| |
+   /_\  | |           //_____//       .||`  _   `._,' | |   | | \ `-' /| |
+        /_\           `------'        \ |  /-\ND _     `.\  | |  `._,' /_\
+                                       \|        |HE         `.\
+                                      __        _           _   __  _
+                                     /   |__|  /_\  |\  /| |_) |_  |_)
+                                     \__ |  | /   \ | \/ | |_) |__ | \
+                                             _  _  
+                                                                                       (_)|-   ___     __     __ __ 
+                                                                                                        |  /\ |__)|  |_ (_  
+                                                                                                        | /--\|__)|__|____) 
+]]--
+
+
 local table_3d
 local temp_pool
 local function create_boundary_box(pos)
        table_3d = {}
-       for x = pos.x-9,pos.x+9 do
+       for x = pos.x-16,pos.x+16 do
                if pool[x] then
-                       for y = pos.y-9,pos.y+9 do
+                       for y = pos.y-16,pos.y+16 do
                                if pool[x][y] then
-                                       for z = pos.z-9,pos.z+9 do
+                                       for z = pos.z-16,pos.z+16 do
                                                temp_pool = pool[x][y][z]
                                                if temp_pool then
                                                        if not table_3d[x] then table_3d[x] = {} end
                                                        if not table_3d[x][y] then table_3d[x][y] = {} end
 
-                                                       if (x == pos.x-9 or x == pos.x+9 or 
-                                                       y == pos.y-9 or y == pos.y+9 or 
-                                                       z == pos.z-9 or z == pos.z+9) and 
+                                                       if (x == pos.x-16 or x == pos.x+16 or 
+                                                       y == pos.y-16 or y == pos.y+16 or 
+                                                       z == pos.z-16 or z == pos.z+16) and 
                                                        temp_pool.dust and temp_pool.dust > 1 then
                                                                table_3d[x][y][z] = {torch=temp_pool.dust}
                                                        else
@@ -114,21 +186,67 @@ local function create_boundary_box(pos)
        return(table_3d)
 end
 
-local function data_injection(pos,data)
-       -- add data into 3d memory
-       if data then
-               if not pool[pos.x] then pool[pos.x] = {} end
-               if not pool[pos.x][pos.y] then pool[pos.x][pos.y] = {} end
-               pool[pos.x][pos.y][pos.z] = data
-       --delete data from 3d memory
+local i
+local index
+local function capacitor_pathfind(source,mem_map)
+       for _,order in pairs(order) do
+
+               i = add_vec(source,order)
+               if not mem_map[i.x] then mem_map[i.x] = {} end
+               if not mem_map[i.x][i.y] then mem_map[i.x][i.y] = {} end
+
+               if not mem_map[i.x][i.y][i.z] then
+
+                       if i and pool and pool[i.x] and pool[i.x][i.y] and pool[i.x][i.y][i.z] then
+                               index = pool[i.x][i.y][i.z]
+                               if index.capacitor then
+                                       mem_map[i.x][i.y][i.z] = {name = index.name, capacitor = 0, source = index.source}
+                                       if index.source then
+                                               mem_map.found = true
+                                       end
+                                       capacitor_pathfind(i,mem_map)
+                               end
+                       end
+               end
+       end
+       return mem_map
+end
+
+local table_3d
+local found
+local temp_pool
+local function capacitor_sniff(pos)
+       table_3d = {}
+       table_3d = capacitor_pathfind(pos,table_3d)
+       found = table_3d.found
+       table_3d.found = nil
+       if found then
+               for x,datax in pairs(table_3d) do
+                       for y,datay in pairs(datax) do
+                               for z,data in pairs(datay) do
+                                       temp_pool = pool[x][y][z]
+                                       if temp_pool then
+                                               temp_pool.capacitor = 1
+                                               if capacitor_table[temp_pool.name] then
+                                                       swap_node(new_vec(x,y,z),{name=capacitor_table[temp_pool.name].on})
+                                                       redstone.update(new_vec(x,y,z))
+                                               end
+                                       end
+                               end
+                       end
+               end
        else
-               if pool and pool[pos.x] and pool[pos.x][pos.y] then
-                       pool[pos.x][pos.y][pos.z] = data
-                       if pool[pos.x][pos.y] and not next(pool[pos.x][pos.y]) then
-                               pool[pos.x][pos.y] = nil
-                               -- only run this if y axis is empty
-                               if pool[pos.x] and not next(pool[pos.x]) then
-                                       pool[pos.x] = nil
+               for x,datax in pairs(table_3d) do
+                       for y,datay in pairs(datax) do
+                               for z,data in pairs(datay) do
+                                       temp_pool = pool[x][y][z]
+                                       if temp_pool then
+                                               temp_pool.capacitor = 0
+                                               if capacitor_table[temp_pool.name] then
+                                                       swap_node(new_vec(x,y,z),{name=capacitor_table[temp_pool.name].off})
+                                                       redstone.update(new_vec(x,y,z))
+                                               end
+                                       end
                                end
                        end
                end
@@ -136,29 +254,35 @@ local function data_injection(pos,data)
 end
 
 
+
 -- activators
 local n_pos
 local temp_pool
 local temp_pool2
 local non_directional_activator = function(pos)
-       temp_pool = pool[pos.x][pos.y][pos.z]
-       for _,order in pairs(order) do
-               n_pos = add_vec(pos,order)
-               if pool[n_pos.x] and pool[n_pos.x][n_pos.y] and pool[n_pos.x][n_pos.y][n_pos.z] then
-                       temp_pool2 = pool[n_pos.x][n_pos.y][n_pos.z]
-                       if temp_pool2 then
-                               if (not temp_pool2.directional_activator and temp_pool2.torch) or 
-                               (temp_pool2.dust and temp_pool2.dust > 0) then
-                                       if activator_table[temp_pool.name].activate then
-                                               activator_table[temp_pool.name].activate(pos)
+       if pool[pos.x] and pool[pos.x][pos.y] and pool[pos.x][pos.y][pos.z] then
+               temp_pool = pool[pos.x][pos.y][pos.z]
+               if temp_pool then
+                       for _,order in pairs(order) do
+                               n_pos = add_vec(pos,order)
+                               if pool[n_pos.x] and pool[n_pos.x][n_pos.y] and pool[n_pos.x][n_pos.y][n_pos.z] then
+                                       temp_pool2 = pool[n_pos.x][n_pos.y][n_pos.z]
+                                       if temp_pool2 then
+                                               if (not temp_pool2.directional_activator and temp_pool2.torch) or 
+                                               (temp_pool2.dust and temp_pool2.dust > 0) or 
+                                               (temp_pool2.torch_directional and vector.equals(temp_pool2.output, pos)) then
+                                                       if activator_table[temp_pool.name] and activator_table[temp_pool.name].activate then
+                                                               activator_table[temp_pool.name].activate(pos)
+                                                       end
+                                                       return
+                                               end
                                        end
-                                       return
                                end
+                       end     
+                       if activator_table[temp_pool.name] and activator_table[temp_pool.name].deactivate then
+                               activator_table[temp_pool.name].deactivate(pos)
                        end
                end
-       end     
-       if activator_table[temp_pool.name].deactivate then
-               activator_table[temp_pool.name].deactivate(pos)
        end
 end
 
@@ -172,8 +296,11 @@ local directional_activator = function(pos)
        
        ignore = false
        input = nil
+       temp_pool = nil
        temp_pool2 = nil
 
+       if not (pool[pos.x] and pool[pos.x][pos.y] and pool[pos.x][pos.y][pos.z]) then return end
+       
        temp_pool = pool[pos.x][pos.y][pos.z]
        
        if not temp_pool then ignore = true end
@@ -197,15 +324,15 @@ local directional_activator = function(pos)
        if not temp_pool2 then ignore = true end
 
        if not ignore and ((temp_pool2.dust and temp_pool2.dust > 0) or (temp_pool2.torch and temp_pool2.directional_activator and temp_pool2.dir == temp_pool.dir) or 
-       (not temp_pool2.directional_activator and temp_pool2.torch))  then
-               if activator_table[temp_pool.name].activate then
+       (not temp_pool2.directional_activator and temp_pool2.torch) or (temp_pool2.capacitor and temp_pool2.capacitor > 0))  then
+               if  activator_table[temp_pool.name] and activator_table[temp_pool.name].activate then
                        activator_table[temp_pool.name].activate(pos)
                        return
                end
                return
        end
 
-       if activator_table[temp_pool.name].deactivate then
+       if activator_table[temp_pool.name] and activator_table[temp_pool.name].deactivate then
                activator_table[temp_pool.name].deactivate(pos)
        end
 end
@@ -214,97 +341,296 @@ end
 local i
 local index
 local passed_on_level
-local function redstone_pathfinder(source,source_level,boundary,output)
-       if not source_level then return end
+local x,y,z
+local function redstone_distribute(pos,power,mem_map,output)
+
+       power = power - 1
+
        --directional torches
        if output then
-               i = output
-               if i and boundary and boundary[i.x] and boundary[i.x][i.y] and boundary[i.x][i.y][i.z] then
-                       index = boundary[i.x][i.y][i.z]
-                       --dust
-                       if index.dust then
-                               passed_on_level = source_level - 1
-                               if passed_on_level > 0 then
-                                       boundary[i.x][i.y][i.z].dust = passed_on_level
-                                       redstone_pathfinder(i,passed_on_level,boundary,nil)
-                               end
+               x=output.x
+               y=output.y
+               z=output.z
+               if mem_map.dust[x] and mem_map.dust[x][y] and mem_map.dust[x][y][z] then
+                       if mem_map.dust[x][y][z].dust < power then
+                               mem_map.dust[x][y][z].dust = power
+                               redstone_distribute(new_vec(x,y,z),power,mem_map,nil)
                        end
                end
        else
                --redstone and torch
                for _,order in pairs(order) do
-                       i = add_vec(source,new_vec(order.x,order.y,order.z))
+                       i = add_vec(pos,order)
+                       x=i.x
+                       y=i.y
+                       z=i.z
+                       if mem_map.dust[x] and mem_map.dust[x][y] and mem_map.dust[x][y][z] then
+                               if mem_map.dust[x][y][z].dust < power then
+                                       mem_map.dust[x][y][z].dust = power
+                                       redstone_distribute(new_vec(x,y,z),power,mem_map,nil)
+                               end
+                       end
+               end
+       end
+       return(mem_map)
+end
+
+
+--[[
+                     , 
+                ,.  | \ 
+               |: \ ; :\ 
+               :' ;\| ::\ 
+                \ : | `::\ 
+                _)  |   `:`. 
+              ,' , `.    ;: ; 
+            ,' ;:  ;"'  ,:: |_ 
+           /,   ` .    ;::: |:`-.__ 
+        _,' _o\  ,::.`:' ;  ;   . ' 
+    _,-'           `:.          ;""\, 
+ ,-'                     ,:         `-;, 
+ \,                       ;:           ;--._ 
+  `.______,-,----._     ,' ;:        ,/ ,  ,` 
+         / /,-';'  \     ; `:      ,'/,::.::: 
+       ,',;-'-'_,--;    ;   :.   ,',',;:::::: 
+      ( /___,-'     `.     ;::,,'o/  ,::::::: 
+       `'             )    ;:,'o /  ;"-   -:: 
+                      \__ _,'o ,'         ,:: 
+                         ) `--'       ,..:::: 
+                         ; `.        ,::::::: 
+                          ;  ``::.    ::::::: 
+]]-- sic em boy!
+local i
+local index
+local function dust_sniff(pos,mem_map,boundary,single,origin,ignore)
+       if not single then
+               --print("all position index--")
+               for _,order in pairs(order) do
+                       i = add_vec(pos,order)
+
+                       if not mem_map[i.x] then mem_map[i.x] = {} end
+                       if not mem_map[i.x][i.y] then mem_map[i.x][i.y] = {} end
+
+                       if not mem_map[i.x][i.y][i.z] then
+                               if i and boundary and boundary[i.x] and boundary[i.x][i.y] and boundary[i.x][i.y][i.z] then
+                                       index = boundary[i.x][i.y][i.z]
+
+                                       if index.dust then
+
+                                               mem_map[i.x][i.y][i.z] = true
+
+                                               if not mem_map.dust[i.x] then mem_map.dust[i.x] = {} end
+                                               if not mem_map.dust[i.x][i.y] then mem_map.dust[i.x][i.y] = {} end
+
+                                               mem_map.dust[i.x][i.y][i.z] = index
+
+                                               dust_sniff(i,mem_map,boundary)
+                                       
+                                       elseif index.torch and index.torch > 1 then
+                                               if index.torch_directional and vec_equals(pos,index.output) then
+                                                       
+                                                       mem_map[i.x][i.y][i.z] = true
+
+                                                       if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
+                                                       if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
+
+                                                       mem_map.torch[i.x][i.y][i.z] = index
+
+                                                       
+                                               elseif not index.torch_directional then
+
+                                                       mem_map[i.x][i.y][i.z] = true
+
+                                                       if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
+                                                       if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
+
+                                                       mem_map.torch[i.x][i.y][i.z] = index
+                                               end
+                                       end
+
+                                       if index.activator then
+                                               mem_map[i.x][i.y][i.z] = true
+
+                                               if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
+                                               if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
+
+                                               mem_map.activator[i.x][i.y][i.z] = index
+                                       elseif index.directional_activator and vec_equals(pos,index.input) then
+
+                                               mem_map[i.x][i.y][i.z] = true
+
+                                               if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
+                                               if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
+
+                                               mem_map.activator[i.x][i.y][i.z] = index
+                                       end
+                               end
+                       end
+               end
+       else
+               --print("single position index")
+               
+               i = pos
+
+
+               if not mem_map[i.x] then mem_map[i.x] = {} end
+               if not mem_map[i.x][i.y] then mem_map[i.x][i.y] = {} end
+
+               if not mem_map[i.x][i.y][i.z] then
                        if i and boundary and boundary[i.x] and boundary[i.x][i.y] and boundary[i.x][i.y][i.z] then
                                index = boundary[i.x][i.y][i.z]
                                if index.dust then
-                                       passed_on_level = source_level - 1
-                                       if passed_on_level > 0 and index.dust < source_level then
-                                               boundary[i.x][i.y][i.z].dust = passed_on_level
-                                               redstone_pathfinder(i,passed_on_level,boundary,nil)
+
+                                       mem_map[i.x][i.y][i.z] = true
+
+                                       if not mem_map.dust[i.x] then mem_map.dust[i.x] = {} end
+                                       if not mem_map.dust[i.x][i.y] then mem_map.dust[i.x][i.y] = {} end
+
+                                       mem_map.dust[i.x][i.y][i.z] = index
+
+                                       dust_sniff(i,mem_map,boundary)
+                               
+                               elseif index.torch and index.torch > 1 then
+                                       if index.torch_directional and (vec_equals(origin,index.output) or ignore) then
+                                               
+                                               mem_map[i.x][i.y][i.z] = true
+
+                                               if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
+                                               if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
+
+                                               mem_map.torch[i.x][i.y][i.z] = index
+
+                                               
+                                       elseif not index.torch_directional then
+
+                                               mem_map[i.x][i.y][i.z] = true
+
+                                               if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
+                                               if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
+
+                                               mem_map.torch[i.x][i.y][i.z] = index
                                        end
                                end
+
+                               if index.activator then
+                                       mem_map[i.x][i.y][i.z] = true
+
+                                       if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
+                                       if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
+
+                                       mem_map.activator[i.x][i.y][i.z] = index
+                               elseif index.directional_activator and (vec_equals(origin,index.input) or ignore) then
+
+                                       mem_map[i.x][i.y][i.z] = true
+
+                                       if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
+                                       if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
+
+                                       mem_map.activator[i.x][i.y][i.z] = index
+                               end
                        end
                end
        end
-       return(boundary)
+       return mem_map
 end
 
-
-
-
 --make all power sources push power out
 local pos
 local node
 local power
 local boundary
-local function calculate(pos)
-       boundary = create_boundary_box(pos)
-       --pathfind through memory map   
-       for x,index_x in pairs(boundary) do
-               for y,index_y in pairs(index_x) do
-                       for z,data in pairs(index_y) do
-                               --allow data values for torches
-                               if data.torch and not data.torch_directional then
-                                       redstone_pathfinder(new_vec(x,y,z),data.torch,boundary)
-                                       boundary[x][y][z] = nil
-                               elseif data.torch_directional then
-                                       redstone_pathfinder(new_vec(x,y,z),data.torch,boundary,data.output)
-                               end
+local dust_detected
+local dust_map
+local pos3
+local temp_pool3
+local directional
+local function calculate(pos,is_capacitor)
+       if not is_capacitor then
+               boundary = create_boundary_box(pos)
+               dust_map = {}
+
+               dust_map.dust = {}
+               dust_map.torch = {}
+               dust_map.activator = {}
+
+               dust_detected = false
+
+               directional = false
+
+               if boundary[pos.x] and boundary[pos.x][pos.y] and boundary[pos.x][pos.y][pos.z] then
+                       if boundary[pos.x][pos.y][pos.z].torch_directional or boundary[pos.x][pos.y][pos.z].directional_activator then
+                               directional = true
                        end
                end
-       end
-       --reassemble the table into a position list minetest can understand
-       --run through and set dust
-       for x,datax in pairs(boundary) do
-               for y,datay in pairs(datax) do
-                       for z,data in pairs(datay) do
-                               if data.dust and data.dust ~= data.origin then
-                                       swap_node(new_vec(x,y,z),{name="redstone:dust_"..data.dust})
+
+               -- sniff all possible dust within boundaries
+               if not directional then
+                       dust_sniff(pos,dust_map,boundary)
+                       for _,pos2 in pairs(order) do
+                               pos3 = add_vec(pos,pos2)
+                               if boundary[pos3.x] and boundary[pos3.x][pos3.y] and boundary[pos3.x][pos3.y][pos3.z] and
+                                       not (dust_map[pos3.x] and dust_map[pos3.x][pos3.y] and dust_map[pos3.x][pos3.y][pos3.z]) then
+                                       temp_pool3 = boundary[pos3.x][pos3.y][pos3.z]
+                                       if temp_pool3.dust then
+                                               dust_sniff(pos3,dust_map,boundary)
+                                       end
                                end
+                       end
+               else
+                       dust_sniff(pos,dust_map,boundary,true,pos,true)
 
-                               --write data back to memory pool
-                               pool[x][y][z] = data
+                       local input = boundary[pos.x][pos.y][pos.z].input
+                       local output = boundary[pos.x][pos.y][pos.z].output
 
-                               if data.dust then
-                                       --delete the data to speed up next loop
-                                       boundary[x][y][z] = nil
+                       if input and boundary[input.x] and boundary[input.x][input.y] and boundary[input.x][input.y][input.z] then
+                               dust_sniff(input,dust_map,boundary,true,pos)
+                       end
+                       if output and boundary[output.x] and boundary[output.x][output.y] and boundary[output.x][output.y][output.z] then
+                               dust_sniff(output,dust_map,boundary,true,pos)
+                       end
+               end
+               --do torches
+               for x,datax in pairs(dust_map.torch) do
+                       for y,datay in pairs(datax) do
+                               for z,data in pairs(datay) do
+                                       if data.torch then
+                                               if data.torch_directional then
+                                                       redstone_distribute(new_vec(x,y,z),data.torch,dust_map,data.output)
+                                               else
+                                                       redstone_distribute(new_vec(x,y,z),data.torch,dust_map)
+                                               end
+                                       end
                                end
                        end
                end
-       end
 
-       
-       --this must be done after the memory is written
-       for x,datax in pairs(boundary) do
-               for y,datay in pairs(datax) do
-                       for z,data in pairs(datay) do
-                               if data.directional_activator then
-                                       directional_activator(new_vec(x,y,z))
-                               elseif data.activator then
-                                       non_directional_activator(new_vec(x,y,z))
+               --set dust, set pool memory
+               for x,datax in pairs(dust_map.dust) do
+                       for y,datay in pairs(datax) do
+                               for z,data in pairs(datay) do
+                                       if data.dust and data.dust ~= data.origin then
+                                               swap_node(new_vec(x,y,z),{name="redstone:dust_"..data.dust})
+                                               data_injection(new_vec(x,y,z),data)
+                                       end
+                               end
+                       end
+               end
+               
+               --activators
+               --this must be run at the end
+               for x,datax in pairs(dust_map.activator) do
+                       for y,datay in pairs(datax) do
+                               for z,data in pairs(datay) do
+                                       if data.directional_activator then
+                                               directional_activator(new_vec(x,y,z))
+                                       elseif data.activator then
+                                               non_directional_activator(new_vec(x,y,z))
+                                       end
                                end
                        end
                end
+       else
+               capacitor_sniff(pos)
        end
 end
 
@@ -315,26 +641,67 @@ end
 
 
 local recursion_check = {}
-function redstone.update(pos)
+local bad_node
+function redstone.update(pos,is_capacitor)
        local s_pos = minetest.serialize(pos)
        if not recursion_check[s_pos] then
                recursion_check[s_pos] = 0
        end
        recursion_check[s_pos] = recursion_check[s_pos] + 1
-       --print(recursion_check[s_pos])
-       if recursion_check[s_pos] > 6 then
+       if recursion_check[s_pos] > 25 then
+               --print(recursion_check[s_pos])
                minetest.after(0,function()
-                       minetest.dig_node(pos)
+                       bad_node = minetest.get_node(pos).name
+                       bad_node = minetest.get_node_drops(bad_node, "main:rubypick")
+                       for _,nodey in pairs(bad_node) do
+                               minetest.throw_item(pos,nodey)
+                       end
+                       minetest.remove_node(pos)
                        data_injection(pos,nil)
                        redstone.update(pos)
                end)
                return
        end
 
-       calculate(pos)
+       calculate(pos,is_capacitor)
+end
+
+
+local level
+local pos2
+local power
+local max
+local function player_detector_calculation()
+       for _,pos in pairs(player_detection_table) do
+               level = pool[pos.x][pos.y][pos.z].torch
+               max = 0
+               for _,player in ipairs(minetest.get_connected_players()) do
+                       pos2 = player:get_pos()
+                       power = floor(17-vector_distance(pos2,pos))
+                       if power > 16 then
+                               power = 16
+                       elseif power < 0 then
+                               power = 0
+                       end
+
+                       if power > max then
+                               max = power
+                       end
+               end
+
+               if max ~= level then
+                       swap_node(pos,{name="redstone:player_detector_"..max})
+                       redstone.inject(pos,{
+                               name = "redstone:player_detector_"..max,
+                               torch = max,
+                       })
+                       redstone.update(pos)
+               end
+       end
 end
 
 minetest.register_globalstep(function()
+       player_detector_calculation()
        recursion_check = {}
 end)
 
@@ -395,26 +762,20 @@ minetest.register_craftitem("redstone:dust", {
                        itemstack:take_item()
                        return(itemstack)
                end
-
-
-                       --minetest.add_node(pointed_thing.above, {name="redstone:dust_0"})
-                       --itemstack:take_item(1)
-                       --minetest.sound_play("stone", {pos=pointed_thing.above})
-                       --return(itemstack)
-               --end
        end,
 })
 
---8 power levels 8 being the highest
-local color = 0
-for i = 0,8 do
-       local coloring = floor(color)
+--15 power levels 15 being the highest
+for i = 0,15 do
+
+       local color = floor(255 * (i/15))
+       
        minetest.register_node("redstone:dust_"..i,{
                description = "Redstone Dust",
                wield_image = "redstone_dust_item.png",
                tiles = {
-                       "redstone_dust_main.png^[colorize:red:"..coloring, "redstone_turn.png^[colorize:red:"..coloring,
-                       "redstone_t.png^[colorize:red:"..coloring, "redstone_cross.png^[colorize:red:"..coloring
+                       "redstone_dust_main.png^[colorize:red:"..color, "redstone_turn.png^[colorize:red:"..color,
+                       "redstone_t.png^[colorize:red:"..color, "redstone_cross.png^[colorize:red:"..color
                },
                power=i,
                drawtype = "raillike",
@@ -440,14 +801,13 @@ for i = 0,8 do
                end,
                connects_to = {"group:redstone"},
        })
-       color= color +31.875
 
        minetest.register_lbm({
         name = "redstone:"..i,
                nodenames = {"redstone:dust_"..i},
                run_at_every_load = true,
         action = function(pos)
-            data_injection(pos,{dust=i})
+                       data_injection(pos,{dust=i})
         end,
     })
 end