Advertisement
Guest User

Untitled

a guest
Oct 21st, 2017
65
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 83.72 KB | None | 0 0
  1. local data = {}
  2. local classes = {}
  3. local selected = {}
  4.  
  5. function save()
  6.   global["uc_data"] = data
  7. end
  8.  
  9. classes["timer-combinator"] = {
  10.   on_click = function(player, object)
  11.     local gui = player.gui.center.uc["timer-combinator"]
  12.     object.meta.reset = tonumber(gui["reset"].text) or object.meta.reset
  13.     object.meta.ticks = tonumber(gui["ticks"].text) or object.meta.ticks
  14.     if object.meta.running then
  15.       object.meta.running = false
  16.     end
  17.     object.meta.count = 0
  18.   end,
  19.   on_key = function(player, object)
  20.     if not (player.gui.center["uc"]) then
  21.       local gui = player.gui.center
  22.       local uc = gui.add{type = "frame", name = "uc", caption = "Timer Combinator"}
  23.       local layout = uc.add{type = "table", name = "timer-combinator", colspan = 2}
  24.       layout.add{type = "label", caption = "Reset Count: (?)", tooltip = {"timer-combinator.reset"}}
  25.       layout.add{type = "textfield", name = "reset", style = "uc_text", text = object.meta.reset}
  26.       layout.add{type = "label", caption = "Update Interval: (?)", tooltip = {"timer-combinator.ticks"}}
  27.       layout.add{type = "textfield", name = "ticks", style = "uc_text", text = object.meta.ticks}
  28.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  29.       layout.add{type = "label", caption = "(extra info)", tooltip = {"timer-combinator.extra"}}
  30.     end
  31.   end,
  32.   on_place = function(entity)
  33.     return {
  34.       meta = {
  35.         entity = entity,
  36.         count = 0,
  37.         reset = 10,
  38.         running = false,
  39.         ticks = 60
  40.       }
  41.     }
  42.   end,
  43.   on_destroy = function() end,
  44.   on_tick = function(object)
  45.     local control = object.meta.entity.get_control_behavior()
  46.     if control then
  47.       if control.enabled then
  48.         if get_count(control, {type = "virtual", name = "start-signal"}) > 0 then
  49.           object.meta.running = true
  50.         end
  51.         if get_count(control, {type = "virtual", name = "stop-signal"}) > 0 then
  52.           object.meta.running = false
  53.         end
  54.         if object.meta.running then
  55.           if (object.meta.ticks < 1) then object.meta.ticks = 1 end
  56.           if (object.meta.ticks > 3600) then object.meta.ticks = 3600 end
  57.           if (game.tick % object.meta.ticks) == 0 then
  58.             object.meta.count = object.meta.count + 1
  59.             if object.meta.count > object.meta.reset then
  60.               object.meta.count = 0
  61.             end
  62.             control.parameters = {
  63.               parameters = {
  64.                 {signal = {type = "virtual", name = "counting-signal"}, count = object.meta.count, index = 1}
  65.               }
  66.             }
  67.           end
  68.         end
  69.       else
  70.         control.parameters = {
  71.           parameters = {
  72.             {signal = {type = "virtual", name = "counting-signal"}, count = 0, index = 1}
  73.           }
  74.         }
  75.       end
  76.     end
  77.   end
  78. }
  79.  
  80. classes["counting-combinator"] = {
  81.   on_click = function(player, object)
  82.     local gui = player.gui.center.uc["counting-combinator"]
  83.     object.meta.reset = tonumber(gui["reset"].text) or object.meta.reset
  84.   end,
  85.   on_key = function(player, object)
  86.     if not (player.gui.center["uc"]) then
  87.       local params = object.meta.params
  88.       local gui = player.gui.center
  89.       local uc = gui.add{type = "frame", name = "uc", caption = "Counting Combinator"}
  90.       local layout = uc.add{type = "table", name = "counting-combinator", colspan = 2}
  91.       layout.add{type = "label", caption = "Reset: (?)", tooltip = {"counting-combinator.reset"}}
  92.       layout.add{type = "textfield", name = "reset", style = "uc_text", text = object.meta.reset}
  93.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  94.       layout.add{type = "label", caption = "(extra info)", tooltip = {"counting-combinator.extra"}}
  95.     end
  96.   end,
  97.   on_place = function(entity)
  98.   return {
  99.     meta = {
  100.         entity = entity,
  101.         count = 0,
  102.         reset = -1
  103.       }
  104.     }
  105.   end,
  106.   on_destroy = function() end,
  107.   on_tick = function(object)
  108.     local control = object.meta.entity.get_control_behavior()
  109.     if control then
  110.       if control.enabled then
  111.         if (object.meta.reset < -1) then object.meta.reset = -1 end
  112.         if (object.meta.count < 0) then object.meta.count = 0 end
  113.         if object.meta.reset > -1 and object.meta.count > object.meta.reset then
  114.           object.meta.count = 0
  115.         end
  116.         object.meta.count = object.meta.count - get_count(control, {type = "virtual", name = "minus-one-signal"})
  117.         object.meta.count = object.meta.count + get_count(control, {type = "virtual", name = "plus-one-signal"})
  118.         if object.meta.reset > -1 and object.meta.count == -1 then
  119.           object.meta.count = object.meta.reset
  120.         end
  121.         control.parameters = {
  122.           parameters = {
  123.             {signal = {type = "virtual", name = "counting-signal"}, count = object.meta.count, index = 1}
  124.           }
  125.         }
  126.       end
  127.     else
  128.       control.parameters = {
  129.         parameters = {
  130.           {signal = {type = "virtual", name = "counting-signal"}, count = 0, index = 1}
  131.         }
  132.       }
  133.     end
  134.   end
  135. }
  136.  
  137. classes["random-combinator"] = {
  138.   on_click = function(player, object)
  139.     local params = object.meta.params
  140.     local gui = player.gui.center.uc["random-combinator"]
  141.     if gui["signal1"].elem_value and gui["signal1"].elem_value.name then
  142.       object.meta.params[1] = {signal = gui["signal1"].elem_value}
  143.     else
  144.       object.meta.params[1] = {signal = {type = "virtual"}}
  145.     end
  146.     if gui["signal2"].elem_value and gui["signal2"].elem_value.name then
  147.       object.meta.params[2] = {signal = gui["signal2"].elem_value}
  148.     else
  149.       object.meta.params[2] = {signal = {type = "virtual"}}
  150.     end
  151.     object.meta.range.minimum = tonumber(gui["lower"].text) or object.meta.range.minimum
  152.     object.meta.range.maximum = tonumber(gui["upper"].text) or object.meta.range.maximum
  153.     object.meta.ticks = tonumber(gui["ticks"].text) or object.meta.ticks
  154.   end,
  155.   on_key = function(player, object)
  156.     if not (player.gui.center["uc"]) then
  157.       local params = object.meta.params
  158.       local gui = player.gui.center
  159.       local uc = gui.add{type = "frame", name = "uc", caption = "Random Combinator"}
  160.       local layout = uc.add{type = "table", name = "random-combinator", colspan = 2}
  161.       layout.add{type = "label", caption = "Trigger: (?)", tooltip = {"random-combinator.trigger"}}
  162.       if params[1].signal and params[1].signal.name then
  163.         layout.add{type = "choose-elem-button", name = "signal1", elem_type = "signal", signal = params[1].signal}
  164.       else
  165.         layout.add{type = "choose-elem-button", name = "signal1", elem_type = "signal"}
  166.       end
  167.       layout.add{type = "label", caption = "Output: (?)", tooltip = {"random-combinator.output"}}
  168.       if params[2].signal and params[2].signal.name then
  169.         layout.add{type = "choose-elem-button", name = "signal2", elem_type = "signal", signal = params[2].signal}
  170.       else
  171.         layout.add{type = "choose-elem-button", name = "signal2", elem_type = "signal"}
  172.       end
  173.       layout.add{type = "label", caption = "Lower Limit: (?)", tooltip = {"random-combinator.lower"}}
  174.       layout.add{type = "textfield", name = "lower", style = "uc_text", text = object.meta.range.minimum}
  175.       layout.add{type = "label", caption = "Upper  Limit: (?)", tooltip = {"random-combinator.upper"}}
  176.       layout.add{type = "textfield", name = "upper", style = "uc_text", text = object.meta.range.maximum}
  177.       layout.add{type = "label", caption = "Ticks: (?)", tooltip = {"random-combinator.ticks"}}
  178.       layout.add{type = "textfield", name = "ticks", style = "uc_text", text = object.meta.ticks}
  179.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  180.     end
  181.   end,
  182.   on_place = function(entity)
  183.   return {
  184.     meta = {
  185.         entity = entity,
  186.         params = {
  187.           {signal = {type = "virtual", name = "input-signal"}},
  188.           {signal = {type = "virtual", name = "output-signal"}, count = 0},
  189.         },
  190.         range = {
  191.           minimum = 1,
  192.           maximum = 10
  193.         },
  194.         ticks = 60
  195.       }
  196.     }
  197.   end,
  198.   on_destroy = function() end,
  199.   on_tick = function(object)
  200.     local control = object.meta.entity.get_control_behavior()
  201.     if control then
  202.       local params = object.meta.params
  203.       if params[1].signal and params[1].signal.name then
  204.         if control.enabled then
  205.           if object.meta.range.minimum < 1 then object.meta.range.minimum = 1 end
  206.           if object.meta.range.maximum <= object.meta.range.minimum then object.meta.range.maximum = object.meta.range.minimum + 1 end
  207.           if object.meta.ticks < 1 then object.meta.ticks = 1 end
  208.           if object.meta.ticks > 180 then object.meta.ticks = 180 end
  209.           local count = control.parameters.parameters[1].count or 0
  210.           if get_count(control, params[1].signal) >= 1 then
  211.             count = math.random(object.meta.range.minimum,object.meta.range.maximum)
  212.           end
  213.           if (game.tick % object.meta.ticks) == 0 then
  214.             control.parameters = {
  215.               parameters = {
  216.                 {signal = params[2].signal, count = count, index = 1}
  217.               }
  218.             }
  219.           end
  220.         end
  221.       else
  222.         control.parameters = {
  223.           parameters = {
  224.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  225.           }
  226.         }
  227.       end
  228.     end
  229.   end
  230. }
  231. -- Increased from 5 to 8
  232. classes["min-combinator"] = {
  233.   on_click = function(player, object)
  234.     local params = object.meta.params
  235.     local gui = player.gui.center.uc["min-combinator"]
  236.     for i = 1,8 do
  237.       if gui["signal"..i].elem_value and gui["signal"..i].elem_value.name then
  238.         object.meta.params[i] = {signal = gui["signal"..i].elem_value}
  239.       else
  240.         object.meta.params[i] = {signal = {type = "virtual"}}
  241.       end
  242.     end
  243.   end,
  244.   on_key = function(player, object)
  245.     if not (player.gui.center["uc"]) then
  246.       local params = object.meta.params
  247.       local gui = player.gui.center
  248.       local uc = gui.add{type = "frame", name = "uc", caption = "Min Combinator"}
  249.       local layout = uc.add{type = "table", name = "min-combinator", colspan = 9}
  250.       layout.add{type = "label", caption = "Filter: (?)", tooltip = {"min-combinator.filter"}}
  251.       for i = 1,8 do
  252.         if params[i].signal and params[i].signal.name then
  253.           layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  254.         else
  255.           layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  256.         end
  257.       end
  258.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  259.     end
  260.   end,
  261.   on_place = function(entity)
  262.     return {
  263.       meta = {
  264.         entity = entity,
  265.         params = {
  266.           {signal = {type = "virtual"}},
  267.           {signal = {type = "virtual"}},
  268.           {signal = {type = "virtual"}},
  269.           {signal = {type = "virtual"}},
  270.           {signal = {type = "virtual"}},
  271.           {signal = {type = "virtual"}},
  272.           {signal = {type = "virtual"}},
  273.           {signal = {type = "virtual"}}
  274.         }
  275.       }
  276.     }
  277.   end,
  278.   on_destroy = function() end,
  279.   on_tick = function(object)
  280.     local control = object.meta.entity.get_control_behavior()
  281.     if control then
  282.       local params = object.meta.params
  283.       if control.enabled then
  284.         local slots = {}
  285.         local signals = get_signals(control)
  286.         local signal = {type = "virtual"}
  287.         local count = math.huge
  288.         for k,v in pairs(signals) do
  289.           count = math.min(count, v.count)
  290.           if count == v.count then
  291.             signal = v.signal
  292.           end
  293.         end
  294.         count = 1
  295.         if count == math.huge then
  296.           count = 0
  297.         end
  298.         for i = 1,8 do
  299.           if params[i].signal and params[i].signal.name then
  300.             if signal.name == params[i].signal.name then
  301.               table.insert(slots, {signal = signal, count = count, index = 1})
  302.               break
  303.             end
  304.           end
  305.         end
  306.         control.parameters = {
  307.           parameters = slots
  308.         }
  309.       else
  310.         control.parameters = {
  311.           parameters = {}
  312.         }
  313.       end
  314.     end
  315.   end
  316. }
  317. -- Increased from 5 to 8
  318. classes["max-combinator"] = {
  319.   on_click = function(player, object)
  320.     local params = object.meta.params
  321.     local gui = player.gui.center.uc["max-combinator"]
  322.     for i = 1,8 do
  323.       if gui["signal"..i].elem_value and gui["signal"..i].elem_value.name then
  324.         object.meta.params[i] = {signal = gui["signal"..i].elem_value}
  325.       else
  326.         object.meta.params[i] = {signal = {type = "virtual"}}
  327.       end
  328.     end
  329.   end,
  330.   on_key = function(player, object)
  331.     if not (player.gui.center["uc"]) then
  332.       local params = object.meta.params
  333.       local gui = player.gui.center
  334.       local uc = gui.add{type = "frame", name = "uc", caption = "Max Combinator"}
  335.       local layout = uc.add{type = "table", name = "max-combinator", colspan = 9}
  336.       layout.add{type = "label", caption = "Filter: (?)", tooltip = {"max-combinator.filter"}}
  337.       for i = 1,8 do
  338.         if params[i].signal and params[i].signal.name then
  339.           layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  340.         else
  341.           layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  342.         end
  343.       end
  344.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  345.     end
  346.   end,
  347.   on_place = function(entity)
  348.     return {
  349.       meta = {
  350.         entity = entity,
  351.         params = {
  352.           {signal = {type = "virtual"}},
  353.           {signal = {type = "virtual"}},
  354.           {signal = {type = "virtual"}},
  355.           {signal = {type = "virtual"}},
  356.           {signal = {type = "virtual"}},
  357.           {signal = {type = "virtual"}},
  358.           {signal = {type = "virtual"}},
  359.           {signal = {type = "virtual"}}
  360.         },
  361.        
  362.       }
  363.     }
  364.   end,
  365.   on_destroy = function() end,
  366.   on_tick = function(object)
  367.     local control = object.meta.entity.get_control_behavior()
  368.     if control then
  369.       local params = object.meta.params
  370.       if control.enabled then
  371.         local slots = {}
  372.         local signals = get_signals(control)
  373.         local signal = {type = "virtual"}
  374.         local count = -math.huge
  375.         for k,v in pairs(signals) do
  376.           count = math.max(count, v.count)
  377.           if count == v.count then
  378.             signal = v.signal
  379.           end
  380.         end
  381.         count = 1
  382.         if count == -math.huge then
  383.           count = 0
  384.         end
  385.         for _,i in pairs(params) do
  386.           if i.signal.name then
  387.             if signal.name == i.signal.name then
  388.               table.insert(slots, {signal = signal, count = count, index = 1})
  389.             end
  390.           end
  391.         end
  392.         control.parameters = {
  393.           parameters = slots
  394.         }
  395.       else
  396.         control.parameters = {
  397.           parameters = {}
  398.         }
  399.       end
  400.     end
  401.   end
  402. }
  403.  
  404. classes["and-gate-combinator"] = {
  405.   on_click = function(player, object)
  406.     local gui = player.gui.center.uc["and-gate-combinator"]
  407.     local params = object.meta.params
  408.     if gui["signal_a"].elem_value and gui["signal_a"].elem_value.name then
  409.       params[1] = {signal = gui["signal_a"].elem_value}
  410.     else
  411.       params[1] = {signal = {type = "virtual"}}
  412.     end
  413.     if gui["signal_b"].elem_value and gui["signal_b"].elem_value.name then
  414.       params[2] = {signal = gui["signal_b"].elem_value}
  415.     else
  416.       params[2] = {signal = {type = "virtual"}}
  417.     end
  418.     if gui["signal_c"].elem_value and gui["signal_c"].elem_value.name then
  419.       params[3] = {signal = gui["signal_c"].elem_value}
  420.     else
  421.       params[3] = {signal = {type = "virtual"}}
  422.     end
  423.   end,
  424.   on_key = function(player, object)
  425.     if not (player.gui.center["uc"]) then
  426.       local params = object.meta.params
  427.       local gui = player.gui.center
  428.       local uc = gui.add{type = "frame", name = "uc", caption = "AND Gate Combinator"}
  429.       local layout = uc.add{type = "table", name = "and-gate-combinator", colspan = 5}
  430.       if params[1].signal and params[1].signal.name then
  431.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal", signal = params[1].signal}
  432.       else
  433.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal"}
  434.       end
  435.       layout.add{type = "label", caption = "AND"}
  436.       if params[2].signal and params[2].signal.name then
  437.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal", signal = params[2].signal}
  438.       else
  439.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal"}
  440.       end
  441.       layout.add{type = "label", caption = " = "}
  442.       if params[3].signal and params[3].signal.name then
  443.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal", signal = params[3].signal}
  444.       else
  445.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal"}
  446.       end
  447.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  448.     end
  449.   end,
  450.   on_place = function(entity)
  451.     return {
  452.       meta = {
  453.         entity = entity,
  454.         params = {
  455.           {signal = {type = "virtual"}},
  456.           {signal = {type = "virtual"}},
  457.           {signal = {type = "virtual", name = "output-signal"}}
  458.         }
  459.       }
  460.     }
  461.   end,
  462.   on_destroy = function() end,
  463.   on_tick = function(object)
  464.     local control = object.meta.entity.get_control_behavior()
  465.     if control then
  466.       local params = object.meta.params
  467.       if params[3].signal then
  468.         if control.enabled then
  469.           local slots = {}
  470.           local c1,c2 = 0,0
  471.           if params[1].signal.name then
  472.             c1 = get_count(control, params[1].signal)
  473.           end
  474.           if params[2].signal.name then
  475.             c2 = get_count(control, params[2].signal)
  476.           end
  477.           if params[3].signal.name then
  478.             if (c1 > 0) and (c2 > 0) and (c1 == c2) then
  479.               table.insert(slots, {signal = params[3].signal, count = 1, index = 1})
  480.             else
  481.               table.insert(slots, {signal = params[3].signal, count = 0, index = 1})
  482.             end
  483.           end
  484.           control.parameters = {
  485.             parameters = slots
  486.           }
  487.         end
  488.       else
  489.         control.parameters = {
  490.           parameters = {
  491.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  492.           }
  493.         }
  494.       end
  495.     end
  496.   end
  497. }
  498.  
  499. classes["nand-gate-combinator"] = {
  500.   on_click = function(player, object)
  501.     local gui = player.gui.center.uc["nand-gate-combinator"]
  502.     local params = object.meta.params
  503.     if gui["signal_a"].elem_value and gui["signal_a"].elem_value.name then
  504.       params[1] = {signal = gui["signal_a"].elem_value}
  505.     else
  506.       params[1] = {signal = {type = "virtual"}}
  507.     end
  508.     if gui["signal_b"].elem_value and gui["signal_b"].elem_value.name then
  509.       params[2] = {signal = gui["signal_b"].elem_value}
  510.     else
  511.       params[2] = {signal = {type = "virtual"}}
  512.     end
  513.     if gui["signal_c"].elem_value and gui["signal_c"].elem_value.name then
  514.       params[3] = {signal = gui["signal_c"].elem_value}
  515.     else
  516.       params[3] = {signal = {type = "virtual"}}
  517.     end
  518.   end,
  519.   on_key = function(player, object)
  520.     if not (player.gui.center["uc"]) then
  521.       local params = object.meta.params
  522.       local gui = player.gui.center
  523.       local uc = gui.add{type = "frame", name = "uc", caption = "NAND Gate Combinator"}
  524.       local layout = uc.add{type = "table", name = "nand-gate-combinator", colspan = 5}
  525.       if params[1].signal and params[1].signal.name then
  526.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal", signal = params[1].signal}
  527.       else
  528.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal"}
  529.       end
  530.       layout.add{type = "label", caption = "NAND"}
  531.       if params[2].signal and params[2].signal.name then
  532.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal", signal = params[2].signal}
  533.       else
  534.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal"}
  535.       end
  536.       layout.add{type = "label", caption = " = "}
  537.       if params[3].signal and params[3].signal.name then
  538.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal", signal = params[3].signal}
  539.       else
  540.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal"}
  541.       end
  542.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  543.     end
  544.   end,
  545.   on_place = function(entity)
  546.     return {
  547.       meta = {
  548.         entity = entity,
  549.         params = {
  550.           {signal = {type = "virtual"}},
  551.           {signal = {type = "virtual"}},
  552.           {signal = {type = "virtual", name = "output-signal"}}
  553.         }
  554.       }
  555.     }
  556.   end,
  557.   on_destroy = function() end,
  558.   on_tick = function(object)
  559.     local control = object.meta.entity.get_control_behavior()
  560.     if control then
  561.       local params = object.meta.params
  562.       if params[3].signal then
  563.         if control.enabled then
  564.           local slots = {}
  565.           local c1,c2 = 0,0
  566.           if params[1].signal.name then
  567.             c1 = get_count(control, params[1].signal)
  568.           end
  569.           if params[2].signal.name then
  570.             c2 = get_count(control, params[2].signal)
  571.           end
  572.           if params[3].signal.name then
  573.             if (c1 > 0) and (c2 > 0) and (c1 == c2) then
  574.               table.insert(slots, {signal = params[3].signal, count = 0, index = 1})
  575.             else
  576.               table.insert(slots, {signal = params[3].signal, count = 1, index = 1})
  577.             end
  578.           end
  579.           control.parameters = {
  580.             parameters = slots
  581.           }
  582.         end
  583.       else
  584.         control.parameters = {
  585.           parameters = {
  586.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  587.           }
  588.         }
  589.       end
  590.     end
  591.   end
  592. }
  593.  
  594. classes["nor-gate-combinator"] = {
  595.   on_click = function(player, object)
  596.     local gui = player.gui.center.uc["nor-gate-combinator"]
  597.     local params = object.meta.params
  598.     if gui["signal_a"].elem_value and gui["signal_a"].elem_value.name then
  599.       params[1] = {signal = gui["signal_a"].elem_value}
  600.     else
  601.       params[1] = {signal = {type = "virtual"}}
  602.     end
  603.     if gui["signal_b"].elem_value and gui["signal_b"].elem_value.name then
  604.       params[2] = {signal = gui["signal_b"].elem_value}
  605.     else
  606.       params[2] = {signal = {type = "virtual"}}
  607.     end
  608.     if gui["signal_c"].elem_value and gui["signal_c"].elem_value.name then
  609.       params[3] = {signal = gui["signal_c"].elem_value}
  610.     else
  611.       params[3] = {signal = {type = "virtual"}}
  612.     end
  613.   end,
  614.   on_key = function(player, object)
  615.     if not (player.gui.center["uc"]) then
  616.       local params = object.meta.params
  617.       local gui = player.gui.center
  618.       local uc = gui.add{type = "frame", name = "uc", caption = "NOR Gate Combinator"}
  619.       local layout = uc.add{type = "table", name = "nor-gate-combinator", colspan = 5}
  620.       if params[1].signal and params[1].signal.name then
  621.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal", signal = params[1].signal}
  622.       else
  623.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal"}
  624.       end
  625.       layout.add{type = "label", caption = "NOR"}
  626.       if params[2].signal and params[2].signal.name then
  627.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal", signal = params[2].signal}
  628.       else
  629.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal"}
  630.       end
  631.       layout.add{type = "label", caption = " = "}
  632.       if params[3].signal and params[3].signal.name then
  633.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal", signal = params[3].signal}
  634.       else
  635.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal"}
  636.       end
  637.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  638.     end
  639.   end,
  640.   on_place = function(entity)
  641.     return {
  642.       meta = {
  643.         entity = entity,
  644.         params = {
  645.           {signal = {type = "virtual"}},
  646.           {signal = {type = "virtual"}},
  647.           {signal = {type = "virtual", name = "output-signal"}}
  648.         }
  649.       }
  650.     }
  651.   end,
  652.   on_destroy = function() end,
  653.   on_tick = function(object)
  654.     local control = object.meta.entity.get_control_behavior()
  655.     if control then
  656.       local params = object.meta.params
  657.       if params[3].signal then
  658.         if control.enabled then
  659.           local slots = {}
  660.           local c1,c2 = 0,0
  661.           if params[1].signal.name then
  662.             c1 = get_count(control, params[1].signal)
  663.           end
  664.           if params[2].signal.name then
  665.             c2 = get_count(control, params[2].signal)
  666.           end
  667.           if params[3].signal.name then
  668.             if (c1 >= 1) or (c2 >= 1) then
  669.               table.insert(slots, {signal = params[3].signal, count = 0, index = 1})
  670.             else
  671.               table.insert(slots, {signal = params[3].signal, count = 1, index = 1})
  672.             end
  673.           end
  674.           control.parameters = {
  675.             parameters = slots
  676.           }
  677.         end
  678.       else
  679.         control.parameters = {
  680.           parameters = {
  681.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  682.           }
  683.         }
  684.       end
  685.     end
  686.   end
  687. }
  688.  
  689. classes["not-gate-combinator"] = {
  690.   on_click = function(player, object)
  691.     local gui = player.gui.center.uc["not-gate-combinator"]
  692.     local params = object.meta.params
  693.     if gui["signal_a"].elem_value and gui["signal_a"].elem_value.name then
  694.       params[1] = {signal = gui["signal_a"].elem_value}
  695.     else
  696.       params[1] = {signal = {type = "virtual"}}
  697.     end
  698.     if gui["signal_b"].elem_value and gui["signal_b"].elem_value.name then
  699.       params[2] = {signal = gui["signal_b"].elem_value}
  700.     else
  701.       params[2] = {signal = {type = "virtual"}}
  702.     end
  703.   end,
  704.   on_key = function(player, object)
  705.     if not (player.gui.center["uc"]) then
  706.       local params = object.meta.params
  707.       local gui = player.gui.center
  708.       local uc = gui.add{type = "frame", name = "uc", caption = "NOT Gate Combinator"}
  709.       local layout = uc.add{type = "table", name = "not-gate-combinator", colspan = 4}
  710.       layout.add{type = "label", caption = "NOT"}
  711.       if params[1].signal and params[1].signal.name then
  712.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal", signal = params[1].signal}
  713.       else
  714.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal"}
  715.       end
  716.       layout.add{type = "label", caption = " = "}
  717.       if params[2].signal and params[2].signal.name then
  718.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal", signal = params[2].signal}
  719.       else
  720.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal"}
  721.       end
  722.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  723.     end
  724.   end,
  725.   on_place = function(entity)
  726.     return {
  727.       meta = {
  728.         entity = entity,
  729.         params = {
  730.           {signal = {type = "virtual"}},
  731.           {signal = {type = "virtual", name = "output-signal"}}
  732.         }
  733.       }
  734.     }
  735.   end,
  736.   on_destroy = function() end,
  737.   on_tick = function(object)
  738.     local control = object.meta.entity.get_control_behavior()
  739.     if control then
  740.       local params = object.meta.params
  741.       if params[2].signal then
  742.         if control.enabled then
  743.           local slots = {}
  744.           local c1,c2 = 0,0
  745.           if params[1].signal.name then
  746.             c1 = get_count(control, params[1].signal)
  747.           end
  748.           if params[2].signal.name then
  749.             if (c1 > 0) then
  750.               table.insert(slots, {signal = params[2].signal, count = 0, index = 1})
  751.             else
  752.               table.insert(slots, {signal = params[2].signal, count = 1, index = 1})
  753.             end
  754.           end
  755.           control.parameters = {
  756.             parameters = slots
  757.           }
  758.         end
  759.       else
  760.         control.parameters = {
  761.           parameters = {
  762.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  763.           }
  764.         }
  765.       end
  766.     end
  767.   end
  768. }
  769.  
  770. classes["or-gate-combinator"] = {
  771.   on_click = function(player, object)
  772.     local gui = player.gui.center.uc["or-gate-combinator"]
  773.     local params = object.meta.params
  774.     if gui["signal_a"].elem_value and gui["signal_a"].elem_value.name then
  775.       params[1] = {signal = gui["signal_a"].elem_value}
  776.     else
  777.       params[1] = {signal = {type = "virtual"}}
  778.     end
  779.     if gui["signal_b"].elem_value and gui["signal_b"].elem_value.name then
  780.       params[2] = {signal = gui["signal_b"].elem_value}
  781.     else
  782.       params[2] = {signal = {type = "virtual"}}
  783.     end
  784.     if gui["signal_c"].elem_value and gui["signal_c"].elem_value.name then
  785.       params[3] = {signal = gui["signal_c"].elem_value}
  786.     else
  787.       params[3] = {signal = {type = "virtual"}}
  788.     end
  789.   end,
  790.   on_key = function(player, object)
  791.     if not (player.gui.center["uc"]) then
  792.       local params = object.meta.params
  793.       local gui = player.gui.center
  794.       local uc = gui.add{type = "frame", name = "uc", caption = "OR Gate Combinator"}
  795.       local layout = uc.add{type = "table", name = "or-gate-combinator", colspan = 5}
  796.       if params[1].signal and params[1].signal.name then
  797.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal", signal = params[1].signal}
  798.       else
  799.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal"}
  800.       end
  801.       layout.add{type = "label", caption = "OR"}
  802.       if params[2].signal and params[2].signal.name then
  803.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal", signal = params[2].signal}
  804.       else
  805.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal"}
  806.       end
  807.       layout.add{type = "label", caption = " = "}
  808.       if params[3].signal and params[3].signal.name then
  809.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal", signal = params[3].signal}
  810.       else
  811.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal"}
  812.       end
  813.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  814.     end
  815.   end,
  816.   on_place = function(entity)
  817.     return {
  818.       meta = {
  819.         entity = entity,
  820.         params = {
  821.           {signal = {type = "virtual"}},
  822.           {signal = {type = "virtual"}},
  823.           {signal = {type = "virtual", name = "output-signal"}}
  824.         }
  825.       }
  826.     }
  827.   end,
  828.   on_destroy = function() end,
  829.   on_tick = function(object)
  830.     local control = object.meta.entity.get_control_behavior()
  831.     if control then
  832.       local params = object.meta.params
  833.       if params[3].signal then
  834.         if control.enabled then
  835.           local slots = {}
  836.           local c1,c2 = 0,0
  837.           if params[1].signal.name then
  838.             c1 = get_count(control, params[1].signal)
  839.           end
  840.           if params[2].signal.name then
  841.             c2 = get_count(control, params[2].signal)
  842.           end
  843.           if params[3].signal.name then
  844.             if (c1 >= 1) or (c2 >= 1) then
  845.               table.insert(slots, {signal = params[3].signal, count = 1, index = 1})
  846.             else
  847.               table.insert(slots, {signal = params[3].signal, count = 0, index = 1})
  848.             end
  849.           end
  850.           control.parameters = {
  851.             parameters = slots
  852.           }
  853.         end
  854.       else
  855.         control.parameters = {
  856.           parameters = {
  857.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  858.           }
  859.         }
  860.       end
  861.     end
  862.   end
  863. }
  864.  
  865. classes["xnor-gate-combinator"] = {
  866.   on_click = function(player, object)
  867.     local gui = player.gui.center.uc["xnor-gate-combinator"]
  868.     local params = object.meta.params
  869.     if gui["signal_a"].elem_value and gui["signal_a"].elem_value.name then
  870.       params[1] = {signal = gui["signal_a"].elem_value}
  871.     else
  872.       params[1] = {signal = {type = "virtual"}}
  873.     end
  874.     if gui["signal_b"].elem_value and gui["signal_b"].elem_value.name then
  875.       params[2] = {signal = gui["signal_b"].elem_value}
  876.     else
  877.       params[2] = {signal = {type = "virtual"}}
  878.     end
  879.     if gui["signal_c"].elem_value and gui["signal_c"].elem_value.name then
  880.       params[3] = {signal = gui["signal_c"].elem_value}
  881.     else
  882.       params[3] = {signal = {type = "virtual"}}
  883.     end
  884.   end,
  885.   on_key = function(player, object)
  886.     if not (player.gui.center["uc"]) then
  887.       local params = object.meta.params
  888.       local gui = player.gui.center
  889.       local uc = gui.add{type = "frame", name = "uc", caption = "XNOR Gate Combinator"}
  890.       local layout = uc.add{type = "table", name = "xnor-gate-combinator", colspan = 5}
  891.       if params[1].signal and params[1].signal.name then
  892.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal", signal = params[1].signal}
  893.       else
  894.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal"}
  895.       end
  896.       layout.add{type = "label", caption = "XNOR"}
  897.       if params[2].signal and params[2].signal.name then
  898.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal", signal = params[2].signal}
  899.       else
  900.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal"}
  901.       end
  902.       layout.add{type = "label", caption = " = "}
  903.       if params[3].signal and params[3].signal.name then
  904.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal", signal = params[3].signal}
  905.       else
  906.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal"}
  907.       end
  908.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  909.     end
  910.   end,
  911.   on_place = function(entity)
  912.     return {
  913.       meta = {
  914.         entity = entity,
  915.         params = {
  916.           {signal = {type = "virtual"}},
  917.           {signal = {type = "virtual"}},
  918.           {signal = {type = "virtual", name = "output-signal"}}
  919.         }
  920.       }
  921.     }
  922.   end,
  923.   on_destroy = function() end,
  924.   on_tick = function(object)
  925.     local control = object.meta.entity.get_control_behavior()
  926.     if control then
  927.       local params = object.meta.params
  928.       if params[3].signal then
  929.         if control.enabled then
  930.           local slots = {}
  931.           local c1,c2 = 0,0
  932.           if params[1].signal.name then
  933.             c1 = get_count(control, params[1].signal)
  934.           end
  935.           if params[2].signal.name then
  936.             c2 = get_count(control, params[2].signal)
  937.           end
  938.           if params[3].signal.name then
  939.             if (c1 == c2) then
  940.               table.insert(slots, {signal = params[3].signal, count = 1, index = 1})
  941.             else
  942.               table.insert(slots, {signal = params[3].signal, count = 0, index = 1})
  943.             end
  944.           end
  945.           control.parameters = {
  946.             parameters = slots
  947.           }
  948.         end
  949.       else
  950.         control.parameters = {
  951.           parameters = {
  952.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  953.           }
  954.         }
  955.       end
  956.     end
  957.   end
  958. }
  959.  
  960. classes["xor-gate-combinator"] = {
  961.   on_click = function(player, object)
  962.     local gui = player.gui.center.uc["xor-gate-combinator"]
  963.     local params = object.meta.params
  964.     if gui["signal_a"].elem_value and gui["signal_a"].elem_value.name then
  965.       params[1] = {signal = gui["signal_a"].elem_value}
  966.     else
  967.       params[1] = {signal = {type = "virtual"}}
  968.     end
  969.     if gui["signal_b"].elem_value and gui["signal_b"].elem_value.name then
  970.       params[2] = {signal = gui["signal_b"].elem_value}
  971.     else
  972.       params[2] = {signal = {type = "virtual"}}
  973.     end
  974.     if gui["signal_c"].elem_value and gui["signal_c"].elem_value.name then
  975.       params[3] = {signal = gui["signal_c"].elem_value}
  976.     else
  977.       params[3] = {signal = {type = "virtual"}}
  978.     end
  979.   end,
  980.   on_key = function(player, object)
  981.     if not (player.gui.center["uc"]) then
  982.       local params = object.meta.params
  983.       local gui = player.gui.center
  984.       local uc = gui.add{type = "frame", name = "uc", caption = "XOR Gate Combinator"}
  985.       local layout = uc.add{type = "table", name = "xor-gate-combinator", colspan = 5}
  986.       if params[1].signal and params[1].signal.name then
  987.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal", signal = params[1].signal}
  988.       else
  989.         layout.add{type = "choose-elem-button", name = "signal_a", elem_type = "signal"}
  990.       end
  991.       layout.add{type = "label", caption = "XOR"}
  992.       if params[2].signal and params[2].signal.name then
  993.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal", signal = params[2].signal}
  994.       else
  995.         layout.add{type = "choose-elem-button", name = "signal_b", elem_type = "signal"}
  996.       end
  997.       layout.add{type = "label", caption = " = "}
  998.       if params[3].signal and params[3].signal.name then
  999.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal", signal = params[3].signal}
  1000.       else
  1001.         layout.add{type = "choose-elem-button", name = "signal_c", elem_type = "signal"}
  1002.       end
  1003.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1004.     end
  1005.   end,
  1006.   on_place = function(entity)
  1007.     return {
  1008.       meta = {
  1009.         entity = entity,
  1010.         params = {
  1011.           {signal = {type = "virtual"}},
  1012.           {signal = {type = "virtual"}},
  1013.           {signal = {type = "virtual", name = "output-signal"}}
  1014.         }
  1015.       }
  1016.     }
  1017.   end,
  1018.   on_destroy = function() end,
  1019.   on_tick = function(object)
  1020.     local control = object.meta.entity.get_control_behavior()
  1021.     if control then
  1022.       local params = object.meta.params
  1023.       if params[3].signal then
  1024.         if control.enabled then
  1025.           local slots = {}
  1026.           local c1,c2 = 0,0
  1027.           if params[1].signal.name then
  1028.             c1 = get_count(control, params[1].signal)
  1029.           end
  1030.           if params[2].signal.name then
  1031.             c2 = get_count(control, params[2].signal)
  1032.           end
  1033.           if params[3].signal.name then
  1034.             if (c1 == c2) then
  1035.               table.insert(slots, {signal = params[3].signal, count = 0, index = 1})
  1036.             else
  1037.               table.insert(slots, {signal = params[3].signal, count = 1, index = 1})
  1038.             end
  1039.           end
  1040.           control.parameters = {
  1041.             parameters = slots
  1042.           }
  1043.         end
  1044.       else
  1045.         control.parameters = {
  1046.           parameters = {
  1047.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  1048.           }
  1049.         }
  1050.       end
  1051.     end
  1052.   end
  1053. }
  1054. -- Increased from 5 to 8
  1055. classes["converter-combinator"] = {
  1056.   on_click = function(player, object)
  1057.     local gui = player.gui.center
  1058.     for i = 1,8 do
  1059.       if gui["uc"]["converter-combinator"]["from"..i].elem_value and gui["uc"]["converter-combinator"]["from"..i].elem_value.name then
  1060.         object.meta.params["from"][i] = {signal = gui["uc"]["converter-combinator"]["from"..i].elem_value}
  1061.       else
  1062.         object.meta.params["from"][i] = {type = "virtual"}
  1063.       end
  1064.       if gui["uc"]["converter-combinator"]["to"..i].elem_value and gui["uc"]["converter-combinator"]["to"..i].elem_value.name then
  1065.         object.meta.params["to"][i] = {signal = gui["uc"]["converter-combinator"]["to"..i].elem_value}
  1066.       else
  1067.         object.meta.params["to"][i] = {type = "virtual"}
  1068.       end
  1069.     end
  1070.   end,
  1071.   on_key = function(player, object)
  1072.     if not (player.gui.center["uc"]) then
  1073.       local params = object.meta.params
  1074.       local gui = player.gui.center
  1075.       local uc = gui.add{type = "frame", name = "uc", caption = "Converter Combinator"}
  1076.       local layout = uc.add{type = "table", name = "converter-combinator", colspan = 2}
  1077.       layout.add{type = "label", caption = "From: (?)", tooltip = {"converter-combinator.from"}}
  1078.       layout.add{type = "label", caption = "To: (?)", tooltip = {"converter-combinator.to"}}
  1079.       for i = 1,8 do
  1080.         if params["from"][i].signal and params["from"][i].signal.name then
  1081.           layout.add{type = "choose-elem-button", name = "from"..i, elem_type = "signal", signal = params["from"][i].signal}
  1082.         else
  1083.           layout.add{type = "choose-elem-button", name = "from"..i, elem_type = "signal"}
  1084.         end
  1085.         if params["to"][i].signal and params["to"][i].signal.name then
  1086.           layout.add{type = "choose-elem-button", name = "to"..i, elem_type = "signal", signal = params["to"][i].signal}
  1087.         else
  1088.           layout.add{type = "choose-elem-button", name = "to"..i, elem_type = "signal"}
  1089.         end
  1090.       end
  1091.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1092.     end
  1093.   end,
  1094.   on_place = function(entity)
  1095.     return {
  1096.       meta = {
  1097.         entity = entity,
  1098.         params = {
  1099.           from = {
  1100.             {signal = {type = "virtual"}},
  1101.             {signal = {type = "virtual"}},
  1102.             {signal = {type = "virtual"}},
  1103.             {signal = {type = "virtual"}},
  1104.             {signal = {type = "virtual"}},
  1105.             {signal = {type = "virtual"}},
  1106.             {signal = {type = "virtual"}},
  1107.             {signal = {type = "virtual"}}
  1108.           },
  1109.           to = {
  1110.             {signal = {type = "virtual"}},
  1111.             {signal = {type = "virtual"}},
  1112.             {signal = {type = "virtual"}},
  1113.             {signal = {type = "virtual"}},
  1114.             {signal = {type = "virtual"}},
  1115.             {signal = {type = "virtual"}},
  1116.             {signal = {type = "virtual"}},
  1117.             {signal = {type = "virtual"}}
  1118.           }
  1119.         }
  1120.       }
  1121.     }
  1122.   end,
  1123.   on_destroy = function() end,
  1124.   on_tick = function(object)
  1125.     local control = object.meta.entity.get_control_behavior()
  1126.     if control then
  1127.       if control.enabled then
  1128.         local slots = {}
  1129.         local params = object.meta.params
  1130.         if not params["from"] and not params["to"] then
  1131.           object.meta.params = {
  1132.             from = {
  1133.               {signal = {type = "virtual"}},
  1134.               {signal = {type = "virtual"}},
  1135.               {signal = {type = "virtual"}},
  1136.               {signal = {type = "virtual"}},
  1137.               {signal = {type = "virtual"}},
  1138.               {signal = {type = "virtual"}},
  1139.               {signal = {type = "virtual"}},
  1140.               {signal = {type = "virtual"}}
  1141.             },
  1142.             to = {
  1143.               {signal = {type = "virtual"}},
  1144.               {signal = {type = "virtual"}},
  1145.               {signal = {type = "virtual"}},
  1146.               {signal = {type = "virtual"}},
  1147.               {signal = {type = "virtual"}},
  1148.               {signal = {type = "virtual"}},
  1149.               {signal = {type = "virtual"}},
  1150.               {signal = {type = "virtual"}}
  1151.             }
  1152.           }
  1153.           params = object.meta.params
  1154.         end
  1155.         for i = 1,8 do
  1156.           if params["to"][i].signal and params["to"][i].signal.name then
  1157.             table.insert(slots, {signal = params["to"][i].signal, count = get_count(control, params["from"][i].signal), index = i})
  1158.           end
  1159.         end
  1160.         control.parameters = {
  1161.             parameters = slots
  1162.           }
  1163.       else
  1164.         control.parameters = {
  1165.           parameters = {}
  1166.         }
  1167.       end
  1168.     end
  1169.   end
  1170. }
  1171.  
  1172. classes["detector-combinator"] = {
  1173.   on_click = function(player, object)
  1174.     local gui = player.gui.center
  1175.     if gui["uc"]["detector-combinator"]["signal"].elem_value and gui["uc"]["detector-combinator"]["signal"].elem_value.name then
  1176.       object.meta.signal = gui["uc"]["detector-combinator"]["signal"].elem_value
  1177.     else
  1178.       object.meta.signal = {type = "virtual"}
  1179.     end
  1180.     object.meta.radius = tonumber(gui["uc"]["detector-combinator"]["radius"].text) or object.meta.radius
  1181.   end,
  1182.   on_key = function(player, object)
  1183.     if not (player.gui.center["uc"]) then
  1184.       local meta = object.meta
  1185.       local gui = player.gui.center
  1186.       local uc = gui.add{type = "frame", name = "uc", caption = "Detector Combinator"}
  1187.       local layout = uc.add{type = "table", name = "detector-combinator", colspan = 4}
  1188.       layout.add{type = "label", caption = "Radius: (?)", tooltip = {"detector-combinator.radius"}}
  1189.       layout.add{type = "textfield", name = "radius", style = "uc_text", text = meta.radius}
  1190.       layout.add{type = "label", caption = "Signal: (?)", tooltip = {"detector-combinator.signal"}}
  1191.       if meta.signal and meta.signal.name then
  1192.         layout.add{type = "choose-elem-button", name = "signal", elem_type = "signal", signal = meta.signal}
  1193.       else
  1194.         layout.add{type = "choose-elem-button", name = "signal", elem_type = "signal"}
  1195.       end
  1196.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1197.     end
  1198.   end,
  1199.   on_place = function(entity)
  1200.     return {
  1201.       meta = {
  1202.         entity = entity,
  1203.         radius = 24,
  1204.         signal = {type = "virtual", name = "output-signal"}
  1205.       }
  1206.     }
  1207.   end,
  1208.   on_destroy = function() end,
  1209.   on_tick = function(object)
  1210.     local control = object.meta.entity.get_control_behavior()
  1211.     if control then
  1212.       local signal = object.meta.signal
  1213.       if signal then
  1214.         if control.enabled then
  1215.           local r = object.meta.radius
  1216.           if r > 24 then
  1217.             r = 24
  1218.             object.meta.radius = 24
  1219.           end
  1220.           if r < 1 then
  1221.             r = 1
  1222.             object.meta.radius = 1
  1223.           end
  1224.           local slots = {}
  1225.           local pos = object.meta.entity.position
  1226.           local units = #object.meta.entity.surface.find_enemy_units(object.meta.entity.position, r + 0.5)
  1227.           if signal.name then
  1228.             table.insert(slots, {signal = signal, count = units, index = 1})
  1229.           end
  1230.           control.parameters = {
  1231.             parameters = slots
  1232.           }
  1233.         end
  1234.       else
  1235.         control.parameters = {
  1236.           parameters = {
  1237.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  1238.           }
  1239.         }
  1240.       end
  1241.     end
  1242.   end
  1243. }
  1244.  
  1245. classes["sensor-combinator"] = {
  1246.   on_click = function(player, object)
  1247.     local gui = player.gui.center
  1248.     if gui["uc"]["sensor-combinator"]["signal"].elem_value and gui["uc"]["sensor-combinator"]["signal"].elem_value.name then
  1249.       object.meta.signal = gui["uc"]["sensor-combinator"]["signal"].elem_value
  1250.     else
  1251.       object.meta.signal = {type = "virtual"}
  1252.     end
  1253.     object.meta.radius = tonumber(gui["uc"]["sensor-combinator"]["radius"].text) or object.meta.radius
  1254.   end,
  1255.   on_key = function(player, object)
  1256.     if not (player.gui.center["uc"]) then
  1257.       local meta = object.meta
  1258.       local gui = player.gui.center
  1259.       local uc = gui.add{type = "frame", name = "uc", caption = "Sensor Combinator"}
  1260.       local layout = uc.add{type = "table", name = "sensor-combinator", colspan = 4}
  1261.       layout.add{type = "label", caption = "Radius: (?)", tooltip = {"sensor-combinator.radius"}}
  1262.       layout.add{type = "textfield", name = "radius", style = "uc_text", text = meta.radius}
  1263.       layout.add{type = "label", caption = "Signal: (?)", tooltip = {"sensor-combinator.signal"}}
  1264.       if meta.signal and meta.signal.name then
  1265.         layout.add{type = "choose-elem-button", name = "signal", elem_type = "signal", signal = meta.signal}
  1266.       else
  1267.         layout.add{type = "choose-elem-button", name = "signal", elem_type = "signal"}
  1268.       end
  1269.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1270.     end
  1271.   end,
  1272.   on_place = function(entity)
  1273.     return {
  1274.       meta = {
  1275.         entity = entity,
  1276.         radius = 24,
  1277.         signal = {type = "virtual", name = "output-signal"}
  1278.       }
  1279.     }
  1280.   end,
  1281.   on_destroy = function() end,
  1282.   on_tick = function(object)
  1283.     local control = object.meta.entity.get_control_behavior()
  1284.     if control then
  1285.       local signal = object.meta.signal
  1286.       if signal then
  1287.         if control.enabled then
  1288.           local r = object.meta.radius
  1289.           if r > 24 then
  1290.             r = 24
  1291.             object.meta.radius = 24
  1292.           end
  1293.           if r < 1 then
  1294.             r = 1
  1295.             object.meta.radius = 1
  1296.           end
  1297.           local slots = {}
  1298.           local pos = object.meta.entity.position
  1299.           local units = object.meta.entity.surface.count_entities_filtered(
  1300.           {
  1301.             area = {{pos.x - (r + 0.5), pos.y - (r + 0.5)}, {pos.x + (r + 0.5), pos.y + (r + 0.5)}},
  1302.             type = "player"
  1303.           })
  1304.           if signal.name then
  1305.             table.insert(slots, {signal = signal, count = units, index = 1})
  1306.           end
  1307.           control.parameters = {
  1308.             parameters = slots
  1309.           }
  1310.         end
  1311.       else
  1312.         control.parameters = {
  1313.           parameters = {
  1314.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  1315.           }
  1316.         }
  1317.       end
  1318.     end
  1319.   end
  1320. }
  1321.  
  1322. classes["railway-combinator"] = {
  1323.   on_click = function(player, object)
  1324.     local gui = player.gui.center
  1325.     if gui["uc"]["railway-combinator"]["signal"].elem_value and gui["uc"]["railway-combinator"]["signal"].elem_value.name then
  1326.       object.meta.signal = gui["uc"]["railway-combinator"]["signal"].elem_value
  1327.     else
  1328.       object.meta.signal = {type = "virtual"}
  1329.     end
  1330.   end,
  1331.   on_key = function(player, object)
  1332.     if not (player.gui.center["uc"]) then
  1333.       local meta = object.meta
  1334.       local gui = player.gui.center
  1335.       local uc = gui.add{type = "frame", name = "uc", caption = "Railway Combinator"}
  1336.       local layout = uc.add{type = "table", name = "railway-combinator", colspan = 2}
  1337.       layout.add{type = "label", caption = "Output: (?)", tooltip = {"railway-combinator.output"}}
  1338.       if meta.signal and meta.signal.name then
  1339.         layout.add{type = "choose-elem-button", name = "signal", elem_type = "signal", signal = meta.signal}
  1340.       else
  1341.         layout.add{type = "choose-elem-button", name = "signal", elem_type = "signal"}
  1342.       end
  1343.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1344.     end
  1345.   end,
  1346.   on_place = function(entity)
  1347.     return {
  1348.       meta = {
  1349.         entity = entity,
  1350.         signal = {type = "virtual", name = "output-signal"}
  1351.       }
  1352.     }
  1353.   end,
  1354.   on_destroy = function() end,
  1355.   on_tick = function(object)
  1356.     local control = object.meta.entity.get_control_behavior()
  1357.     if control then
  1358.       local output = object.meta.signal
  1359.       if output then
  1360.         if control.enabled then
  1361.           local slots = {}
  1362.           local pos = object.meta.entity.position
  1363.           local units = object.meta.entity.surface.count_entities_filtered(
  1364.             {
  1365.               area = {{pos.x - 1, pos.y - 1}, {pos.x + 1, pos.y + 1}},
  1366.               type = "locomotive"
  1367.             })
  1368.           if output.name then
  1369.             table.insert(slots, {signal = output, count = units, index = 1})
  1370.           end
  1371.           control.parameters = {
  1372.             parameters = slots
  1373.           }
  1374.         end
  1375.       else
  1376.         control.parameters = {
  1377.           parameters = {
  1378.             {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  1379.           }
  1380.         }
  1381.       end
  1382.     end
  1383.   end
  1384. }
  1385.  
  1386. classes["color-combinator"] = {
  1387.   on_click = function(player, object)
  1388.     local gui = player.gui.center
  1389.     for i = 1,6 do
  1390.       if gui["uc"]["color-combinator"]["signal"..i].elem_value and gui["uc"]["color-combinator"]["signal"..i].elem_value.name then
  1391.         object.meta.params[i] = {signal = gui["uc"]["color-combinator"]["signal"..i].elem_value, count = tonumber(gui["uc"]["color-combinator"]["count"..i].text) or object.meta.params[i].count}
  1392.       else
  1393.         object.meta.params[i] = {signal = {type = "virtual"}, count = 0}
  1394.       end
  1395.     end
  1396.   end,
  1397.   on_key = function(player, object)
  1398.     if not (player.gui.center["uc"]) then
  1399.       local gui = player.gui.center
  1400.       local params = object.meta.params
  1401.       local uc = gui.add{type = "frame", name = "uc", caption = "Color Combinator"}
  1402.       local layout = uc.add{type = "table", name = "color-combinator", colspan = 4}
  1403.       for i = 1,6 do
  1404.         if i == 1 then
  1405.           layout.add{type = "label", caption = "Red: (?)", tooltip = {"color-combinator.red"}}
  1406.           if params[i].signal and params[i].signal.name then  
  1407.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  1408.           else
  1409.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  1410.           end
  1411.           layout.add{type = "label", caption = " = "}
  1412.           layout.add{type = "textfield", name = "count"..i, style = "uc_text", text = params[i].count or 0}
  1413.         elseif i == 2 then
  1414.           layout.add{type = "label", caption = "Green: (?)", tooltip = {"color-combinator.green"}}
  1415.           if params[i].signal and params[i].signal.name then  
  1416.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  1417.           else
  1418.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  1419.           end
  1420.           layout.add{type = "label", caption = " = "}
  1421.           layout.add{type = "textfield", name = "count"..i, style = "uc_text", text = params[i].count or i}
  1422.         elseif i == 3 then
  1423.           layout.add{type = "label", caption = "Blue: (?)", tooltip = {"color-combinator.blue"}}
  1424.           if params[i].signal and params[i].signal.name then  
  1425.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  1426.           else
  1427.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  1428.           end
  1429.           layout.add{type = "label", caption = " = "}
  1430.           layout.add{type = "textfield", name = "count"..i, style = "uc_text", text = params[i].count or i}
  1431.         elseif i == 4 then
  1432.           layout.add{type = "label", caption = "Yellow: (?)", tooltip = {"color-combinator.yellow"}}
  1433.           if params[i].signal and params[i].signal.name then  
  1434.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  1435.           else
  1436.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  1437.           end
  1438.           layout.add{type = "label", caption = " = "}
  1439.           layout.add{type = "textfield", name = "count"..i, style = "uc_text", text = params[i].count or i}
  1440.         elseif i == 5 then
  1441.           layout.add{type = "label", caption = "Magenta: (?)", tooltip = {"color-combinator.magenta"}}
  1442.           if params[i].signal and params[i].signal.name then  
  1443.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  1444.           else
  1445.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  1446.           end
  1447.           layout.add{type = "label", caption = " = "}
  1448.           layout.add{type = "textfield", name = "count"..i, style = "uc_text", text = params[i].count or i}
  1449.         elseif i == 6 then
  1450.           layout.add{type = "label", caption = "Cyan: (?)", tooltip = {"color-combinator.cyan"}}
  1451.           if params[i].signal and params[i].signal.name then  
  1452.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal", signal = params[i].signal}
  1453.           else
  1454.             layout.add{type = "choose-elem-button", name = "signal"..i, elem_type = "signal"}
  1455.           end
  1456.           layout.add{type = "label", caption = " = "}
  1457.           layout.add{type = "textfield", name = "count"..i, style = "uc_text", text = params[i].count or i}
  1458.         end
  1459.       end
  1460.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1461.     end
  1462.   end,
  1463.   on_place = function(entity)
  1464.     return {
  1465.       meta = {
  1466.         entity = entity,
  1467.         params = {
  1468.           {signal = {type = "virtual", name = "red-signal"}, count = 1},
  1469.           {signal = {type = "virtual", name = "green-signal"}, count = 2},
  1470.           {signal = {type = "virtual", name = "blue-signal"}, count = 3},
  1471.           {signal = {type = "virtual", name = "yellow-signal"}, count = 4},
  1472.           {signal = {type = "virtual", name = "magenta-signal"}, count = 5},
  1473.           {signal = {type = "virtual", name = "cyan-signal"}, count = 6}
  1474.         }
  1475.       }
  1476.     }
  1477.   end,
  1478.   on_destroy = function() end,
  1479.   on_tick = function(object)
  1480.     local control = object.meta.entity.get_control_behavior()
  1481.     if control then
  1482.       local params = object.meta.params
  1483.       if control.enabled then
  1484.         local slots = {
  1485.           {signal = {type = "virtual", name = "signal-red"}, count = 0, index = 1},
  1486.           {signal = {type = "virtual", name = "signal-green"}, count = 0, index = 2},
  1487.           {signal = {type = "virtual", name = "signal-blue"}, count = 0, index = 3},
  1488.           {signal = {type = "virtual", name = "signal-yellow"}, count = 0, index = 4},
  1489.           {signal = {type = "virtual", name = "signal-pink"}, count = 0, index = 5},
  1490.           {signal = {type = "virtual", name = "signal-cyan"}, count = 0, index = 6}
  1491.         }
  1492.         for i = 1,6 do
  1493.           if params[i].signal and params[i].signal.name then
  1494.             local color = ""
  1495.             if i == 1 then
  1496.               color = "signal-red"
  1497.             elseif i == 2 then
  1498.               color = "signal-green"
  1499.             elseif i == 3 then
  1500.               color = "signal-blue"
  1501.             elseif i == 4 then
  1502.               color = "signal-yellow"
  1503.             elseif i == 5 then
  1504.               color = "signal-pink"
  1505.             elseif i == 6 then
  1506.               color = "signal-cyan"
  1507.             end
  1508.             if get_count(control, params[i].signal) == params[i].count then
  1509.               table.insert(slots, {signal = {type = "virtual", name = color}, count = 1, index = i})
  1510.             else
  1511.               table.insert(slots, {signal = {type = "virtual", name = color}, count = 0, index = i})
  1512.             end
  1513.           end
  1514.         end
  1515.         control.parameters = {
  1516.           parameters = slots
  1517.         }
  1518.       else
  1519.         control.parameters = {
  1520.           parameters = {
  1521.             {signal = {type = "virtual", name = "signal-red"}, count = 0, index = 1},
  1522.             {signal = {type = "virtual", name = "signal-green"}, count = 0, index = 2},
  1523.             {signal = {type = "virtual", name = "signal-blue"}, count = 0, index = 3},
  1524.             {signal = {type = "virtual", name = "signal-yellow"}, count = 0, index = 4},
  1525.             {signal = {type = "virtual", name = "signal-pink"}, count = 0, index = 5},
  1526.             {signal = {type = "virtual", name = "signal-cyan"}, count = 0, index = 6}
  1527.           }
  1528.         }
  1529.       end
  1530.     end
  1531.   end
  1532. }
  1533.  
  1534. classes["emitter-combinator"] = {
  1535.   on_click = function(player, object)
  1536.     local gui = player.gui.center
  1537.     local params = {}
  1538.     for i = 1,6 do
  1539.       if gui["uc"]["emitter-combinator"]["signal"..i].elem_value then
  1540.         params[i] = {signal = gui["uc"]["emitter-combinator"]["signal"..i].elem_value}
  1541.       else
  1542.         params[i] = {signal = {type = "virtual"}}
  1543.       end
  1544.     end
  1545.     object.meta.params = params
  1546.   end,
  1547.   on_key = function(player, object)
  1548.     if not (player.gui.center["uc"]) then
  1549.       local gui = player.gui.center
  1550.       local params = object.meta.params
  1551.       local uc = gui.add{type = "frame", name = "uc", caption = "Emitter Combinator"}
  1552.       local layout = uc.add{type = "table", name = "emitter-combinator", colspan = 8}
  1553.       layout.add{type = "label", caption = "Signal: (?)", tooltip = {"emitter-combinator.signal"}}
  1554.       if params[1] and params[1].signal then  
  1555.         layout.add{type = "choose-elem-button", name = "signal1", elem_type = "signal", signal = params[1].signal}
  1556.       else
  1557.         layout.add{type = "choose-elem-button", name = "signal1", elem_type = "signal"}
  1558.       end
  1559.       layout.add{type = "label", caption = "Filter: (?)", tooltip = {"emitter-combinator.filter"}}
  1560.       for i= 2,6 do
  1561.         if params[i] and params[i].signal then
  1562.           layout.add{type = "choose-elem-button", name = "signal" .. i, elem_type = "signal", signal = params[i].signal}
  1563.         else
  1564.           layout.add{type = "choose-elem-button", name = "signal" .. i, elem_type = "signal"}
  1565.         end
  1566.       end
  1567.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1568.     end
  1569.   end,
  1570.   on_place = function(entity)
  1571.     return {
  1572.       meta = {
  1573.         entity = entity,
  1574.         params = {}
  1575.       }
  1576.     }
  1577.   end,
  1578.   on_destroy = function() end,
  1579.   on_tick = function(object)
  1580.     local control = object.meta.entity.get_control_behavior()
  1581.     if control then
  1582.       local params = object.meta.params
  1583.       if control.enabled then
  1584.         for i = 2,9 do
  1585.           if params[i] and params[i].signal and params[i].signal.name then
  1586.             object.meta.params[i].count = get_count(control, params[i].signal)
  1587.           end
  1588.         end
  1589.       end
  1590.     end
  1591.   end
  1592. }
  1593.  
  1594. classes["receiver-combinator"] = {
  1595.   on_click = function(player, object)
  1596.     local gui = player.gui.center
  1597.     if gui["uc"]["receiver-combinator"]["signal"].elem_value then
  1598.       object.meta.signal = gui["uc"]["receiver-combinator"]["signal"].elem_value
  1599.     else
  1600.       object.meta.signal = { type = "virtual" }
  1601.     end
  1602.   end,
  1603.   on_key = function(player, object)
  1604.     if not (player.gui.center["uc"]) then
  1605.       local gui = player.gui.center
  1606.       local uc = gui.add{type = "frame", name = "uc", caption = "Receiver Combinator"}
  1607.       local layout = uc.add{type = "table", name = "receiver-combinator", colspan = 2}
  1608.       layout.add{type = "label", caption = "Signal: (?)", tooltip = {"receiver-combinator.signal"}}
  1609.       layout.add{type = "choose-elem-button", name = "signal", elem_type = "signal", signal = object.meta.signal}
  1610.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1611.     end
  1612.   end,
  1613.   on_place = function(entity)
  1614.     return {
  1615.       meta = {
  1616.         entity = entity,
  1617.         signal = { type = "virtual", name = "signal-0"}
  1618.       }
  1619.     }
  1620.   end,
  1621.   on_destroy = function() end,
  1622.   on_tick = function(object)
  1623.     local control = object.meta.entity.get_control_behavior()
  1624.     if control then
  1625.       local params = control.parameters.parameters
  1626.       if object.meta.signal.name then
  1627.         local slots = {}
  1628.         local p1 = object.meta.signal
  1629.         if control.enabled then
  1630.           local sender
  1631.           for k,v in pairs(data["emitter-combinator"]) do
  1632.             if v.meta.params[1] and (p1.name == v.meta.params[1].signal.name) then
  1633.               sender = v.meta
  1634.               break;
  1635.             end
  1636.           end
  1637.           if sender then
  1638.             local sender_control = sender.entity.get_control_behavior()
  1639.             for i = 2,6 do
  1640.               if sender.params[i].signal and sender.params[i].signal.name then
  1641.                 table.insert(slots, {signal = sender.params[i].signal, count = sender.params[i].count, index = (i - 1)})
  1642.               end
  1643.             end
  1644.           end
  1645.           control.parameters = {
  1646.             parameters = slots
  1647.           }
  1648.         end
  1649.       else
  1650.         control.parameters = {
  1651.           parameters = {}
  1652.         }
  1653.       end
  1654.     end
  1655.   end
  1656. }
  1657.  
  1658. classes["power-combinator"] = {
  1659.   on_click = function(player, object)
  1660.     local gui = player.gui.center
  1661.     object.meta.ticks = tonumber(gui["uc"]["power-combinator"]["ticks"].text) or 1
  1662.   end,
  1663.   on_key = function(player, object)
  1664.     if not (player.gui.center["uc"]) then
  1665.       local gui = player.gui.center
  1666.       local uc = gui.add{type = "frame", name = "uc", caption = "Power Combinator"}
  1667.       local layout = uc.add{type = "table", name = "power-combinator", colspan = 2}
  1668.       layout.add{type = "label", caption = "Ticks: (?)", tooltip = {"power-combinator.ticks"}}
  1669.       layout.add{type = "textfield", name = "ticks", style = "uc_text", text = object.meta.ticks}
  1670.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1671.     end
  1672.   end,
  1673.   on_place = function(entity)
  1674.     return {
  1675.       meta = {
  1676.         entity = entity,
  1677.         ticks = 1,
  1678.         prev = 0,
  1679.         params = {
  1680.           {signal = {type = "virtual", name = "watts-signal"}, count = 0, index = 4},
  1681.           {signal = {type = "virtual", name = "kilo-watts-signal"}, count = 0, index = 3},
  1682.           {signal = {type = "virtual", name = "mega-watts-signal"}, count = 0, index = 2},
  1683.           {signal = {type = "virtual", name = "giga-watts-signal"}, count = 0, index = 1}
  1684.         }
  1685.       }
  1686.     }
  1687.   end,
  1688.   on_destroy = function(object) end,
  1689.   on_tick = function(object)
  1690.     local control = object.meta.entity.get_control_behavior()
  1691.     if control then
  1692.       local params = object.meta.params
  1693.       if params[1].signal.name then
  1694.         local ticks = object.meta.ticks
  1695.         if ticks < 1 then
  1696.           ticks = 1
  1697.           object.meta.ticks = 1
  1698.         end
  1699.         if ticks > 3600 then
  1700.           ticks = 3600
  1701.           object.meta.ticks = 3600
  1702.         end
  1703.         if control.enabled then
  1704.           local slots = {
  1705.             {signal = params[4].signal, count = params[4].count, index = 4},
  1706.             {signal = params[3].signal, count = params[3].count, index = 3},
  1707.             {signal = params[2].signal, count = params[2].count, index = 2},
  1708.             {signal = params[1].signal, count = params[1].count, index = 1}
  1709.           }
  1710.           local pos = object.meta.entity.position
  1711.           local poles = object.meta.entity.surface.find_entities_filtered(
  1712.             {
  1713.               area = {{pos.x - 1, pos.y - 1}, {pos.x + 1, pos.y + 1}},
  1714.               type = "electric-pole"
  1715.             })
  1716.           local power = 0
  1717.           local watts = 0
  1718.           if #poles > 0 then
  1719.             for _,p in pairs(poles) do
  1720.               for k,v in pairs(p.electric_network_statistics.output_counts) do
  1721.                 power = power + (p.electric_network_statistics.get_output_count(k) or 0)
  1722.               end
  1723.               if power > 0 then
  1724.                 break
  1725.               end
  1726.             end
  1727.             watts = (power - object.meta.prev) * 60
  1728.             object.meta.prev = power
  1729.           end
  1730.           if ((game.tick % ticks) == 0) then
  1731.             slots = {}
  1732.             local w = watts % 1000
  1733.             local kw = ((watts - w) / 1000) % 1000
  1734.             local mw = ((watts - (w + (kw * 1000))) / (10 ^ 6)) % 1000
  1735.             local gw = ((watts - (w + (kw * 1000) + (mw * 10 ^ 6))) / (10 ^ 9))
  1736.             table.insert(slots, {signal = {type = "virtual", name = "giga-watts-signal"}, count = gw, index = 1})
  1737.             table.insert(slots, {signal = {type = "virtual", name = "mega-watts-signal"}, count = mw, index = 2})
  1738.             table.insert(slots, {signal = {type = "virtual", name = "kilo-watts-signal"}, count = kw, index = 3})
  1739.             table.insert(slots, {signal = {type = "virtual", name = "watts-signal"}, count = w, index = 4})
  1740.             object.meta.params = slots
  1741.           end
  1742.           control.parameters = {
  1743.             parameters = slots
  1744.           }
  1745.         end
  1746.       else
  1747.         control.parameters = {
  1748.           parameters = {
  1749.             {signal = {type = "virtual", name = "watts-signal"}, count = 0, index = 4},
  1750.             {signal = {type = "virtual", name = "kilo-watts-signal"}, count = 0, index = 3},
  1751.             {signal = {type = "virtual", name = "mega-watts-signal"}, count = 0, index = 2},
  1752.             {signal = {type = "virtual", name = "giga-watts-signal"}, count = 0, index = 1},
  1753.           }
  1754.         }
  1755.       end
  1756.     end
  1757.   end
  1758. }
  1759.  
  1760. classes["daytime-combinator"] = {
  1761.   on_click = function(player, object)
  1762.     local gui = player.gui.center
  1763.     if gui["uc"]["daytime-combinator"]["minutes"].elem_value and gui["uc"]["daytime-combinator"]["minutes"].elem_value.name then
  1764.       object.meta.minutes = gui["uc"]["daytime-combinator"]["minutes"].elem_value
  1765.     else
  1766.       object.meta.minutes = {type = "virtual", name = "signal-M"}
  1767.     end
  1768.     if gui["uc"]["daytime-combinator"]["hours"].elem_value and gui["uc"]["daytime-combinator"]["hours"].elem_value.name then
  1769.       object.meta.hours = gui["uc"]["daytime-combinator"]["hours"].elem_value
  1770.     else
  1771.       object.meta.hours = {type = "virtual", name = "signal-H"}
  1772.     end
  1773.   end,
  1774.   on_key = function(player, object)
  1775.     if not (player.gui.center["uc"]) then
  1776.       local meta = object.meta
  1777.       local gui = player.gui.center
  1778.       local uc = gui.add{type = "frame", name = "uc", caption = "Daytime Combinator"}
  1779.       local layout = uc.add{type = "table", name = "daytime-combinator", colspan = 2}
  1780.       layout.add{type = "label", caption = "Minutes: (?)", tooltip = {"daytime-combinator.minutes"}}
  1781.       if meta.minutes and meta.minutes.name then
  1782.         layout.add{type = "choose-elem-button", name = "minutes", elem_type = "signal", signal = meta.minutes}
  1783.       else
  1784.         layout.add{type = "choose-elem-button", name = "minutes", elem_type = "signal"}
  1785.       end
  1786.       layout.add{type = "label", caption = "Hours: (?)", tooltip = {"daytime-combinator.hours"}}
  1787.       if meta.hours and meta.hours.name then
  1788.         layout.add{type = "choose-elem-button", name = "hours", elem_type = "signal", signal = meta.hours}
  1789.       else
  1790.         layout.add{type = "choose-elem-button", name = "hours", elem_type = "signal"}
  1791.       end
  1792.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1793.     end
  1794.   end,
  1795.   on_place = function(entity)
  1796.     return {
  1797.       meta = {
  1798.         entity = entity,
  1799.         minutes = {type = "virtual", name = "signal-M"},
  1800.         hours = {type = "virtual", name = "signal-H"}
  1801.       }
  1802.     }
  1803.   end,
  1804.   on_destroy = function() end,
  1805.   on_tick = function(object)
  1806.     local control = object.meta.entity.get_control_behavior()
  1807.     if control then
  1808.       if control.enabled then
  1809.         local slots = {}
  1810.         local meta = object.meta
  1811.         local daytime = (meta.entity.surface.daytime * 24 + 12) % 24
  1812.         if meta.minutes and meta.minutes.name then
  1813.           table.insert(slots, {signal = meta.minutes, count = math.floor((daytime - math.floor(daytime)) * 60), index = 1})
  1814.         end
  1815.         if meta.hours and meta.hours.name then
  1816.           table.insert(slots, {signal = meta.hours, count = math.floor(daytime), index = 2})
  1817.         end
  1818.         control.parameters = {
  1819.           parameters = slots
  1820.         }
  1821.       end
  1822.     else
  1823.       control.parameters = {
  1824.         parameters = {
  1825.           {signal = {type = "virtual", name = "signal-M"}, count = 0, index = 1},
  1826.           {signal = {type = "virtual", name = "signal-H"}, count = 0, index = 2}
  1827.         }
  1828.       }
  1829.     end
  1830.   end
  1831. }
  1832.  
  1833. classes["pollution-combinator"] = {
  1834.   on_click = function(player, object)
  1835.     local gui = player.gui.center
  1836.     if gui["uc"]["pollution-combinator"]["output"].elem_value and gui["uc"]["pollution-combinator"]["output"].elem_value.name then
  1837.       object.meta.minutes = gui["uc"]["pollution-combinator"]["output"].elem_value
  1838.     else
  1839.       object.meta.minutes = {type = "virtual"}
  1840.     end
  1841.   end,
  1842.   on_key = function(player, object)
  1843.     if not (player.gui.center["uc"]) then
  1844.       local meta = object.meta
  1845.       local gui = player.gui.center
  1846.       local uc = gui.add{type = "frame", name = "uc", caption = "Pollution Combinator"}
  1847.       local layout = uc.add{type = "table", name = "pollution-combinator", colspan = 2}
  1848.       layout.add{type = "label", caption = "Output: (?)", tooltip = {"pollution-combinator.output"}}
  1849.       if meta.output and meta.output.name then
  1850.         layout.add{type = "choose-elem-button", name = "output", elem_type = "signal", signal = meta.output}
  1851.       else
  1852.         layout.add{type = "choose-elem-button", name = "output", elem_type = "signal"}
  1853.       end
  1854.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1855.     end
  1856.   end,
  1857.   on_place = function(entity)
  1858.     return {
  1859.       meta = {
  1860.         entity = entity,
  1861.         output = {type = "virtual", name = "output-signal"}
  1862.       }
  1863.     }
  1864.   end,
  1865.   on_destroy = function() end,
  1866.   on_tick = function(object)
  1867.     local control = object.meta.entity.get_control_behavior()
  1868.     if control then
  1869.       if control.enabled then
  1870.         local slots = {}
  1871.         local meta = object.meta
  1872.         local pollution = meta.entity.surface.get_pollution(meta.entity.position)
  1873.         if meta.output and meta.output.name then
  1874.           table.insert(slots, {signal = meta.output, count = pollution, index = 1})
  1875.         end
  1876.         control.parameters = {
  1877.           parameters = slots
  1878.         }
  1879.       end
  1880.     else
  1881.       control.parameters = {
  1882.         parameters = {
  1883.           {signal = {type = "virtual", name = "output-signal"}, count = 0, index = 1}
  1884.         }
  1885.       }
  1886.     end
  1887.   end
  1888. }
  1889.  
  1890. classes["statistic-combinator"] = {
  1891.   on_click = function(player, object)
  1892.     local gui = player.gui.center
  1893.     local params = {}
  1894.     for i = 1,8 do
  1895.       if gui["uc"]["statistic-combinator"]["signal"..i].elem_value then
  1896.         params[i] = {signal = {name = gui["uc"]["statistic-combinator"]["signal"..i].elem_value, type = "item"}}
  1897.         game.players[1].print(params[i].signal.name)
  1898.       else
  1899.         params[i] = {signal = {type = "item"}}
  1900.       end
  1901.     end
  1902.     object.meta.params = params
  1903.     object.meta.index = gui["uc"]["statistic-combinator"]["stat"].selected_index
  1904.     --object.meta.ticks = tonumber(gui["uc"]["statistic-combinator"]["ticks"].text) or 1
  1905.   end,
  1906.   on_key = function(player, object)
  1907.     if not (player.gui.center["uc"]) then
  1908.       local gui = player.gui.center
  1909.       local params = object.meta.params
  1910.       local uc = gui.add{type = "frame", name = "uc", caption = "Statistic Combinator"}
  1911.       local layout = uc.add{type = "table", name = "statistic-combinator", colspan = 11}
  1912.       layout.add{type = "label", caption = "Type: (?)", tooltip = {"statistic-combinator.stat"}}
  1913.       layout.add{type = "drop-down", name = "stat", items = {{"statistic-combinator.production"}, {"statistic-combinator.consumption"}}, selected_index = object.meta.index}
  1914.       --layout.add{type = "label", caption = "Ticks: (?)", tooltip = {"statistic-combinator.ticks"}}
  1915.       --layout.add{type = "textfield", name = "ticks", style = "uc_text", text = object.meta.ticks}
  1916.       layout.add{type = "label", caption = "Filter: (?)", tooltip = {"statistic-combinator.filter"}}
  1917.       for i= 1,8 do
  1918.         if params[i] and params[i].signal and params[i].signal.name then
  1919.           layout.add{type = "choose-elem-button", name = "signal" .. i, elem_type = "item", item = params[i].signal.name}
  1920.         else
  1921.           layout.add{type = "choose-elem-button", name = "signal" .. i, elem_type = "item"}
  1922.         end
  1923.       end
  1924.       layout.add{type = "button", name = "uc-exit", caption = "Ok"}
  1925.     end
  1926.   end,
  1927.   on_place = function(entity)
  1928.     return {
  1929.       meta = {
  1930.         entity = entity,
  1931.         params = {
  1932.           {signal = {type = "item"}, count = 0, index = 1},
  1933.           {signal = {type = "item"}, count = 0, index = 2},
  1934.           {signal = {type = "item"}, count = 0, index = 3},
  1935.           {signal = {type = "item"}, count = 0, index = 4},
  1936.           {signal = {type = "item"}, count = 0, index = 5},
  1937.           {signal = {type = "item"}, count = 0, index = 6},
  1938.           {signal = {type = "item"}, count = 0, index = 7},
  1939.           {signal = {type = "item"}, count = 0, index = 8}
  1940.         },
  1941.         --ticks = 300,
  1942.         prev = {0, 0, 0, 0, 0, 0, 0, 0},
  1943.         index = 1
  1944.       }
  1945.     }
  1946.   end,
  1947.   on_destroy = function() end,
  1948.   on_tick = function(object)
  1949.     local control = object.meta.entity.get_control_behavior()
  1950.     if control then
  1951.       local params = object.meta.params
  1952.       if control.enabled then
  1953.         local slots = {
  1954.           {signal = params[1].signal, count = params[1].count or 0, index = 1},
  1955.           {signal = params[2].signal, count = params[2].count or 0, index = 2},
  1956.           {signal = params[3].signal, count = params[3].count or 0, index = 3},
  1957.           {signal = params[4].signal, count = params[4].count or 0, index = 4},
  1958.           {signal = params[5].signal, count = params[5].count or 0, index = 5},
  1959.           {signal = params[6].signal, count = params[6].count or 0, index = 6},
  1960.           {signal = params[7].signal, count = params[7].count or 0, index = 7},
  1961.           {signal = params[8].signal, count = params[8].count or 0, index = 8}
  1962.         }
  1963.         --[[local ticks = object.meta.ticks
  1964.         if ticks < 1 then
  1965.           ticks = 1
  1966.           object.meta.ticks = 1
  1967.         end
  1968.         if ticks > 3600 then
  1969.           ticks = 3600
  1970.           object.meta.ticks = 3600
  1971.         end]]
  1972.         if ((game.tick % 60) == 0) then
  1973.           for i = 1,8 do
  1974.             if params[i] and params[i].signal and params[i].signal.name then
  1975.               local stats
  1976.               local flow
  1977.               if game.item_prototypes[params[i].signal.name] and game.item_prototypes[params[i].signal.name].type == "fluid" then
  1978.                 stats = object.meta.entity.force.fluid_production_statistics
  1979.               else
  1980.                 stats = object.meta.entity.force.item_production_statistics
  1981.               end
  1982.               if object.meta.index == 1 then
  1983.                 flow = stats.get_input_count(params[i].signal.name) or 0
  1984.               elseif object.meta.index == 2 then
  1985.                 flow = stats.get_output_count(params[i].signal.name) or 0
  1986.               end
  1987.               local old = object.meta.prev[i]
  1988.               object.meta.params[i].count = flow - old
  1989.               table.insert(slots, {signal = params[i].signal, count = object.meta.params[i].count, index = i})
  1990.               object.meta.prev[i] = flow
  1991.             end
  1992.           end
  1993.         end
  1994.         control.parameters = {
  1995.           parameters = slots
  1996.         }
  1997.       end
  1998.     else
  1999.       control.parameters = {
  2000.         parameters = {
  2001.           {signal = {type = "item"}, count = 0, index = 1},
  2002.           {signal = {type = "item"}, count = 0, index = 2},
  2003.           {signal = {type = "item"}, count = 0, index = 3},
  2004.           {signal = {type = "item"}, count = 0, index = 4},
  2005.           {signal = {type = "item"}, count = 0, index = 5},
  2006.           {signal = {type = "item"}, count = 0, index = 6},
  2007.           {signal = {type = "item"}, count = 0, index = 7},
  2008.           {signal = {type = "item"}, count = 0, index = 8}
  2009.         }
  2010.       }
  2011.     end
  2012.   end
  2013. }
  2014.  
  2015. function get_count(control, signal)
  2016.   if not signal then return 0 end
  2017.   local red = control.get_circuit_network(defines.wire_type.red)
  2018.   local green = control.get_circuit_network(defines.wire_type.green)
  2019.   local val = 0
  2020.   if red then
  2021.     val = red.get_signal(signal) or 0
  2022.   end
  2023.   if green then
  2024.     val = val + (green.get_signal(signal) or 0)
  2025.   end
  2026.   return val
  2027. end
  2028.  
  2029. function get_signals(control)
  2030.   local red = control.get_circuit_network(defines.wire_type.red)
  2031.   local green = control.get_circuit_network(defines.wire_type.green)
  2032.   local network = {}
  2033.   if red and red.signals then
  2034.     for _,v in pairs(red.signals) do
  2035.       if v.signal.name then
  2036.         network[v.signal.name] = v
  2037.       end
  2038.     end
  2039.   end
  2040.   if green and green.signals then
  2041.     for _,v in pairs(green.signals) do
  2042.       if v.signal.name then
  2043.         network[v.signal.name] = v
  2044.       end
  2045.     end
  2046.   end
  2047.   return network
  2048. end
  2049.  
  2050. function entity_built(event)
  2051.   if classes[event.created_entity.name] ~= nil then
  2052.     local tab = data[event.created_entity.name] or {}
  2053.     table.insert(tab, classes[event.created_entity.name].on_place(event.created_entity))
  2054.     data[event.created_entity.name] = tab
  2055.     save()
  2056.   end
  2057. end
  2058.  
  2059. function entity_removed(event)
  2060.   if classes[event.entity.name] ~= nil then
  2061.     for k,v in ipairs(data[event.entity.name]) do
  2062.       if v.meta.entity == event.entity then
  2063.         local tab = data[event.entity.name]
  2064.         table.remove(tab, k)
  2065.         classes[event.entity.name].on_destroy(v)
  2066.         data[event.entity.name] = tab
  2067.         for i,j in pairs(selected) do
  2068.           if j.entity == v.meta.entity then
  2069.             j.player.gui.center["uc"].destroy()
  2070.             table.remove(selected, i)
  2071.           end
  2072.         end
  2073.         save()
  2074.         break
  2075.       end
  2076.     end
  2077.   end
  2078. end
  2079.  
  2080. function tick()
  2081.   for k,v in pairs(classes) do
  2082.     if data ~= nil and data[k] ~= nil then
  2083.       for q,i in pairs(data[k]) do
  2084.         if i.meta and i.meta.entity.valid then
  2085.           v.on_tick(i, q)
  2086.         end
  2087.       end
  2088.     end
  2089.   end
  2090. end
  2091.  
  2092. function uc_load()
  2093.   data = global["uc_data"] or {}
  2094. end
  2095.  
  2096. function init()
  2097.   data = global["uc_data"] or {}
  2098.   for k,v in pairs(classes) do
  2099.     data[k] = data[k] or {}
  2100.   end
  2101. end
  2102.  
  2103. function configuration_changed(cfg)
  2104.   if cfg.mod_changes then
  2105.     local changes = cfg.mod_changes["UsefulCombinators"]
  2106.     if changes then
  2107.       init()
  2108.       if global["uc_data"] then
  2109.         for k,v in pairs(classes) do
  2110.           local tab = {}
  2111.           for _,s in pairs(game.surfaces) do
  2112.             for i,j in pairs(s.find_entities_filtered({name = k})) do
  2113.               table.insert(tab, classes[k].on_place(j))
  2114.               data[k] = tab
  2115.             end
  2116.           end
  2117.           save()
  2118.         end
  2119.       end
  2120.     end
  2121.   end
  2122. end
  2123.  
  2124. function on_key(event)
  2125.   local player = game.players[event.player_index]
  2126.   local entity = player.selected
  2127.   if entity and player.can_reach_entity(entity) then
  2128.     for k,v in pairs(classes) do
  2129.       if data ~= nil and data[k] ~= nil then
  2130.         if entity.name == k then
  2131.           for h,i in pairs(data[k]) do
  2132.             if i.meta.entity.valid then
  2133.               if i.meta.entity == entity then
  2134.                 if not (player.gui.center["uc"]) and not player.cursor_stack.valid_for_read then
  2135.                   table.insert(selected, { player = player, entity = entity})
  2136.                   v.on_key(player, i)
  2137.                   if entity.operable then
  2138.                     entity.operable = false
  2139.                   end
  2140.                   break
  2141.                 end
  2142.               end
  2143.             end
  2144.           end
  2145.         end
  2146.       end
  2147.     end
  2148.   end
  2149. end
  2150.  
  2151. function on_click_ok(event)
  2152.   local player = game.players[event.player_index]
  2153.   local element = event.element
  2154.   if element.name and element.name == "uc-exit" then
  2155.     for k,v in pairs(classes) do
  2156.       if data and data[k] then
  2157.         for h,i in pairs(data[k]) do
  2158.           for l,m in pairs(selected) do
  2159.             if i.meta.entity == m.entity then
  2160.               v.on_click(player, i)
  2161.               table.remove(selected, l)
  2162.               if not i.meta.entity.operable then
  2163.                 i.meta.entity.operable = true
  2164.               end
  2165.               break
  2166.             end
  2167.           end
  2168.         end
  2169.       end
  2170.     end
  2171.     player.gui.center["uc"].destroy()
  2172.   end
  2173. end
  2174.  
  2175. --[[function on_paste(event)
  2176.   local player = game.players[event.player_index]
  2177.   local copy,paste = event.source,event.destination
  2178.   for k,v in pairs(classes) do
  2179.     if copy.name == k and paste.name == k then
  2180.       if copy.valid and paste.valid then
  2181.         if data and data[k] then
  2182.           local from,to
  2183.           for a,b in pairs (data[k]) do
  2184.             if b.meta.entity == copy then
  2185.               from = b
  2186.               break
  2187.             end
  2188.           end
  2189.           for a,b in pairs (data[k]) do
  2190.             if b.meta.entity == paste then
  2191.               to = b
  2192.               break
  2193.             end
  2194.           end
  2195.           for a,b in pairs(from.meta) do
  2196.             if not (a == "entity") then
  2197.               to.meta[a] = b
  2198.             end
  2199.           end
  2200.         end
  2201.       end
  2202.     end
  2203.   end
  2204. end]]
  2205.  
  2206. script.on_init(init)
  2207. script.on_load(uc_load)
  2208. script.on_event(defines.events.on_built_entity, entity_built)
  2209. script.on_event(defines.events.on_robot_built_entity, entity_built)
  2210. script.on_event(defines.events.on_preplayer_mined_item, entity_removed)
  2211. script.on_event(defines.events.on_robot_pre_mined, entity_removed)
  2212. script.on_event(defines.events.on_entity_died, entity_removed)
  2213. script.on_event(defines.events.on_tick, tick)
  2214. script.on_event(defines.events.on_gui_click, on_click_ok)
  2215. --script.on_event(defines.events.on_entity_settings_pasted, on_paste)
  2216. script.on_event("uc-edit", on_key)
  2217. script.on_configuration_changed(configuration_changed)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement