]> git.lizzy.rs Git - Crafter.git/blob - mods/redstone/init.lua
Push all debug info
[Crafter.git] / mods / redstone / init.lua
1 --if you attempt to read this, god bless you
2
3 local 
4 minetest,vector,math,table,pairs,next
5 =
6 minetest,vector,math,table,pairs,next
7
8 -- minetest class
9 local get_node        = minetest.get_node
10 local get_item_group  = minetest.get_item_group
11 local get_meta        = minetest.get_meta
12 local facedir_to_dir  = minetest.facedir_to_dir
13 local content_id      = minetest.get_name_from_content_id
14 local get_content_id  = minetest.get_content_id
15 local get_voxel_manip = minetest.get_voxel_manip
16 local after           = minetest.after
17
18 local swap_node       = minetest.swap_node
19 local registered_nodes
20 minetest.register_on_mods_loaded(function()
21         registered_nodes  = minetest.registered_nodes
22 end)
23
24 -- math class
25 local abs   = math.abs
26 local floor = math.floor
27 local ceil   = math.ceil
28
29 -- vector library
30 local new_vec         = vector.new
31 local add_vec         = vector.add
32 local sub_vec         = vector.subtract
33 local vector_distance = vector.distance
34 local vec_equals      = vector.equals
35
36 local activator_table = {} -- this holds the translation data of activator tables (activator functions)
37 local capacitor_table = {}
38 local player_detection_table = {}
39 local instructions = 0
40
41 -- redstone class
42 redstone = {}
43
44 redstone.max_state = 64 -- the limit to power transmission
45
46 redstone.player_detector_add = function(pos)
47         player_detection_table[minetest.serialize(pos)] = pos
48 end
49
50 redstone.player_detector_remove = function(pos)
51         player_detection_table[minetest.serialize(pos)] = nil
52 end
53
54
55 -- enables mods to create data functions
56 function redstone.register_activator(data)
57         activator_table[data.name] = {
58                 activate   = data.activate,
59                 deactivate = data.deactivate
60         }
61 end
62
63 -- enables mods to create data functions
64 function redstone.register_capacitor(data)
65         capacitor_table[data.name] = {
66                 off = data.off,
67                 on  = data.on
68         }
69 end
70
71 local path = minetest.get_modpath("redstone")
72 dofile(path.."/functions.lua")
73 dofile(path.."/torch.lua")
74 dofile(path.."/lever.lua")
75 dofile(path.."/button.lua")
76 dofile(path.."/repeater.lua")
77 dofile(path.."/light.lua")
78 dofile(path.."/piston.lua")
79 --dofile(path.."/comparator.lua")
80 dofile(path.."/craft.lua")
81 --dofile(path.."/ore.lua")
82 dofile(path.."/inverter.lua")
83 dofile(path.."/player_detector.lua")
84 dofile(path.."/space_maker.lua")
85 --dofile(path.."/pressure_plate.lua")
86 dofile(path.."/capacitors.lua")
87 dofile(path.."/breaker.lua")
88 dofile(path.."/detector.lua")
89
90
91 --this is written out manually so that
92 --math.abs is not needed
93 local order = {
94         {x= 0,y= 0,z= 0},
95         {x= 1,y= 0,z= 0},
96         {x=-1,y= 0,z= 0},
97         {x= 0,y= 0,z= 1},
98         {x= 0,y= 0,z=-1},
99         {x= 0,y= 1,z= 0},
100         {x= 0,y=-1,z= 0},
101         {x= 1,y= 1,z= 0}, 
102         {x=-1,y= 1,z= 0},
103         {x= 0,y= 1,z= 1},
104         {x= 0,y= 1,z=-1},
105         {x= 1,y=-1,z= 0},
106         {x=-1,y=-1,z= 0},
107         {x= 0,y=-1,z= 1},
108         {x= 0,y=-1,z=-1},
109         }
110
111 --thanks to RhodiumToad for helping me figure out a good method to do this
112
113 local pool = {} -- this holds all redstone data (literal 3d virtual memory map)
114
115
116 local function data_injection(pos,data)
117         instructions = instructions + 1
118         -- add data into 3d memory
119         if data then
120                 if not pool[pos.x] then pool[pos.x] = {} end
121                 if not pool[pos.x][pos.y] then pool[pos.x][pos.y] = {} end
122                 pool[pos.x][pos.y][pos.z] = data
123                 instructions = instructions + 1
124                 --print("building 3d memory")
125         --delete data from 3d memory
126         else
127                 if pool and pool[pos.x] and pool[pos.x][pos.y] then
128                         pool[pos.x][pos.y][pos.z] = data
129                         instructions = instructions + 1
130                         --print("deleting 3d memory")
131                         if pool[pos.x][pos.y] and not next(pool[pos.x][pos.y]) then
132                                 pool[pos.x][pos.y] = nil
133                                 instructions = instructions + 1
134                                 -- only run this if y axis is empty
135                                 if pool[pos.x] and not next(pool[pos.x]) then
136                                         pool[pos.x] = nil
137                                         instructions = instructions + 1
138                                 end
139                         end
140                 end
141         end
142 end
143
144 --[[
145                                          _ __
146         ___                             | '  \
147    ___  \ /  ___         ,'\_           | .-. \        /|
148    \ /  | |,'__ \  ,'\_  |   \          | | | |      ,' |_   /|
149  _ | |  | |\/  \ \ |   \ | |\_|    _    | |_| |   _ '-. .-',' |_   _
150 // | |  | |____| | | |\_|| |__    //    |     | ,'_`. | | '-. .-',' `. ,'\_
151 \\_| |_,' .-, _  | | |   | |\ \  //    .| |\_/ | / \ || |   | | / |\  \|   \
152  `-. .-'| |/ / | | | |   | | \ \//     |  |    | | | || |   | | | |_\ || |\_|
153    | |  | || \_| | | |   /_\  \ /      | |`    | | | || |   | | | .---'| |
154    | |  | |\___,_\ /_\ _      //       | |     | \_/ || |   | | | |  /\| |
155    /_\  | |           //_____//       .||`  _   `._,' | |   | | \ `-' /| |
156         /_\           `------'        \ |  /-\ND _     `.\  | |  `._,' /_\
157                                        \|        |HE         `.\
158                                       __        _           _   __  _
159                                      /   |__|  /_\  |\  /| |_) |_  |_)
160                                      \__ |  | /   \ | \/ | |_) |__ | \
161                                              _  _  
162                                                                                         (_)|-   ___     __     __ __ 
163                                                                                                          |  /\ |__)|  |_ (_  
164                                                                                                          | /--\|__)|__|____) 
165 ]]--
166
167
168 local table_3d
169 local temp_pool
170 local r_max = redstone.max_state
171 local function create_boundary_box(pos)
172         instructions = instructions + 1
173         table_3d = {}
174         for x = pos.x-r_max,pos.x+r_max do
175                 instructions = instructions + 1
176                 if pool[x] then
177                         for y = pos.y-r_max,pos.y+r_max do
178                                 instructions = instructions + 1
179                                 if pool[x][y] then
180                                         for z = pos.z-r_max,pos.z+r_max do
181                                                 instructions = instructions + 1
182                                                 temp_pool = pool[x][y][z]
183                                                 instructions = instructions + 1
184                                                 if temp_pool then
185                                                         if not table_3d[x] then table_3d[x] = {} end
186                                                         if not table_3d[x][y] then table_3d[x][y] = {} end
187
188                                                         if (x == pos.x-r_max or x == pos.x+r_max or 
189                                                         y == pos.y-r_max or y == pos.y+r_max or 
190                                                         z == pos.z-r_max or z == pos.z+r_max) and 
191                                                         temp_pool.dust and temp_pool.dust > 1 then
192                                                                 table_3d[x][y][z] = {torch=temp_pool.dust}
193                                                         else
194                                                                 if temp_pool.dust then
195                                                                         table_3d[x][y][z] = {dust=0,origin=temp_pool.dust}
196                                                                 else
197                                                                         table_3d[x][y][z] = temp_pool
198                                                                 end
199                                                         end
200                                                 end
201                                         end
202                                 end
203                         end
204                 end
205         end
206         return(table_3d)
207 end
208
209 local i
210 local index
211 local function capacitor_pathfind(source,mem_map)
212         for _,order in pairs(order) do
213                 
214                 i = add_vec(source,order)
215                 if not mem_map[i.x] then mem_map[i.x] = {} end
216                 if not mem_map[i.x][i.y] then mem_map[i.x][i.y] = {} end
217
218                 if not mem_map[i.x][i.y][i.z] then
219
220                         if i and pool and pool[i.x] and pool[i.x][i.y] and pool[i.x][i.y][i.z] then
221                                 index = pool[i.x][i.y][i.z]
222                                 if index.capacitor then
223                                         mem_map[i.x][i.y][i.z] = {name = index.name, capacitor = 0, source = index.source}
224                                         if index.source then
225                                                 mem_map.found = true
226                                         end
227                                         capacitor_pathfind(i,mem_map)
228                                 end
229                         end
230                 end
231         end
232         return mem_map
233 end
234
235 local table_3d
236 local found
237 local temp_pool
238 local function capacitor_sniff(pos)
239         table_3d = {}
240         table_3d = capacitor_pathfind(pos,table_3d)
241         found = table_3d.found
242         table_3d.found = nil
243         if found then
244                 for x,datax in pairs(table_3d) do
245                         for y,datay in pairs(datax) do
246                                 for z,data in pairs(datay) do
247                                         temp_pool = pool[x][y][z]
248                                         if temp_pool then
249                                                 temp_pool.capacitor = 1
250                                                 if capacitor_table[temp_pool.name] then
251                                                         swap_node(new_vec(x,y,z),{name=capacitor_table[temp_pool.name].on})
252                                                         redstone.update(new_vec(x,y,z))
253                                                 end
254                                         end
255                                 end
256                         end
257                 end
258         else
259                 for x,datax in pairs(table_3d) do
260                         for y,datay in pairs(datax) do
261                                 for z,data in pairs(datay) do
262                                         temp_pool = pool[x][y][z]
263                                         if temp_pool then
264                                                 temp_pool.capacitor = 0
265                                                 if capacitor_table[temp_pool.name] then
266                                                         swap_node(new_vec(x,y,z),{name=capacitor_table[temp_pool.name].off})
267                                                         redstone.update(new_vec(x,y,z))
268                                                 end
269                                         end
270                                 end
271                         end
272                 end
273         end
274 end
275
276
277
278 -- activators
279 local n_pos
280 local temp_pool
281 local temp_pool2
282 local non_directional_activator = function(pos)
283         if pool[pos.x] and pool[pos.x][pos.y] and pool[pos.x][pos.y][pos.z] then
284                 temp_pool = pool[pos.x][pos.y][pos.z]
285                 if temp_pool then
286                         for _,order in pairs(order) do
287                                 n_pos = add_vec(pos,order)
288                                 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
289                                         temp_pool2 = pool[n_pos.x][n_pos.y][n_pos.z]
290                                         if temp_pool2 then
291                                                 if (not temp_pool2.directional_activator and temp_pool2.torch) or 
292                                                 (temp_pool2.dust and temp_pool2.dust > 0) or 
293                                                 (temp_pool2.torch_directional and vector.equals(temp_pool2.output, pos)) then
294                                                         if activator_table[temp_pool.name] and activator_table[temp_pool.name].activate then
295                                                                 activator_table[temp_pool.name].activate(pos)
296                                                         end
297                                                         return
298                                                 end
299                                         end
300                                 end
301                         end     
302                         if activator_table[temp_pool.name] and activator_table[temp_pool.name].deactivate then
303                                 activator_table[temp_pool.name].deactivate(pos)
304                         end
305                 end
306         end
307 end
308
309 -- directional activators
310 local n_pos
311 local temp_pool
312 local temp_pool2
313 local input
314 local ignore
315 local directional_activator = function(pos)
316         
317         ignore = false
318         input = nil
319         temp_pool = nil
320         temp_pool2 = nil
321
322         if not (pool[pos.x] and pool[pos.x][pos.y] and pool[pos.x][pos.y][pos.z]) then return end
323         
324         temp_pool = pool[pos.x][pos.y][pos.z]
325         
326         if not temp_pool then ignore = true end
327
328         if not ignore then
329                 input = temp_pool.input
330         end
331
332         if not input then ignore = true end
333
334         if not ignore then
335                 input = temp_pool.input
336         end
337
338         if not ignore and pool and pool[input.x] and pool[input.x][input.y] and pool[input.x][input.y][input.z] then
339                 temp_pool2 = pool[input.x][input.y][input.z]
340         else
341                 ignore = true
342         end
343
344         if not temp_pool2 then ignore = true end
345
346         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 
347         (not temp_pool2.directional_activator and temp_pool2.torch) or (temp_pool2.capacitor and temp_pool2.capacitor > 0))  then
348                 if  activator_table[temp_pool.name] and activator_table[temp_pool.name].activate then
349                         activator_table[temp_pool.name].activate(pos)
350                         return
351                 end
352                 return
353         end
354
355         if activator_table[temp_pool.name] and activator_table[temp_pool.name].deactivate then
356                 activator_table[temp_pool.name].deactivate(pos)
357         end
358 end
359
360 --make redstone wire pass on current one level lower than it is
361 local i
362 local index
363 local passed_on_level
364 local x,y,z
365 local function redstone_distribute(pos,power,mem_map,output)
366
367         power = power - 1
368
369         --directional torches
370         if output then
371                 x=output.x
372                 y=output.y
373                 z=output.z
374                 if mem_map.dust[x] and mem_map.dust[x][y] and mem_map.dust[x][y][z] then
375                         if mem_map.dust[x][y][z].dust < power then
376                                 mem_map.dust[x][y][z].dust = power
377                                 redstone_distribute(new_vec(x,y,z),power,mem_map,nil)
378                         end
379                 end
380         else
381                 --redstone and torch
382                 for _,order in pairs(order) do
383                         instructions = instructions + 1
384                         i = add_vec(pos,order)
385                         x=i.x
386                         y=i.y
387                         z=i.z
388                         if mem_map.dust[x] and mem_map.dust[x][y] and mem_map.dust[x][y][z] then
389                                 if mem_map.dust[x][y][z].dust < power then
390                                         mem_map.dust[x][y][z].dust = power
391                                         redstone_distribute(new_vec(x,y,z),power,mem_map,nil)
392                                 end
393                         end
394                 end
395         end
396         return(mem_map)
397 end
398
399
400 --[[
401                      , 
402                 ,.  | \ 
403                |: \ ; :\ 
404                :' ;\| ::\ 
405                 \ : | `::\ 
406                 _)  |   `:`. 
407               ,' , `.    ;: ; 
408             ,' ;:  ;"'  ,:: |_ 
409            /,   ` .    ;::: |:`-.__ 
410         _,' _o\  ,::.`:' ;  ;   . ' 
411     _,-'           `:.          ;""\, 
412  ,-'                     ,:         `-;, 
413  \,                       ;:           ;--._ 
414   `.______,-,----._     ,' ;:        ,/ ,  ,` 
415          / /,-';'  \     ; `:      ,'/,::.::: 
416        ,',;-'-'_,--;    ;   :.   ,',',;:::::: 
417       ( /___,-'     `.     ;::,,'o/  ,::::::: 
418        `'             )    ;:,'o /  ;"-   -:: 
419                       \__ _,'o ,'         ,:: 
420                          ) `--'       ,..:::: 
421                          ; `.        ,::::::: 
422                           ;  ``::.    ::::::: 
423 ]]-- sic em boy!
424 local i
425 local index
426 local function dust_sniff(pos,mem_map,boundary,single,origin,ignore)
427         if not single then
428                 --print("all position index--")
429                 for _,order in pairs(order) do
430                         instructions = instructions + 1
431                         i = add_vec(pos,order)
432
433                         if not mem_map[i.x] then mem_map[i.x] = {} end
434                         if not mem_map[i.x][i.y] then mem_map[i.x][i.y] = {} end
435
436                         if not mem_map[i.x][i.y][i.z] then
437                                 if i and boundary and boundary[i.x] and boundary[i.x][i.y] and boundary[i.x][i.y][i.z] then
438                                         index = boundary[i.x][i.y][i.z]
439
440                                         if index.dust then
441
442                                                 mem_map[i.x][i.y][i.z] = true
443
444                                                 if not mem_map.dust[i.x] then mem_map.dust[i.x] = {} end
445                                                 if not mem_map.dust[i.x][i.y] then mem_map.dust[i.x][i.y] = {} end
446
447                                                 mem_map.dust[i.x][i.y][i.z] = index
448
449                                                 dust_sniff(i,mem_map,boundary)
450                                         
451                                         elseif index.torch and index.torch > 1 then
452                                                 if index.torch_directional and vec_equals(pos,index.output) then
453                                                         
454                                                         mem_map[i.x][i.y][i.z] = true
455
456                                                         if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
457                                                         if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
458
459                                                         mem_map.torch[i.x][i.y][i.z] = index
460
461                                                         
462                                                 elseif not index.torch_directional then
463
464                                                         mem_map[i.x][i.y][i.z] = true
465
466                                                         if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
467                                                         if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
468
469                                                         mem_map.torch[i.x][i.y][i.z] = index
470                                                 end
471                                         end
472
473                                         if index.activator then
474                                                 mem_map[i.x][i.y][i.z] = true
475
476                                                 if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
477                                                 if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
478
479                                                 mem_map.activator[i.x][i.y][i.z] = index
480                                         elseif index.directional_activator and vec_equals(pos,index.input) then
481
482                                                 mem_map[i.x][i.y][i.z] = true
483
484                                                 if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
485                                                 if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
486
487                                                 mem_map.activator[i.x][i.y][i.z] = index
488                                         end
489                                 end
490                         end
491                 end
492         else
493                 --print("single position index")
494                 
495                 i = pos
496
497
498                 if not mem_map[i.x] then mem_map[i.x] = {} end
499                 if not mem_map[i.x][i.y] then mem_map[i.x][i.y] = {} end
500
501                 if not mem_map[i.x][i.y][i.z] then
502                         if i and boundary and boundary[i.x] and boundary[i.x][i.y] and boundary[i.x][i.y][i.z] then
503                                 index = boundary[i.x][i.y][i.z]
504                                 if index.dust then
505
506                                         mem_map[i.x][i.y][i.z] = true
507
508                                         if not mem_map.dust[i.x] then mem_map.dust[i.x] = {} end
509                                         if not mem_map.dust[i.x][i.y] then mem_map.dust[i.x][i.y] = {} end
510
511                                         mem_map.dust[i.x][i.y][i.z] = index
512
513                                         dust_sniff(i,mem_map,boundary)
514                                 
515                                 elseif index.torch and index.torch > 1 then
516                                         if index.torch_directional and (vec_equals(origin,index.output) or ignore) then
517                                                 
518                                                 mem_map[i.x][i.y][i.z] = true
519
520                                                 if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
521                                                 if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
522
523                                                 mem_map.torch[i.x][i.y][i.z] = index
524
525                                                 
526                                         elseif not index.torch_directional then
527
528                                                 mem_map[i.x][i.y][i.z] = true
529
530                                                 if not mem_map.torch[i.x] then mem_map.torch[i.x] = {} end
531                                                 if not mem_map.torch[i.x][i.y] then mem_map.torch[i.x][i.y] = {} end
532
533                                                 mem_map.torch[i.x][i.y][i.z] = index
534                                         end
535                                 end
536
537                                 if index.activator then
538                                         mem_map[i.x][i.y][i.z] = true
539
540                                         if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
541                                         if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
542
543                                         mem_map.activator[i.x][i.y][i.z] = index
544                                 elseif index.directional_activator and (vec_equals(origin,index.input) or ignore) then
545
546                                         mem_map[i.x][i.y][i.z] = true
547
548                                         if not mem_map.activator[i.x] then mem_map.activator[i.x] = {} end
549                                         if not mem_map.activator[i.x][i.y] then mem_map.activator[i.x][i.y] = {} end
550
551                                         mem_map.activator[i.x][i.y][i.z] = index
552                                 end
553                         end
554                 end
555         end
556         return mem_map
557 end
558
559 --make all power sources push power out
560 local pos
561 local node
562 local power
563 local boundary
564 local dust_detected
565 local dust_map
566 local pos3
567 local temp_pool3
568 local directional
569 local function calculate(pos,is_capacitor)
570         if not is_capacitor then
571                 boundary = create_boundary_box(pos)
572                 dust_map = {}
573
574                 dust_map.dust = {}
575                 dust_map.torch = {}
576                 dust_map.activator = {}
577
578                 dust_detected = false
579
580                 directional = false
581
582                 if boundary[pos.x] and boundary[pos.x][pos.y] and boundary[pos.x][pos.y][pos.z] then
583                         if boundary[pos.x][pos.y][pos.z].torch_directional or boundary[pos.x][pos.y][pos.z].directional_activator then
584                                 directional = true
585                         end
586                 end
587
588                 -- sniff all possible dust within boundaries
589                 if not directional then
590                         dust_sniff(pos,dust_map,boundary)
591                         for _,pos2 in pairs(order) do
592                                 pos3 = add_vec(pos,pos2)
593                                 if boundary[pos3.x] and boundary[pos3.x][pos3.y] and boundary[pos3.x][pos3.y][pos3.z] and
594                                         not (dust_map[pos3.x] and dust_map[pos3.x][pos3.y] and dust_map[pos3.x][pos3.y][pos3.z]) then
595                                         temp_pool3 = boundary[pos3.x][pos3.y][pos3.z]
596                                         if temp_pool3.dust then
597                                                 dust_sniff(pos3,dust_map,boundary)
598                                         end
599                                 end
600                         end
601                 else
602                         dust_sniff(pos,dust_map,boundary,true,pos,true)
603
604                         local input = boundary[pos.x][pos.y][pos.z].input
605                         local output = boundary[pos.x][pos.y][pos.z].output
606
607                         if input and boundary[input.x] and boundary[input.x][input.y] and boundary[input.x][input.y][input.z] then
608                                 dust_sniff(input,dust_map,boundary,true,pos)
609                         end
610                         if output and boundary[output.x] and boundary[output.x][output.y] and boundary[output.x][output.y][output.z] then
611                                 dust_sniff(output,dust_map,boundary,true,pos)
612                         end
613                 end
614                 --do torches
615                 for x,datax in pairs(dust_map.torch) do
616                         for y,datay in pairs(datax) do
617                                 for z,data in pairs(datay) do
618                                         if data.torch then
619                                                 if data.torch_directional then
620                                                         redstone_distribute(new_vec(x,y,z),data.torch,dust_map,data.output)
621                                                 else
622                                                         redstone_distribute(new_vec(x,y,z),data.torch,dust_map)
623                                                 end
624                                         end
625                                 end
626                         end
627                 end
628
629                 --set dust, set pool memory
630                 for x,datax in pairs(dust_map.dust) do
631                         for y,datay in pairs(datax) do
632                                 for z,data in pairs(datay) do
633                                         if data.dust and data.dust ~= data.origin then
634                                                 swap_node(new_vec(x,y,z),{name="redstone:dust_"..data.dust})
635                                                 data_injection(new_vec(x,y,z),data)
636                                         end
637                                 end
638                         end
639                 end
640                 
641                 --activators
642                 --this must be run at the end
643                 for x,datax in pairs(dust_map.activator) do
644                         for y,datay in pairs(datax) do
645                                 for z,data in pairs(datay) do
646                                         if data.directional_activator then
647                                                 directional_activator(new_vec(x,y,z))
648                                         elseif data.activator then
649                                                 non_directional_activator(new_vec(x,y,z))
650                                         end
651                                 end
652                         end
653                 end
654         else
655                 capacitor_sniff(pos)
656         end
657 end
658
659
660 function redstone.inject(pos,data)
661         data_injection(pos,data)
662 end
663
664
665
666 local level
667 local pos2
668 local power
669 local max
670 local function player_detector_calculation()
671         for _,pos in pairs(player_detection_table) do
672                 level = pool[pos.x][pos.y][pos.z].torch
673                 max = 0
674                 for _,player in ipairs(minetest.get_connected_players()) do
675                         pos2 = player:get_pos()
676                         power = floor(11-vector_distance(pos2,pos))
677                         if power > r_max then
678                                 power = r_max
679                         elseif power < 0 then
680                                 power = 0
681                         end
682
683                         if power > max then
684                                 max = power
685                         end
686                 end
687
688                 if max ~= level then
689                         swap_node(pos,{name="redstone:player_detector_"..max})
690                         redstone.inject(pos,{
691                                 name = "redstone:player_detector_"..max,
692                                 torch = max,
693                         })
694                         redstone.update(pos)
695                 end
696         end
697 end
698
699
700 local recursion_check = {}
701 local bad_node
702 local queue = {}
703 function redstone.update(pos,is_capacitor)
704         local count = table.getn(queue)
705         local s_pos = minetest.serialize(pos)
706         if not recursion_check[s_pos] then
707                 recursion_check[s_pos] = 0
708         end
709         recursion_check[s_pos] = recursion_check[s_pos] + 1
710         if recursion_check[s_pos] > 25 then
711                 --print(recursion_check[s_pos])
712                 minetest.after(0,function()
713                         bad_node = minetest.get_node(pos).name
714                         bad_node = minetest.get_node_drops(bad_node, "main:rubypick")
715                         for _,nodey in pairs(bad_node) do
716                                 minetest.throw_item(pos,nodey)
717                         end
718                         minetest.remove_node(pos)
719                         data_injection(pos,nil)
720                         redstone.update(pos)
721                 end)
722                 return
723         end
724         calculate(pos,is_capacitor)
725 end
726 local dtime_goal = 0.02
727 local sleep = 0
728 minetest.register_globalstep(function(dtime)
729         player_detector_calculation()
730         recursion_check = {}
731         --[[
732         if dtime > dtime_goal then
733                 sleep = dtime - dtime_goal
734         end
735
736         if sleep == 0 then
737
738                 for index,element in pairs(queue) do
739                         calculate(element.pos,element.is_capacitor)
740                 end
741
742                 queue = {}
743                 
744         else
745                 sleep = sleep - dtime
746                 if sleep <= 0 then
747                         sleep = 0
748                 end
749         end
750         ]]--
751         if instructions and instructions > 0 then
752                 print(instructions)
753         end
754         instructions = 0
755 end)
756
757
758 ----------------------------------------------------------------------------
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792 minetest.register_craftitem("redstone:dust", {
793         description = "Redstone Dust",
794         inventory_image = "redstone_dust_item.png",
795         wield_image = "redstone_dust_item.png",
796         wield_scale = {x = 1, y = 1, z = 1 + 1/16},
797         liquids_pointable = false,
798         on_place = function(itemstack, placer, pointed_thing)
799                 if not pointed_thing.type == "node" then
800                         return
801                 end             
802                 local sneak = placer:get_player_control().sneak
803                 local noddef = registered_nodes[get_node(pointed_thing.under).name]
804                 if not sneak and noddef.on_rightclick then
805                         minetest.item_place(itemstack, placer, pointed_thing)
806                         return
807                 end
808                 
809                 local _,worked = minetest.item_place(ItemStack("redstone:dust_0"), placer, pointed_thing)
810                 if worked then
811                         itemstack:take_item()
812                         return(itemstack)
813                 end
814         end,
815 })
816
817 --power levels r_max-1 being the highest
818 local d_max = r_max-1
819 for i = 0,d_max do
820
821         local color = floor(255 * (i/d_max))
822         
823         minetest.register_node("redstone:dust_"..i,{
824                 description = "Redstone Dust",
825                 wield_image = "redstone_dust_item.png",
826                 tiles = {
827                         "redstone_dust_main.png^[colorize:red:"..color, "redstone_turn.png^[colorize:red:"..color,
828                         "redstone_t.png^[colorize:red:"..color, "redstone_cross.png^[colorize:red:"..color
829                 },
830                 power=i,
831                 drawtype = "raillike",
832                 paramtype = "light",
833                 sunlight_propagates = true,
834                 is_ground_content = false,
835                 walkable = false,
836                 node_placement_prediction = "",
837                 selection_box = {
838                         type = "fixed",
839                         fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
840                 },
841                 sounds = main.stoneSound(),
842                 groups={dig_immediate=1,attached_node=1,redstone_dust=1,redstone=1,redstone_power=i},
843                 drop="redstone:dust",
844                 on_construct = function(pos)
845                         data_injection(pos,{dust=i})
846                         calculate(pos)
847                 end,
848                 after_destruct = function(pos)                  
849                         data_injection(pos,nil)
850                         calculate(pos)
851                 end,
852                 connects_to = {"group:redstone"},
853         })
854
855         minetest.register_lbm({
856         name = "redstone:"..i,
857                 nodenames = {"redstone:dust_"..i},
858                 run_at_every_load = true,
859         action = function(pos)
860                         data_injection(pos,{dust=i})
861         end,
862     })
863 end