Files
minecraft-bot/mosfet/jobs/gather_wart.py
T

148 lines
4.8 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:
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:
print('Nether wart replanted at', self.wart)
self.state = self.cleanup
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.break_deadline = None
self.item_deadline = None
self.place_deadline = None
self.item_wait_logged = False
def run(self):
self.state()