Advertisement
osmarks

Autonomous Bee Processor

Nov 16th, 2021 (edited)
1,117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.09 KB | None | 0 0
  1. local input_chest = "actuallyadditions:giantchestlarge_0"
  2. --local princess_chest = "actuallyadditions:giantchestlarge_2"
  3. local bee_products_chest = "actuallyadditions:giantchestlarge_1"
  4. local bee_overflow_chest = "actuallyadditions:giantchestlarge_7"
  5. local apiaries = {peripheral.find "forestry:apiary"}
  6. local index = {}
  7. local bee_list = {}
  8. local storage = {peripheral.find("actuallyadditions:giantchestlarge", function(n) return n ~= input_chest and n ~= bee_products_chest and n ~= bee_overflow_chest end)}
  9. print("Got", #storage, "storage chests")
  10.  
  11. local function find_free_space()
  12.     for _, inv in pairs(storage) do
  13.         if not inv.cached_size then inv.cached_size = inv.size() end
  14.         local name = peripheral.getName(inv)
  15.         if not index[name] then
  16.             return name, 1
  17.         end
  18.         for slot = 1, inv.cached_size do
  19.             if not index[name][slot] then return name, slot end
  20.         end
  21.     end
  22. end
  23.  
  24. local function run_cleanup()
  25.     for i = 1, peripheral.call(bee_overflow_chest, "size") do
  26.         local bee = bee_list[1]
  27.         local moved = peripheral.call(bee_overflow_chest, "pullItems", bee[1], bee[2])
  28.         index[bee[1]][bee[2]].count = index[bee[1]][bee[2]].count - moved
  29.         if index[bee[1]][bee[2]].count == 0 then
  30.             index[bee[1]][bee[2]] = nil
  31.             table.remove(bee_list, 1)
  32.         end
  33.         print("Eliminated", moved, "bees")
  34.     end
  35. end
  36.  
  37. local tol_table = {
  38.     none = 0,
  39.     both_1 = 3,
  40.     both_2 = 4,
  41.     both_3 = 6,
  42.     up_1 = 1.5,
  43.     down_1 = 1.5,
  44.     up_2 = 2,
  45.     down_2 = 2,
  46.     up_3 = 3,
  47.     down_3 = 3
  48. }
  49.  
  50. local function score_genome_slot(g)
  51.     local score = g.speed * 8 + (20 / g.lifespan) + g.fertility
  52.     if g.never_sleeps then score = score + 5 end
  53.     if g.tolerates_rain then score = score + 2 end
  54.     if g.cave_dwelling then score = score + 5 end
  55.     score = score + tol_table[g.humidity_tolerance]
  56.     score = score + tol_table[g.temperature_tolerance]
  57.     return score
  58. end
  59.  
  60. local function score_bee(individual)
  61.     return score_genome_slot(individual.genome.active) + 0.5 * score_genome_slot(individual.genome.inactive)
  62. end
  63.  
  64. local function insert_into_list(bee, inv, slot)
  65.     local score = score_bee(bee.bee_data)
  66.     local lo, hi = 1, #bee_list + 1
  67.     while lo < hi do
  68.         local mid = math.floor((lo + hi) / 2)
  69.         local compr_score = bee_list[mid][3]
  70.         if score < compr_score then
  71.             hi = mid
  72.         else
  73.             lo = mid + 1
  74.         end
  75.     end
  76.     table.insert(bee_list, lo, { inv, slot, score })
  77. end
  78.  
  79. local indexed_count = 0
  80. print "Bee indexing initiating"
  81. for _, chest in pairs(storage) do
  82.     local name = peripheral.getName(chest)
  83.     if not index[name] then index[name] = {} end
  84.     for slot, item in pairs(chest.list()) do
  85.         local meta = chest.getItemMeta(slot)
  86.         index[name][slot] = { count = item.count, name = meta.displayName, bee_data = meta.individual }
  87.         indexed_count = indexed_count + 1
  88.         if indexed_count % 100 == 0 then sleep() print(indexed_count, "bees indexed") end
  89.     end
  90. end
  91. print(indexed_count, "bees indexed")
  92.  
  93. print "Bee list preload initiating"
  94. for inv, contents in pairs(index) do
  95.     for slot, bee in pairs(contents) do
  96.         insert_into_list(bee, inv, slot)
  97.     end
  98. end
  99.  
  100. while true do
  101.     local modified_count = 0
  102.     for slot, info in pairs(peripheral.call(input_chest, "list")) do
  103.         if string.find(info.name, "drone") then
  104.             local meta = peripheral.call(input_chest, "getItemMeta", slot)
  105.             local invname, targslot = find_free_space()
  106.             if not invname then
  107.                 printError "Bee store at capacity - initiating cleanup."
  108.                 run_cleanup()
  109.                 sleep(1)
  110.             else
  111.                 local moved = peripheral.call(input_chest, "pushItems", invname, slot, 64, targslot)
  112.                 if not moved then
  113.                     printError "Bees nonmotile"
  114.                     sleep(1)
  115.                 else
  116.                     data = { count = moved, name = meta.displayName, bee_data = meta.individual }
  117.                     index[invname] = index[invname] or {}
  118.                     index[invname][targslot] = data
  119.                     modified_count = modified_count + 1
  120.                     insert_into_list(data, invname, targslot)
  121.                 end
  122.             end
  123.         elseif not string.find(info.name, "princess") then
  124.             peripheral.call(input_chest, "pushItems", bee_products_chest, slot)
  125.         end    
  126.     end
  127.     print("Loaded", modified_count, "unique bees into stores")
  128.     modified_count = 0
  129.     for _, apiary in pairs(apiaries) do
  130.         local content = apiary.list()
  131.         if not content[1] then -- need princess
  132.             print "Loading princess"
  133.             local success = false
  134.             for slot, ccontent in pairs(peripheral.call(input_chest, "list")) do
  135.                 if ccontent and string.find(ccontent.name, "princess") then
  136.                     peripheral.call(input_chest, "pushItems", peripheral.getName(apiary), slot)
  137.                     success = true
  138.                     break
  139.                 end
  140.             end
  141.             if not success then
  142.                 printError "Insufficient princesses"
  143.                 sleep(1)
  144.             end
  145.         end
  146.         if not content[2] then
  147.             print "Loading drone"
  148.             local bee = table.remove(bee_list)
  149.             if not bee then
  150.                 printError "Drone not found"
  151.                 sleep(1)
  152.             else
  153.                 local moved = peripheral.call(bee[1], "pushItems", peripheral.getName(apiary), bee[2])
  154.                 index[bee[1]][bee[2]].count = index[bee[1]][bee[2]].count - moved
  155.                 if index[bee[1]][bee[2]].count == 0 then
  156.                     index[bee[1]][bee[2]] = nil
  157.                 end
  158.                 modified_count = modified_count + 1
  159.             end
  160.         end
  161.         sleep(0.05)
  162.     end
  163.     print("Moved", modified_count, "drones")
  164. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement