local Direction = require("lib.direction") local TurtleController = require("controller.turtle_controller") ---@alias VolumeExcavationControllerConfig {mine_forward: number, mine_left: number, mine_right: number} ---@class VolumeExcavationController ---@field controller TurtleController ---@field config VolumeExcavationControllerConfig local VolumeExcavationController = {} VolumeExcavationController.__index = VolumeExcavationController ---@return VolumeExcavationController function VolumeExcavationController:Create() local t = {} setmetatable(t, VolumeExcavationController) ----------------------------------------------------------------------------------------------- -- Fields ----------------------------------------------------------------------------------------------- t.controller = TurtleController:Create() t.config = { mine_forward = 0, mine_left = 0, mine_right = 0, } return t end ----------------------------------------------------------------------------------------------- -- Behavior Methods ----------------------------------------------------------------------------------------------- function VolumeExcavationController:Excavate() print(("Turtle is mining layer at y=%d..."):format(self.controller.position.y)) -- Enter the excavation area self.controller:EnableMining() self.controller:MoveRelative(1) -- Move to the bottom right corner of the layer self.controller:TurnToDirection(Direction.EAST) self.controller:MoveRelative(self.config.mine_right) self.controller:TurnToDirection(Direction.WEST) -- Zig zag mine the full width from back to front -- The direction is important so we can travel to start without colliding with unminded walls local turn_dir = 1 for i = 1,self.config.mine_forward do self.controller:MoveRelative(self.config.mine_left + self.config.mine_right) -- Skip the last turn, as we won't mine that slice -- We want to stay in the mined area so we can move back freely if i == self.config.mine_forward then break end -- Skip the turning if we're mining in a straight line if self.config.mine_left + self.config.mine_right > 0 then self.controller:TurnRelative(turn_dir) self.controller:MoveRelative(1) self.controller:TurnRelative(turn_dir) end turn_dir = -1 * turn_dir end self.controller:MoveToPosition(0, 0, 0, Direction.NORTH) -- Unload before doing the next layer self.controller:TurnToDirection(self.controller.config.storage_direction) self.controller:DropInventory() self.controller:TurnToDirection(Direction.NORTH) end ----------------------------------------------------------------------------------------------- -- Management Methods ----------------------------------------------------------------------------------------------- function VolumeExcavationController:Configure() local config_complete = false while not config_complete do print("How many blocks should the turtle mine forward?") self.config.mine_forward = tonumber(io.read()) or 3 print("How many blocks should the turtle to its right?") self.config.mine_right = tonumber(io.read()) or 3 print("How many blocks should the turtle mine to its left?") self.config.mine_left = tonumber(io.read()) or 3 local width = self.config.mine_left + self.config.mine_right + 1 local height = 3 print("Configuration complete!") print(("Turtle will mine an area of %d x %d x %d (forward x width x height) totalling %d blocks."):format( self.config.mine_forward, width, height, self.config.mine_forward * width * height )) print("Do you want to accept the configuration (enter 1, otherwise 0)?") config_complete = tonumber(io.read()) == 1 end end ----------------------------------------------------------------------------------------------- -- Main Method ----------------------------------------------------------------------------------------------- function VolumeExcavationController:Run() self.controller:Configure() self:Configure() -- Consume our starting fuel and refuel to the full amount turtle.select(1) turtle.refuel() self.controller:RefuelIfEmpty() self:Excavate() end return VolumeExcavationController