157 lines
5.1 KiB
Python
157 lines
5.1 KiB
Python
import time
|
|
|
|
from minecraft.networking.types import BlockFace
|
|
|
|
from mosfet import path
|
|
from mosfet import utils
|
|
from mosfet.info import blocks
|
|
from mosfet.info import items
|
|
|
|
|
|
class GatherWartStates:
|
|
WARTS_PER_BATCH = 16
|
|
BREAK_TIMEOUT = 5.0
|
|
ITEM_TIMEOUT = 8.0
|
|
PLACE_TIMEOUT = 3.0
|
|
|
|
def idle(self):
|
|
return None
|
|
|
|
def init(self):
|
|
self.state = self.find_new_wart
|
|
|
|
def _blacklist_wart(self):
|
|
if self.wart is not None and self.wart not in self.bad_warts:
|
|
self.bad_warts.append(self.wart)
|
|
|
|
def find_new_wart(self):
|
|
print('Finding new wart...')
|
|
world = self.g.world
|
|
center = utils.pint(self.g.pos)
|
|
mature_wart = max(blocks.NETHERWART_IDS)
|
|
candidates = world.find_blocks_indexed(
|
|
center, {mature_wart}, 50)
|
|
candidates = world.filter_work_positions(candidates)
|
|
wart = next((position for position in candidates
|
|
if position not in self.bad_warts), None)
|
|
if wart is None:
|
|
print('No good warts left, aborting.')
|
|
self.state = self.cleanup
|
|
return
|
|
|
|
print('Found wart:', wart)
|
|
self.wart = wart
|
|
self.type_id = mature_wart
|
|
self.state = self.nav_to_wart
|
|
|
|
def nav_to_wart(self):
|
|
world = self.g.world
|
|
position = utils.pint(self.g.pos)
|
|
navpath = world.path_to_place(position, self.wart)
|
|
|
|
if navpath:
|
|
print('Going to wart', self.wart)
|
|
self.g.path = navpath
|
|
self.g.look_at = self.wart
|
|
self.state = self.going_to_wart
|
|
else:
|
|
print('Cant get to it, blacklisting')
|
|
self._blacklist_wart()
|
|
self.state = self.find_new_wart
|
|
|
|
def going_to_wart(self):
|
|
if utils.pint(self.g.pos) == self.wart:
|
|
print('At the wart')
|
|
self.state = self.break_wart
|
|
|
|
def break_wart(self):
|
|
current = self.g.world.block_at(*self.wart)
|
|
if current != self.type_id:
|
|
print('Wart changed before break; searching again')
|
|
self._blacklist_wart()
|
|
self.state = self.find_new_wart
|
|
return
|
|
|
|
if self.g.game.break_block(self.wart):
|
|
self.break_deadline = time.monotonic() + self.BREAK_TIMEOUT
|
|
self.state = self.wait_break
|
|
else:
|
|
print('Break request skipped; blacklisting', self.wart)
|
|
self._blacklist_wart()
|
|
self.state = self.find_new_wart
|
|
|
|
def wait_break(self):
|
|
current = self.g.world.block_at(*self.wart)
|
|
if current != self.type_id:
|
|
print('Wart break confirmed at {}: {} -> {}'.format(
|
|
self.wart, self.type_id, current))
|
|
self.item_deadline = time.monotonic() + self.ITEM_TIMEOUT
|
|
self.item_wait_logged = False
|
|
self.state = self.select_wart
|
|
elif time.monotonic() > self.break_deadline:
|
|
print('Wart did not break; blacklisting', self.wart)
|
|
self._blacklist_wart()
|
|
self.state = self.find_new_wart
|
|
|
|
def select_wart(self):
|
|
if self.g.game.select_item([items.NETHERWART_ID]):
|
|
self.state = self.wait_select
|
|
return
|
|
|
|
if time.monotonic() > self.item_deadline:
|
|
print('No nether wart collected; skipping', self.wart)
|
|
self._blacklist_wart()
|
|
self.state = self.find_new_wart
|
|
elif not self.item_wait_logged:
|
|
print('Waiting for nether wart in inventory/hotbar')
|
|
self.item_wait_logged = True
|
|
|
|
def wait_select(self):
|
|
if self.g.get('holding') == items.NETHERWART_ID:
|
|
self.state = self.place_wart
|
|
|
|
def place_wart(self):
|
|
soul_sand = utils.padd(self.wart, path.BLOCK_BELOW)
|
|
self.g.game.place_block(soul_sand, BlockFace.TOP)
|
|
self.place_deadline = time.monotonic() + self.PLACE_TIMEOUT
|
|
self.state = self.wait_place
|
|
|
|
def wait_place(self):
|
|
current = self.g.world.block_at(*self.wart)
|
|
if current in blocks.NETHERWART_IDS and current != self.type_id:
|
|
self.completed_warts += 1
|
|
print('Nether wart replanted at', self.wart)
|
|
if self.completed_warts >= self.WARTS_PER_BATCH:
|
|
print('Completed {} nether wart harvests; running maintenance'.format(
|
|
self.completed_warts))
|
|
self.completed_warts = 0
|
|
self.state = self.cleanup
|
|
else:
|
|
self.state = self.find_new_wart
|
|
elif time.monotonic() > self.place_deadline:
|
|
print('Nether wart did not replant; blacklisting', self.wart)
|
|
self._blacklist_wart()
|
|
self.state = self.find_new_wart
|
|
|
|
def cleanup(self):
|
|
self.g.look_at = None
|
|
self.state = self.done
|
|
|
|
def done(self):
|
|
return None
|
|
|
|
def __init__(self, global_state):
|
|
self.g = global_state
|
|
self.state = self.idle
|
|
self.wart = None
|
|
self.type_id = None
|
|
self.bad_warts = []
|
|
self.completed_warts = 0
|
|
self.break_deadline = None
|
|
self.item_deadline = None
|
|
self.place_deadline = None
|
|
self.item_wait_logged = False
|
|
|
|
def run(self):
|
|
self.state()
|