SHOW:
|
|
- or go back to the newest paste.
1 | - | local ms = require("movescript") |
1 | + | -- pastebin get -f REyTTip0 planter.lua |
2 | - | local robot = require("robot") |
2 | + | |
3 | - | local component = require("component") |
3 | + | local ms = require("movescript") |
4 | - | local ic = component.inventory_controller |
4 | + | local robot = require("robot") |
5 | - | |
5 | + | local component = require("component") |
6 | - | local function equipItemOrWait(name) |
6 | + | local sides = require("sides") |
7 | - | repeat |
7 | + | local ic = component.inventory_controller |
8 | - | local success = ms.selectItem(name) |
8 | + | local geolyzer = component.geolyzer |
9 | - | if not success then |
9 | + | |
10 | - | print("Please add more " .. name .. ", then press enter.") |
10 | + | -- The list of names of all blocks that crops may be planted on. |
11 | - | io.read() |
11 | + | local PLANTABLE_BLOCKS = { |
12 | - | end |
12 | + | "minecraft:dirt", |
13 | - | until success |
13 | + | "minecraft:grass", |
14 | - | ic.equip() |
14 | + | "biomesoplenty:dirt", |
15 | - | end |
15 | + | "biomesoplenty:grass" |
16 | - | |
16 | + | } |
17 | - | local function goToNextSpot() |
17 | + | |
18 | - | equipItemOrWait("pickaxe") |
18 | + | local PICKAXE_NAME = "pickaxe" |
19 | - | while robot.detect() do |
19 | + | local HOE_NAME = "mattock" |
20 | - | ms.exec("d_U") |
20 | + | |
21 | - | end |
21 | + | local DISPLACEMENT = -1 -- Displacement == 0 means we're on the first row of the field. |
22 | - | ms.exec("F") |
22 | + | |
23 | - | while not robot.detectDown() do |
23 | + | local function equipNothing() |
24 | - | ms.exec("d_D") |
24 | + | for i = 1, robot.inventorySize() do |
25 | - | end |
25 | + | if robot.count(i) == 0 then |
26 | - | ms.exec("d_U") |
26 | + | robot.select(i) |
27 | - | end |
27 | + | ic.equip() |
28 | - | |
28 | + | return true |
29 | - | local function plantSpot(cropName) |
29 | + | end |
30 | - | repeat |
30 | + | end |
31 | - | equipItemOrWait("hoe") |
31 | + | return false |
32 | - | robot.useDown() |
32 | + | end |
33 | - | equipItemOrWait(cropName) |
33 | + | |
34 | - | local success = robot.useDown() |
34 | + | local function dropAllExcept(names) |
35 | - | until success |
35 | + | for i = 1, robot.inventorySize() do |
36 | - | end |
36 | + | local stack = ic.getStackInInternalSlot(i) |
37 | - | |
37 | + | if stack ~= nil then |
38 | - | local function plantArea(length, width, cropName) |
38 | + | local shouldDrop = true |
39 | - | goToNextSpot() |
39 | + | for _, acceptableName in ipairs(names) do |
40 | - | plantSpot(cropName) |
40 | + | if string.find(stack.name, acceptableName) then |
41 | - | ms.exec("R") |
41 | + | shouldDrop = false |
42 | - | for row = 1, length do |
42 | + | end |
43 | - | for col = 1, width - 1 do |
43 | + | end |
44 | - | goToNextSpot() |
44 | + | if shouldDrop then |
45 | - | plantSpot(cropName) |
45 | + | robot.select(i) |
46 | - | end |
46 | + | robot.dropDown() |
47 | - | if row % 2 == 1 then |
47 | + | end |
48 | - | ms.exec("L") |
48 | + | end |
49 | - | else |
49 | + | end |
50 | - | ms.exec("R") |
50 | + | end |
51 | - | end |
51 | + | |
52 | - | if row ~= length then |
52 | + | local function equipItemOrWait(name, cropName) |
53 | - | goToNextSpot() |
53 | + | -- First, ensure that nothing is equipped. |
54 | - | plantSpot(cropName) |
54 | + | repeat |
55 | - | end |
55 | + | local success = equipNothing() |
56 | - | if row % 2 == 1 then |
56 | + | if not success then |
57 | - | ms.exec("L") |
57 | + | dropAllExcept({PICKAXE_NAME, HOE_NAME, cropName}) |
58 | - | else |
58 | + | end |
59 | - | ms.exec("R") |
59 | + | until success |
60 | - | end |
60 | + | -- Then try and select the item until we succeed. |
61 | - | print("Completed row " .. row .. " of " .. length) |
61 | + | repeat |
62 | - | end |
62 | + | local success = ms.selectItem(name) |
63 | - | end |
63 | + | if not success then |
64 | - | |
64 | + | print("Please add more " .. name .. ", then press enter.") |
65 | - | |
65 | + | io.read() |
66 | - | local args = {...} |
66 | + | end |
67 | - | |
67 | + | until success |
68 | - | local length = tonumber(args[1]) |
68 | + | ic.equip() |
69 | - | local width = tonumber(args[2]) |
69 | + | end |
70 | - | local cropName = args[3] |
70 | + | |
71 | - | if not length or not width or not cropName then |
71 | + | local function ensureEnoughEnergy() |
72 | - | error("Invalid args.") |
72 | + | if ms.getEnergyRatio() < 0.05 then |
73 | - | end |
73 | + | while ms.getEnergyRatio() < 0.5 do |
74 | - | print("Planting an area " .. length .. " by " .. width .. " with " .. cropName .. ".") |
74 | + | print("Energy low! Sleeping for a while.") |
75 | os.sleep(60) | |
76 | end | |
77 | end | |
78 | end | |
79 | ||
80 | -- Moves from the current position to the next planting spot (just above grass). | |
81 | -- Returns false if no spot could be found. | |
82 | local function goToNextSpot(cropName) | |
83 | ensureEnoughEnergy() | |
84 | equipItemOrWait(PICKAXE_NAME, cropName) | |
85 | -- Go up to try and get around an obstacle, or give up if we can't. | |
86 | while robot.detect() do | |
87 | if not robot.up() then return false end | |
88 | end | |
89 | ms.exec("F") | |
90 | DISPLACEMENT = DISPLACEMENT + 1 | |
91 | local grassFound = false | |
92 | while true do | |
93 | local blocking, desc = robot.detectDown() | |
94 | -- If we hit a liquid, quit right away. | |
95 | if not blocking and desc == "liquid" then return false end | |
96 | if blocking then -- There is something blocking the robot's path. | |
97 | -- If the block below us is something passable or an entity, keep swinging until it's gone. | |
98 | if desc == "passable" or desc == "entity" then | |
99 | repeat | |
100 | ms.exec("Sd") | |
101 | until not robot.detectDown() | |
102 | end | |
103 | if desc == "solid" then | |
104 | local blockData = geolyzer.analyze(sides.bottom) | |
105 | -- If for some reason we can't analyze the block, quit. | |
106 | if blockData == nil then return false end | |
107 | for _, plantableBlockName in ipairs(PLANTABLE_BLOCKS) do | |
108 | if blockData.name == plantableBlockName then | |
109 | ms.exec("U") | |
110 | return true | |
111 | end | |
112 | end | |
113 | -- If we reached a solid block that's not plantable, quit and return false. | |
114 | if not grassFound then return false end | |
115 | end | |
116 | else -- The robot is free to move down. | |
117 | ms.exec("D") | |
118 | end | |
119 | end | |
120 | end | |
121 | ||
122 | local function plantSpot(cropName) | |
123 | repeat | |
124 | equipItemOrWait(HOE_NAME, cropName) | |
125 | robot.useDown() | |
126 | equipItemOrWait(cropName, cropName) | |
127 | local success = robot.useDown() | |
128 | until success | |
129 | end | |
130 | ||
131 | local function plantUnboundedLength(width, cropName) | |
132 | for col = 1, width do | |
133 | -- Go as far as possible in this column. | |
134 | repeat | |
135 | local success = goToNextSpot(cropName) | |
136 | if success then | |
137 | plantSpot(cropName) | |
138 | end | |
139 | until not success | |
140 | -- We've reached the end. Go all the way back, then go into the next column. | |
141 | ms.exec("RR") | |
142 | while DISPLACEMENT ~= 0 do | |
143 | while not robot.detectDown() do | |
144 | ms.exec("D") | |
145 | end | |
146 | while robot.detect() do | |
147 | ms.exec("U") | |
148 | end | |
149 | ms.exec("F") | |
150 | DISPLACEMENT = DISPLACEMENT - 1 | |
151 | end | |
152 | ms.exec("L") | |
153 | print("Completed column " .. col .. " of " .. width) | |
154 | if col ~= width then | |
155 | goToNextSpot(cropName) | |
156 | plantSpot(cropName) | |
157 | DISPLACEMENT = 0 -- Reset our global displacement tracker before going on the next run. | |
158 | end | |
159 | ms.exec("L") | |
160 | end | |
161 | end | |
162 | ||
163 | local function plantArea(length, width, cropName) | |
164 | goToNextSpot(cropName) | |
165 | plantSpot(cropName) | |
166 | ms.exec("R") | |
167 | for row = 1, length do | |
168 | for col = 1, width - 1 do | |
169 | goToNextSpot(cropName) | |
170 | plantSpot(cropName) | |
171 | end | |
172 | if row % 2 == 1 then | |
173 | ms.exec("L") | |
174 | else | |
175 | ms.exec("R") | |
176 | end | |
177 | if row ~= length then | |
178 | goToNextSpot(cropName) | |
179 | plantSpot(cropName) | |
180 | end | |
181 | if row % 2 == 1 then | |
182 | ms.exec("L") | |
183 | else | |
184 | ms.exec("R") | |
185 | end | |
186 | print("Completed row " .. row .. " of " .. length) | |
187 | end | |
188 | end | |
189 | ||
190 | ||
191 | if ic == nil then error("Missing inventory controller component.") end | |
192 | if geolyzer == nil then error("Missing geolyzer component.") end | |
193 | ||
194 | local arg = {...} | |
195 | ||
196 | local length = tonumber(arg[1]) | |
197 | local width = tonumber(arg[2]) | |
198 | local cropName = arg[3] | |
199 | if not length or not width or not cropName then | |
200 | error("Invalid args.") | |
201 | end | |
202 | ||
203 | if length < 0 and width > 0 then | |
204 | print("Planting area " .. width .. " blocks wide, with unbounded length, with " .. cropName) | |
205 | plantUnboundedLength(width, cropName) | |
206 | return | |
207 | end | |
208 | ||
209 | print("Planting an area " .. length .. " by " .. width .. " with " .. cropName .. ".") | |
210 | plantArea(length, width, cropName) |