You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
236 lines
6.8 KiB
236 lines
6.8 KiB
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) |
|
if len(self.bad_barrels) > 3: |
|
self.state = self.cleanup |
|
else: |
|
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()
|
|
|