Advertisement
firegodjr

Computercraft Library Manager

Apr 5th, 2020
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.25 KB | None | 0 0
  1. Args = {...}
  2.  
  3. os.loadAPI("apis/log.lua")
  4. os.loadAPI("apis/pos.lua")
  5. os.loadAPI("apis/storage.lua")
  6.  
  7. local ST_IDLE = "idle"
  8. local ST_MAP_LIBRARY = "mapping_library"
  9. local ST_FIND_SPACE_FOR_ITEM = "finding_space_for_item"
  10. local ST_RETRIEVE_ITEMS = "retrieving_items"
  11.  
  12. local ItemMap = {}
  13. local EmptyChests = {}
  14. local BoundsMap = {}
  15. local ItemAliases = {}
  16.  
  17. --[[
  18. Log the current state to the resumefile
  19. ]]
  20. function SaveState()
  21. log.SaveData("resume", {"library"})
  22. log.SaveData("libraryItemMap", {textutils.serialize(ItemMap)})
  23. log.SaveData("libraryEmptyChests", {textutils.serialize(EmptyChests)})
  24. log.SaveData("libraryItemAliases", {textutils.serialize(ItemAliases)})
  25. end
  26.  
  27. --[[
  28. Load state using args from the resumefile
  29. ]]
  30. function LoadState(args)
  31. local itemMapData = log.LoadData("libraryItemMap")
  32. local emptyChestData = log.LoadData("libraryEmptyChests")
  33. local itemAliasData = log.LoadData("libraryItemAliases")
  34. if (itemMapData ~= nil and emptyChestData ~= nil and itemAliasData ~= nil) then
  35. ItemMap = textutils.unserialize(itemMapData)
  36. EmptyChests = textutils.unserialize(emptyChestData)
  37. ItemAliases = textutils.unserialize(itemAliasData)
  38. else
  39. ItemMap = {}
  40. EmptyChests = {}
  41. ItemAliases = {}
  42. end
  43. end
  44.  
  45. --[[
  46. Select an empty slot, if there is one.
  47. returns bool success
  48. ]]
  49. function SelectEmptySlot()
  50. local initialSlot = turtle.getSelectedSlot()
  51. turtle.select(1)
  52. while(turtle.getItemCount() > 0 and turtle.getSelectedSlot()+1 <= 16) do
  53. turtle.select(turtle.getSelectedSlot()+1)
  54. end
  55. if (turtle.getItemCount() == 0) then
  56. return true
  57. else
  58. turtle.select(initialSlot)
  59. return false
  60. end
  61. end
  62.  
  63. function SelectFullSlot()
  64. local initialSlot = turtle.getSelectedSlot()
  65. turtle.select(1)
  66. while(turtle.getItemCount() == 0 and turtle.getSelectedSlot()+1 <= 16) do
  67. turtle.select(turtle.getSelectedSlot()+1)
  68. end
  69. if (turtle.getItemCount() > 0) then
  70. return true
  71. else
  72. turtle.select(initialSlot)
  73. return false
  74. end
  75. end
  76.  
  77. --[[
  78. Test the chest ahead to see if it is empty.
  79. Requires at least one empty slot in inventory to function.
  80. returns bool success
  81. ]]
  82. function ChestIsEmpty()
  83. local initialSlot = turtle.getSelectedSlot()
  84. SelectEmptySlot()
  85.  
  86. if(turtle.suck(1)) then
  87. turtle.drop()
  88. turtle.select(initialSlot)
  89. return false;
  90. else
  91. turtle.select(initialSlot)
  92. return true;
  93. end
  94. end
  95.  
  96. --[[
  97. Load the turtle up with items, ensuring that the last slot is empty
  98. ]]
  99. function LoadEnsureEmpty()
  100. turtle.select(1)
  101. turtle.suck()
  102. while(turtle.select(turtle.getSelectedSlot()+1)) do
  103. turtle.suck()
  104. end
  105. turtle.drop()
  106. turtle.select(1)
  107. end
  108.  
  109. function DepositToChest(itemStr)
  110. print("Depositing "..itemStr.." in chest.")
  111. if not (ItemAliases) then
  112. ItemAliases = {}
  113. end
  114. local aliases = ItemAliases[itemStr]
  115. local chestIsFull = true
  116. local currentAlias = 1
  117. -- Ensure there is a chest available
  118. if(ItemMap == nil) then ItemMap = {} end
  119. if (aliases == nil) then
  120. if not(AssignEmptyChest(itemStr)) then
  121. DepositToDefault()
  122. return
  123. end
  124.  
  125. aliases = ItemAliases[itemStr]
  126. end
  127.  
  128. while (chestIsFull) do
  129. -- Get the alias for the current chest
  130. local alias = aliases[currentAlias]
  131.  
  132. -- Find the chest
  133. local chestPos = ItemMap[alias]
  134. if (chestPos.y > BoundsMap[pos.GetX()].y or chestPos.z > BoundsMap[pos.GetX()].z) then
  135. DepositToDefault()
  136. return
  137. end
  138. -- Navigate to the chest
  139. ReturnHome()
  140. if (chestPos.x > 0) then
  141. pos.TurnToFace(pos.X_POSITIVE)
  142. for i = 1, chestPos.x, 1 do
  143. pos.Forward()
  144. end
  145. pos.TurnToFace(pos.Z_POSITIVE)
  146. end
  147. for i = 1, chestPos.y, 1 do
  148. pos.Up()
  149. end
  150. for i = 1, chestPos.z, 1 do
  151. pos.Forward()
  152. end
  153. if (chestPos.positive_x) then
  154. pos.TurnToFace(pos.X_POSITIVE)
  155. else
  156. pos.TurnToFace(pos.X_NEGATIVE)
  157. end
  158.  
  159. local detail = turtle.getItemDetail()
  160. if (turtle.drop()) then
  161. chestIsFull = false
  162. storage.AddToStore(detail.name, detail.count)
  163. else
  164. currentAlias = currentAlias + 1
  165. print("Chest is full. Finding new chest.")
  166. end
  167. end
  168. end
  169.  
  170. function DepositToDefault()
  171. pos.TurnToFace(pos.X_NEGATIVE)
  172. local detail = turtle.getItemDetail()
  173. turtle.drop()
  174. if not (ItemCounts) then
  175. ItemCounts = {}
  176. end
  177. if (detail) then
  178. storage.AddToStore(detail.name, detail.count)
  179. end
  180. pos.TurnToFace(pos.Z_POSITIVE)
  181. end
  182.  
  183. function AssignEmptyChest(itemStr)
  184. if not (ItemAliases[itemStr]) then
  185. ItemAliases[itemStr] = {}
  186. end
  187. local alias = itemStr..tostring(#ItemAliases[itemStr])
  188. table.insert(ItemAliases[itemStr], alias)
  189. if not(SetChest(alias, table.remove(EmptyChests, 1))) then
  190. return nil
  191. end
  192. SaveState()
  193. return ItemMap[alias]
  194. end
  195.  
  196. function SetChest(itemStr, chestPos)
  197. local isFacingPositiveX = false
  198. if (pos.GetFace() == pos.X_POSITIVE) then
  199. isFacingPositiveX = true
  200. end
  201. if (chestPos ~= nil) then
  202. ItemMap[itemStr] = chestPos
  203. return true
  204. else
  205. return false
  206. end
  207. end
  208.  
  209. function InitEmptyChests(y, z, xVal)
  210. print("x: "..tostring(xVal)..", y: "..tostring(y)..", z: "..tostring(z))
  211. EmptyChests = {}
  212. for i = 0, y do
  213. for j = 1, z do
  214. local posXChestIsFull = false
  215. local negXChestIsFull = false
  216. for key, value in pairs(ItemMap) do
  217. if (value.x == xVal and value.y == i and value.z == j) then
  218. if (value.positive_x) then
  219. posXChestIsFull = true
  220. else
  221. negXChestIsFull = true
  222. end
  223. end
  224. end
  225. if not (posXChestIsFull) then
  226. table.insert(EmptyChests, {
  227. x=xVal,
  228. y=i,
  229. z=j,
  230. positive_x=true
  231. })
  232. end
  233. if not (negXChestIsFull) then
  234. table.insert(EmptyChests, {
  235. x=xVal,
  236. y=i,
  237. z=j,
  238. positive_x=false
  239. })
  240. end
  241. end
  242. end
  243. end
  244.  
  245. --[[
  246. Autonomously find the boundaries of the current library
  247. ]]
  248. function MapLibrary()
  249. while (pos.Forward()) do end
  250. while (pos.Up()) do end
  251. if not (BoundsMap) then BoundsMap = {} end
  252. InitBounds(pos.GetX(), pos.GetY(), pos.GetZ())
  253. ReturnHome()
  254. end
  255.  
  256. function InitBounds(xLocation, y, z)
  257. InitEmptyChests(y, z, xLocation)
  258. BoundsMap[xLocation] = {y=y, z=z}
  259. end
  260.  
  261. --[[
  262. Returns to the place the program was first run
  263. ]]
  264. function ReturnHome()
  265. pos.TurnToFace(pos.Z_POSITIVE)
  266. for i = 1, pos.GetY(), 1 do
  267. pos.Down()
  268. end
  269. for i = 1, pos.GetZ(), 1 do
  270. pos.Back()
  271. end
  272. if(pos.GetX() > 0) then
  273. pos.TurnToFace(pos.X_NEGATIVE)
  274. for i = 1, pos.GetX(), 1 do
  275. pos.Forward()
  276. end
  277. pos.TurnToFace(pos.Z_POSITIVE)
  278. end
  279. end
  280.  
  281. LoadState()
  282. if ItemMap == nil then ItemMap = {} end
  283. if EmptyChests == nil then EmptyChests = {} end
  284. MapLibrary()
  285. SaveState()
  286. ReturnHome()
  287.  
  288. while true do
  289. -- If items exist in inventory
  290. if (SelectFullSlot()) then
  291. local itemName = turtle.getItemDetail().name
  292. DepositToChest(itemName)
  293. local itemDetail = turtle.getItemDetail(turtle.getSelectedSlot()+1)
  294. while (itemDetail ~= nil and itemDetail.name == itemName) do
  295. turtle.select(turtle.getSelectedSlot()+1)
  296. turtle.drop()
  297. storage.AddToStore(itemDetail.name, itemDetail.count)
  298. itemDetail = turtle.getItemDetail(turtle.getSelectedSlot()+1)
  299. end
  300. ReturnHome()
  301. end
  302. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement