234 lines
6.7 KiB
Python
234 lines
6.7 KiB
Python
import re
|
|
import time
|
|
import importlib
|
|
import random
|
|
from itertools import count
|
|
from math import floor
|
|
|
|
from minecraft.networking.types import BlockFace
|
|
|
|
from mosfet.protocol.managers import ChunkNotLoadedException
|
|
|
|
from mosfet import utils
|
|
from mosfet import path
|
|
from mosfet.info import blocks
|
|
from mosfet.info import items
|
|
from mosfet.info import mcdata
|
|
from mosfet.info import mobs
|
|
|
|
class GrabSuppliesStates:
|
|
def idle(self):
|
|
return None
|
|
|
|
def init(self):
|
|
print('Started grab supplies states')
|
|
self.checked_barrels = []
|
|
|
|
used_slots = self.g.game.count_inventory_slots()
|
|
print('used:', used_slots, 'total:', self.g.maximum_supply_slots)
|
|
if used_slots >= self.g.maximum_supply_slots:
|
|
print('Inventory is too full, aborting')
|
|
self.state = self.cleanup
|
|
return
|
|
|
|
if self.supplies:
|
|
self.state = self.check_supplies
|
|
else:
|
|
print('Aborting getting supplies, none specified')
|
|
self.state = self.cleanup
|
|
|
|
def check_supplies(self):
|
|
# check if we need to grab anything
|
|
for items, limits in self.supplies.items():
|
|
minimum, maximum = limits
|
|
print('Checking items:', items)
|
|
num_items = self.g.game.count_items(items)
|
|
print('Have:', num_items)
|
|
|
|
if num_items >= minimum:
|
|
print('Have enough, skipping')
|
|
continue
|
|
|
|
print('Need at least one item')
|
|
self.state = self.find_barrels
|
|
return
|
|
|
|
print('Aborting, dont need any supplies')
|
|
self.state = self.cleanup
|
|
|
|
def find_barrels(self):
|
|
print('Finding barrels...')
|
|
w = self.g.world
|
|
p = utils.pint(self.g.pos)
|
|
|
|
self.barrels = w.find_blocks_indexed(p, blocks.BARREL_IDS, 80)
|
|
print('Found:', self.barrels)
|
|
self.state = self.choose_barrel
|
|
|
|
def choose_barrel(self):
|
|
print('Choosing a barrel...')
|
|
for barrel in self.barrels:
|
|
if barrel in self.checked_barrels:
|
|
continue
|
|
if barrel in self.bad_barrels:
|
|
continue
|
|
|
|
print('Chose:', barrel)
|
|
self.barrel = barrel
|
|
self.state = self.path_to_barrel
|
|
return
|
|
|
|
print('No barrels')
|
|
self.state = self.cleanup
|
|
|
|
def path_to_barrel(self):
|
|
print('Finding path to barrel')
|
|
w = self.g.world
|
|
p = utils.pint(self.g.pos)
|
|
c = self.g.chunks
|
|
|
|
navpath = w.path_to_place_faked(p, self.barrel)
|
|
print('navpath:', navpath)
|
|
|
|
if navpath:
|
|
self.g.path = navpath[:-1]
|
|
self.opening = self.g.path[-1]
|
|
self.checked_barrels.append(self.barrel)
|
|
self.area = self.barrel
|
|
self.state = self.going_to_barrel
|
|
self.checked_supplies = []
|
|
return
|
|
else:
|
|
print('No path, blacklisting barrel')
|
|
time.sleep(0.1)
|
|
self.bad_barrels.append(self.barrel)
|
|
self.state = self.choose_barrel
|
|
|
|
def going_to_barrel(self):
|
|
if utils.pint(self.g.pos) == self.opening:
|
|
self.g.look_at = self.area
|
|
self.state = self.open_barrel
|
|
|
|
def open_barrel(self):
|
|
print('Opening barrel')
|
|
self.g.game.open_container(self.area)
|
|
self.wait_time = 1
|
|
self.state = self.wait
|
|
|
|
def wait(self):
|
|
# wait for server to send us inventory contents
|
|
if self.wait_time > 0:
|
|
self.wait_time -= utils.TICK
|
|
else:
|
|
self.state = self.choose_items
|
|
|
|
def choose_items(self):
|
|
print('Selecting next item')
|
|
for items, limits in self.supplies.items():
|
|
minimum_items, maximum_stacks = limits
|
|
print('Checking items:', items)
|
|
num_items = self.g.game.count_items(items)
|
|
print('Have:', num_items)
|
|
|
|
if num_items >= minimum_items:
|
|
print('Have enough, skipping')
|
|
continue
|
|
|
|
if items in self.checked_supplies:
|
|
print('Already checked, skipping')
|
|
continue
|
|
|
|
print('Need some')
|
|
self.checked_supplies.append(items)
|
|
self.target_items = items
|
|
self.maximum_stacks = maximum_stacks
|
|
self.count = 0
|
|
self.state = self.grab_items
|
|
return
|
|
|
|
print('Aborting, dont need any more supplies')
|
|
self.state = self.close_barrel
|
|
|
|
def grab_items(self):
|
|
if self.g.item_lock: return
|
|
w = self.g.window
|
|
|
|
if not w:
|
|
print('Didnt get a window, aborting')
|
|
self.state = self.cleanup
|
|
return
|
|
if w.data.window_type != mcdata.SINGLE_CHEST:
|
|
print('Got wrong window, aborting')
|
|
self.state = self.cleanup
|
|
return
|
|
used_slots = self.g.game.count_inventory_slots()
|
|
print('used:', used_slots, 'total:', self.g.maximum_supply_slots)
|
|
if used_slots >= self.g.maximum_supply_slots:
|
|
print('Inventory is too full, aborting')
|
|
self.g.game.close_window()
|
|
self.g.look_at = None
|
|
self.state = self.cleanup
|
|
return
|
|
|
|
w_info = mcdata.WINDOWS[w.data.window_type]
|
|
w_container_slots = w_info.container
|
|
|
|
for slot_num in w_container_slots:
|
|
if slot_num not in w.contents:
|
|
continue
|
|
|
|
slot = w.contents[slot_num]
|
|
|
|
if not slot.present:
|
|
continue
|
|
|
|
if slot.item_id not in self.target_items:
|
|
continue
|
|
|
|
if self.maximum_stacks and self.count >= self.maximum_stacks:
|
|
break
|
|
self.count += 1
|
|
|
|
print('Moving', slot)
|
|
|
|
self.g.item_lock = True
|
|
self.g.game.click_window(slot_num, 0, 1, slot)
|
|
return
|
|
|
|
print('None left to move')
|
|
self.wait_time = 0.25
|
|
self.state = self.wait
|
|
|
|
def close_barrel(self):
|
|
print('Closing barrel')
|
|
self.g.game.close_window()
|
|
self.g.look_at = None
|
|
self.state = self.choose_barrel
|
|
|
|
def cleanup(self):
|
|
self.state = self.done
|
|
|
|
def done(self):
|
|
# never gets ran, placeholder
|
|
return None
|
|
|
|
def __init__(self, global_state):
|
|
self.g = global_state
|
|
self.state = self.idle
|
|
|
|
self.supplies = {}
|
|
self.barrels = []
|
|
self.checked_barrels = []
|
|
self.bad_barrels = []
|
|
self.barrel = None
|
|
self.checked_supplies = []
|
|
self.target_items = None
|
|
self.maximum_stacks = 0
|
|
self.count = 0
|
|
self.area = None
|
|
self.opening = None
|
|
self.wait_time = 0
|
|
|
|
def run(self):
|
|
self.state()
|