View difference between Paste ID: REyTTip0 and jp5s2D5d
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)