bldng1

newlib

Aug 23rd, 2025 (edited)
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.23 KB | None | 0 0
  1. local vec3 = {}
  2. vec3.__index = vec3
  3.  
  4. -- The constructor for a new vec3 object.
  5. -- @param x The x-component (number).
  6. -- @param y The y-component (number).
  7. -- @param z The z-component (number).
  8. -- @return A new vec3 object.
  9. function vec3.new(x, y, z)
  10. -- Create a new table for the vector.
  11. local newVec = {
  12. x = x or 0,
  13. y = y or 0,
  14. z = z or 0
  15. }
  16. -- Set its metatable to the vec3 type, allowing it to
  17. -- inherit methods and use operator overloading.
  18. return setmetatable(newVec, vec3)
  19. end
  20.  
  21. -- Metamethod for the addition operator (+).
  22. -- This is called when you use the '+' operator on two vec3 objects.
  23. -- @param a The first vector.
  24. -- @param b The second vector.
  25. -- @return A new vector that is the sum of the two.
  26. function vec3.__add(a, b)
  27. return vec3.new(a.x + b.x, a.y + b.y, a.z + b.z)
  28. end
  29.  
  30. -- Metamethod for converting the vector to a string.
  31. -- This is useful for printing the vector's values.
  32. -- @param v The vector to be converted.
  33. -- @return A formatted string representation of the vector.
  34. function vec3.__tostring(v)
  35. return string.format("vec3(x:%.2f, y:%.2f, z:%.2f)", v.x, v.y, v.z)
  36. end
  37.  
  38. function vec3.serialize(v)
  39. return { typeid = "vec3", x = v.x, y = v.y, z = v.z }
  40. end
  41.  
  42. local Stack = {}
  43. Stack.__index = Stack
  44.  
  45. --[[
  46. Creates and returns a new Stack object.
  47. This is the constructor function.
  48. ]]
  49. function Stack.new()
  50. local self = {
  51. -- The internal data storage for the stack.
  52. -- We use a table to hold the elements.
  53. data = {}
  54. }
  55. -- Set up the metatable so that new instances can use the Stack methods.
  56. return setmetatable(self, Stack)
  57. end
  58.  
  59. --[[
  60. Adds an element to the top of the stack.
  61. @param self The Stack object instance.
  62. @param element The element to add to the stack.
  63. ]]
  64. function Stack:push(element)
  65. -- The # operator gets the number of elements in the table (size).
  66. -- We add the new element at the next available index.
  67. self.data[#self.data + 1] = element
  68. end
  69.  
  70. --[[
  71. Removes and returns the element at the top of the stack.
  72. Returns nil if the stack is empty.
  73. @param self The Stack object instance.
  74. @return The element that was removed, or nil.
  75. ]]
  76. function Stack:pop()
  77. if self:isEmpty() then
  78. return nil
  79. end
  80. -- Get the current top element.
  81. local topElement = self.data[#self.data]
  82. -- Remove the top element from the table.
  83. self.data[#self.data] = nil
  84. return topElement
  85. end
  86.  
  87. --[[
  88. Returns the element at the top of the stack without removing it.
  89. Returns nil if the stack is empty.
  90. @param self The Stack object instance.
  91. @return The top element, or nil.
  92. ]]
  93. function Stack:peek()
  94. if self:isEmpty() then
  95. return nil
  96. end
  97. -- Simply return the element at the top.
  98. return self.data[#self.data]
  99. end
  100.  
  101. --[[
  102. Checks if the stack is empty.
  103. @param self The Stack object instance.
  104. @return true if the stack is empty, false otherwise.
  105. ]]
  106. function Stack:isEmpty()
  107. -- The stack is empty if its size is 0.
  108. return #self.data == 0
  109. end
  110.  
  111. --[[
  112. Returns the number of elements currently in the stack.
  113. @param self The Stack object instance.
  114. @return The size of the stack.
  115. ]]
  116. function Stack:size()
  117. return #self.data
  118. end
  119.  
  120. function Stack:serialize()
  121. local data = self.data.map(function(v)
  122. if v.serialize then
  123. return v.serialize()
  124. end
  125. return v
  126. end)
  127. return { typeid = "stack", data = table.concat(data, ",") }
  128. end
  129.  
  130. --- Set.lua
  131. -- A module for creating and manipulating Set data structures in Lua.
  132. -- Sets are implemented using Lua tables, where elements are keys.
  133. -- This provides O(1) average time complexity for add, remove, and contains operations.
  134.  
  135. local Set = {}
  136. Set.__index = Set
  137.  
  138. --- Creates a new empty set.
  139. -- @return table A new set instance.
  140. function Set.new()
  141. local newSet = {}
  142. -- Use a metatable to give the set object a custom type and methods.
  143. return setmetatable(newSet, Set)
  144. end
  145.  
  146. --- Adds an element to the set.
  147. -- @param self table The set instance.
  148. -- @param element any The element to add.
  149. function Set:add(element)
  150. self[element] = true
  151. end
  152.  
  153. --- Removes an element from the set.
  154. -- @param self table The set instance.
  155. -- @param element any The element to remove.
  156. function Set:remove(element)
  157. self[element] = nil
  158. end
  159.  
  160. --- Checks if an element is in the set.
  161. -- @param self table The set instance.
  162. -- @param element any The element to check for.
  163. -- @return boolean True if the element is in the set, false otherwise.
  164. function Set:contains(element)
  165. return self[element] ~= nil
  166. end
  167.  
  168. --- Returns the number of elements in the set.
  169. -- This iterates over the table, so it's O(n) complexity.
  170. -- For simple use cases, this is fine, but for performance-critical scenarios,
  171. -- you might want to maintain a separate count variable.
  172. -- @param self table The set instance.
  173. -- @return number The number of elements.
  174. function Set:size()
  175. local count = 0
  176. for _ in pairs(self) do
  177. count = count + 1
  178. end
  179. return count
  180. end
  181.  
  182. --- Returns an iterator for the elements in the set.
  183. -- @param self table The set instance.
  184. -- @return function An iterator function.
  185. function Set:elements()
  186. local i = 0
  187. local keys = {}
  188. for k in pairs(self) do
  189. keys[#keys + 1] = k
  190. end
  191. return function()
  192. i = i + 1
  193. return keys[i]
  194. end
  195. end
  196.  
  197. --- Creates a new set that is the union of two sets.
  198. -- @param self table The first set.
  199. -- @param otherSet table The second set.
  200. -- @return table The new set containing all elements from both sets.
  201. function Set:union(otherSet)
  202. local newSet = Set.new()
  203. for k in pairs(self) do
  204. newSet:add(k)
  205. end
  206. for k in pairs(otherSet) do
  207. newSet:add(k)
  208. end
  209. return newSet
  210. end
  211.  
  212. --- Creates a new set that is the intersection of two sets.
  213. -- @param self table The first set.
  214. -- @param otherSet table The second set.
  215. -- @return table The new set containing only elements common to both sets.
  216. function Set:intersection(otherSet)
  217. local newSet = Set.new()
  218. for k in pairs(self) do
  219. if otherSet:contains(k) then
  220. newSet:add(k)
  221. end
  222. end
  223. return newSet
  224. end
  225.  
  226. --- Creates a new set that is the difference of two sets (self - otherSet).
  227. -- @param self table The first set.
  228. -- @param otherSet table The second set.
  229. -- @return table The new set containing elements in the first set but not the second.
  230. function Set:difference(otherSet)
  231. local newSet = Set.new()
  232. for k in pairs(self) do
  233. if not otherSet:contains(k) then
  234. newSet:add(k)
  235. end
  236. end
  237. return newSet
  238. end
  239.  
  240. --- Checks if this set is a subset of another set.
  241. -- @param self table The potential subset.
  242. -- @param otherSet table The potential superset.
  243. -- @return boolean True if the first set is a subset of the second, false otherwise.
  244. function Set:is_subset(otherSet)
  245. for k in pairs(self) do
  246. if not otherSet:contains(k) then
  247. return false
  248. end
  249. end
  250. return true
  251. end
  252.  
  253. function Set:serialize()
  254. local data = self.map(function(v)
  255. if v.serialize then
  256. return v.serialize()
  257. end
  258. return v
  259. end)
  260. return { typeid = "set", data = table.concat(data, ",") }
  261. end
  262.  
  263. -- MISC
  264.  
  265. function sign(x)
  266. if x > 0 then
  267. return 1
  268. elseif x < 0 then
  269. return -1
  270. else
  271. return 0
  272. end
  273. end
  274.  
  275. function table.map(f, t)
  276. local r = {}
  277. for i, v in ipairs(t) do
  278. r[i] = f(v)
  279. end
  280. return r
  281. end
  282.  
  283. -- State Saving
  284.  
  285. function Deserialize(data)
  286. if (data.typeid == "stack") then
  287. local stack = Stack.new()
  288. for i, v in ipairs(data.data:split(",")) do
  289. stack:push(Deserialize(v))
  290. end
  291. return stack
  292. elseif (data.typeid == "vec3") then
  293. return vec3.new(data.x, data.y, data.z)
  294. elseif (data.typeid == "set") then
  295. local set = Set.new()
  296. for i, v in ipairs(data.data:split(",")) do
  297. set:add(Deserialize(v))
  298. end
  299. return set
  300. end
  301. return data
  302. end
  303.  
  304. function SaveState()
  305. local r = fs.open("resume", "w")
  306. r.write(path)
  307. r.close()
  308. local f = fs.open("save", "w")
  309. f.write(textutils.serialize(STATE))
  310. f.flush()
  311. f.close()
  312. end
  313.  
  314. function LoadState()
  315. if not fs.exists("save") then
  316. return
  317. end
  318. local f = fs.open("save", "r")
  319. _G.STATE = Deserialize(textutils.unserialize(f.readAll()))
  320. f.close()
  321. resume()
  322. end
  323.  
  324. function resume()
  325. if GetReturning() then
  326. ReturnHome()
  327. end
  328. if GetVeinMining() then
  329. moveto(GetVeinInitialPos())
  330. SetVeinMining(false)
  331. end
  332. print("Resuming Operation")
  333. end
  334.  
  335. STATE = {}
  336. function UseState(key, initial)
  337. return function()
  338. if _G.STATE == nil then
  339. _G.STATE = {}
  340. end
  341. if _G.STATE[key] == nil then
  342. _G.STATE[key] = initial
  343. end
  344. return _G.STATE[key]
  345. end, function(v)
  346. _G.STATE[key] = v
  347. end
  348. end
  349.  
  350. GetPosition, SetPosition = UseState("Position", vec3.new(0, 0, 0))
  351. GetFacing, SetFacing = UseState("Facing", 0)
  352. FORWARD = 0
  353. RIGHT = 1
  354. BACK = 2
  355. LEFT = 3
  356. DOWN = 4
  357. UP = 5
  358.  
  359. function DirToString(dir)
  360. if dir == UP then
  361. return "UP"
  362. elseif dir == DOWN then
  363. return "DOWN"
  364. elseif dir == FORWARD then
  365. return "FORWARD"
  366. elseif dir == BACK then
  367. return "BACK"
  368. elseif dir == LEFT then
  369. return "LEFT"
  370. elseif dir == RIGHT then
  371. return "RIGHT"
  372. end
  373. return "UNKNOWN"
  374. end
  375.  
  376. function DirToVec(dir)
  377. if dir == UP then
  378. return vec3.new(0, 0, 1)
  379. elseif dir == DOWN then
  380. return vec3.new(0, 0, -1)
  381. elseif dir == FORWARD then
  382. return vec3.new(1, 0, 0)
  383. elseif dir == BACK then
  384. return vec3.new(-1, 0, 0)
  385. elseif dir == LEFT then
  386. return vec3.new(0, -1, 0)
  387. elseif dir == RIGHT then
  388. return vec3.new(0, 1, 0)
  389. end
  390. end
  391.  
  392. function VecToDir(vec)
  393. if vec.x > 0 and vec.y == 0 and vec.z == 0 then
  394. return FORWARD;
  395. end
  396. if vec.x < 0 and vec.y == 0 and vec.z == 0 then
  397. return BACK;
  398. end
  399. if vec.x == 0 and vec.y < 0 and vec.z == 0 then
  400. return LEFT;
  401. end
  402. if vec.x == 0 and vec.y > 0 and vec.z == 0 then
  403. return RIGHT;
  404. end
  405. return GetFacing()
  406. end
  407.  
  408. function getMoveDir(mx, my)
  409. return VecToDir(vec3.new(mx, my, 0))
  410. end
  411.  
  412. function rotate(dir)
  413. if dir == UP or dir == DOWN then
  414. return
  415. end
  416. while not (dir == GetFacing()) do
  417. if dir < GetFacing() then
  418. turtle.turnLeft()
  419. SetFacing(GetFacing() - 1)
  420. else
  421. turtle.turnRight()
  422. SetFacing(GetFacing() + 1)
  423. end
  424. end
  425. end
  426.  
  427. function move(mx, my, mz, destructive)
  428. destructive = destructive or true
  429. print("Moving " .. mx .. ", " .. my .. ", " .. mz)
  430. function mv(z)
  431. function step()
  432. if z == "UP" then
  433. return turtle.up()
  434. elseif z == "DOWN" then
  435. return turtle.down()
  436. elseif z == "FORWARD" then
  437. return turtle.forward()
  438. end
  439. end
  440. function dig()
  441. if z == "UP" then
  442. turtle.digUp()
  443. turtle.attackUp()
  444. elseif z == "DOWN" then
  445. turtle.digDown()
  446. turtle.attackDown()
  447. elseif z == "FORWARD" then
  448. turtle.dig()
  449. turtle.attack()
  450. end
  451. end
  452.  
  453. while not step() do
  454. if destructive then
  455. dig()
  456. end
  457. sleep(0.1)
  458. end
  459. checkReturn()
  460. checkInv()
  461. if not GetReturning() then
  462. checkForWorth(GetFacing())
  463. checkForWorth(UP)
  464. checkForWorth(DOWN)
  465. end
  466. end
  467.  
  468. if not (mx == 0) then
  469. rotate(getMoveDir(mx, 0))
  470. local dist = math.abs(mx);
  471. while not (dist == 0) do
  472. dist = dist - 1;
  473. mv("FORWARD")
  474. SetPosition(GetPosition() + vec3.new(sign(mx), 0, 0))
  475. end
  476. end
  477. if not (my == 0) then
  478. rotate(getMoveDir(0, my))
  479. local dist = math.abs(my);
  480. while not (dist == 0) do
  481. dist = dist - 1;
  482. mv("FORWARD")
  483. SetPosition(GetPosition() + vec3.new(0, sign(my), 0))
  484. end
  485. end
  486. if not (mz == 0) then
  487. rotate(getMoveDir(0, 0))
  488. local dist = math.abs(mz);
  489. while not (dist == 0) do
  490. if mz < 0 then
  491. mv("DOWN")
  492. else
  493. mv("UP")
  494. end
  495. dist = dist - 1;
  496. SetPosition(GetPosition() + vec3.new(0, 0, sign(mz)))
  497. end
  498. end
  499. end
  500.  
  501. function moveto(vec)
  502. print("Moveto")
  503. local pos = GetPosition()
  504. print("Moveto pos")
  505. move(vec.x - pos.x, vec.y - pos.y, vec.z - pos.z)
  506. end
  507.  
  508. function place(dir)
  509. if dir == UP then
  510. return turtle.placeUp()
  511. elseif dir == DOWN then
  512. return turtle.placeDown()
  513. else
  514. rotate(dir)
  515. return turtle.place()
  516. end
  517. end
  518.  
  519. function dig(dir)
  520. if dir == UP then
  521. return turtle.digUp()
  522. elseif dir == DOWN then
  523. return turtle.digDown()
  524. else
  525. rotate(dir)
  526. return turtle.dig()
  527. end
  528. end
  529.  
  530. GetReturning, SetReturning = UseState("Returning", false)
  531.  
  532. function getFuel()
  533. if turtleNeedFuel == 0 then
  534. return 99999
  535. end
  536. local fuel = turtle.getFuelLevel()
  537. if fuel < turtle.getFuelLimit() then
  538. turtle.refuel(1)
  539. end
  540. return fuel
  541. end
  542.  
  543. function hasEnoughFuel()
  544. local pos = GetPosition()
  545. local fuel = getFuel()
  546. local dist = (pos.x + pos.y + pos.z) + 100
  547. if dist > fuel then
  548. return false
  549. end
  550. return true
  551. end
  552.  
  553. function checkReturn()
  554. if not hasEnoughFuel() then
  555. print("Not enough fuel Returning")
  556. ReturnHome()
  557. exit()
  558. end
  559. end
  560.  
  561. function ReturnHome()
  562. SetReturning(true)
  563. moveto(vec3.new(0, 0, 0))
  564. end
  565.  
  566. GetVeinMining, SetVeinMining = UseState("VeinMining", false)
  567. GetVeinInitialPos, SetVeinInitialPos = UseState("VeinInitialPos", vec3.new(0, 0, 0))
  568. Worth = Set.new()
  569. Junk = Set.new()
  570.  
  571. function inspect(dir)
  572. if dir == UP then
  573. local has, block = turtle.inspectUp()
  574. if not has then
  575. return nil
  576. end
  577. return block
  578. elseif dir == DOWN then
  579. local has, block = turtle.inspectDown()
  580. if not has then
  581. return nil
  582. end
  583. return block
  584. else
  585. rotate(dir)
  586. local has, block = turtle.inspect()
  587. if not has then
  588. return nil
  589. end
  590. return block
  591. end
  592. end
  593.  
  594. function checkBlockWorth(block, tocheck)
  595. tocheck = tocheck or Worth
  596. if block == nil then
  597. return false
  598. end
  599. for v in tocheck:elements() do
  600. if string.find(block["name"], v) then
  601. return true
  602. end
  603. end
  604. return false
  605. end
  606.  
  607. function isChest(block)
  608. if block == nil then
  609. return false
  610. end
  611. if block["name"] == nil then
  612. print("DEBUG BLOCK")
  613. print(block)
  614. return false
  615. end
  616. return string.find(block["name"], "chest")
  617. end
  618.  
  619. function checkForWorth(dir)
  620. local block = inspect(dir)
  621. if block == nil then
  622. print(DirToString(dir) .. " is nil")
  623. return
  624. end
  625. print(DirToString(dir) .. " is " .. block["name"])
  626. if isChest(block) then
  627. lootChest(dir)
  628. return
  629. end
  630. if block == "lava" and block.state.level == 0 then
  631. if selectItem("bucket") then
  632. place(dir)
  633. turtle.refuel(1)
  634. end
  635. return
  636. end
  637. if checkBlockWorth(block) then
  638. veinmine(dir, Worth)
  639. end
  640. end
  641.  
  642. local alldirs = {
  643. vec3.new(0, 0, -1),
  644. vec3.new(0, 0, 1),
  645. vec3.new(0, -1, 0),
  646. vec3.new(0, 1, 0),
  647. vec3.new(-1, 0, 0),
  648. vec3.new(1, 0, 0)
  649. }
  650.  
  651. function veinmine(dir, tomine)
  652. local initpos = GetPosition()
  653. SetVeinInitialPos(initpos)
  654. SetVeinMining(true)
  655. print("Starting Veinmine")
  656. local stack = Stack.new()
  657. local checked = Set.new()
  658. print("Pushing initial position")
  659. stack:push(DirToVec(dir) + initpos)
  660. print("Pushed initial position")
  661. while not stack:isEmpty() do
  662. local vec = stack:pop()
  663. print("Moving to " .. vec.x .. ", " .. vec.y .. ", " .. vec.z)
  664. moveto(vec)
  665. for i, v in ipairs(alldirs) do
  666. local dir = VecToDir(v)
  667. local pos = GetPosition() + v
  668. if not checked:contains(pos) then
  669. checked:add(pos)
  670. print("Checking " .. pos.x .. ", " .. pos.y .. ", " .. pos.z)
  671. if checkBlockWorth(inspect(dir), tomine) then
  672. stack:push(vec + v)
  673. end
  674. end
  675. end
  676. end
  677. moveto(GetVeinInitialPos())
  678. SetVeinMining(false)
  679. end
  680.  
  681. -- Inventory
  682. clearfrom = 2
  683.  
  684. function lootChest(dir)
  685. if dir == UP then
  686. while turtle.suckUp() do end
  687. elseif dir == DOWN then
  688. while turtle.suckDown() do end
  689. else
  690. rotate(dir)
  691. while turtle.suck() do end
  692. end
  693. end
  694.  
  695. function deposit(dir)
  696. local block = inspect(dir)
  697. if not isChest(block) then
  698. return false
  699. end
  700. for i = clearfrom, 16 do
  701. turtle.select(i)
  702. while turtle.drop() == false and turtle.getItemCount() ~= 0 do -- Waits until turtle can deposit item
  703. sleep(0.1)
  704. end
  705. turtle.drop()
  706. end
  707. turtle.select(1)
  708. return true
  709. end
  710.  
  711. function isInvFull()
  712. local full = true
  713. for i = clearfrom, 16 do
  714. local count = turtle.getItemCount(i)
  715. if count == 0 then
  716. full = false
  717. end
  718. end
  719. return full
  720. end
  721.  
  722. function clearInv()
  723. for i = clearfrom, 16 do
  724. while turtle.getItemCount(i) > 0 do
  725. turtle.select(i)
  726. local item = turtle.getItemDetail(i)
  727.  
  728. for junk in Junk:elements() do
  729. if string.find(item["name"], junk) then
  730. turtle.select(i)
  731. turtle.drop()
  732. end
  733. end
  734. end
  735. end
  736. if isInvFull() then
  737. print("Going back to clear inventory")
  738. ReturnHome()
  739. for _, dir in pairs({ UP, DOWN, FORWARD, BACK, LEFT, RIGHT }) do
  740. local block = inspect(dir)
  741. if isChest(block) then
  742. deposit(dir)
  743. end
  744. end
  745. end
  746. if isInvFull() then
  747. print("Inventory is full")
  748. exit()
  749. end
  750. end
  751.  
  752. function checkInv()
  753. if not isInvFull() then
  754. return
  755. end
  756. print("Inventory is full")
  757. clearInv()
  758. end
  759.  
  760. function selectItem(name)
  761. for i = 1, 16 do
  762. if turtle.getItemCount(i) > 0 then
  763. if string.find(turtle.getItemDetail(i)["name"], name) then
  764. turtle.select(i)
  765. return true
  766. end
  767. end
  768. end
  769. return false
  770. end
  771.  
  772. print("Library Loaded")
  773. print("Loading State")
  774. LoadState()
  775. print("State Loaded")
  776.  
Advertisement
Add Comment
Please, Sign In to add comment