import re import time import importlib import random from itertools import count from math import hypot, floor from minecraft.networking.types import BlockFace from protocol.managers import ChunkNotLoadedException import utils importlib.reload(utils) import path importlib.reload(path) import blocks importlib.reload(blocks) import items importlib.reload(items) import mcdata importlib.reload(mcdata) import mobs importlib.reload(mobs) class FillBlocksStates: def idle(self): return None def init(self): f = self.g.filling if not f: self.state = self.cleanup print('Aborting, nothing to fill') return if self.last_block: self.state = self.select_item else: self.state = self.find_last_block def find_last_block(self): w = self.g.world f = self.g.filling print('Finding last block') b1, b2 = utils.pboundingbox(f.coord1, f.coord2) box = utils.psub(b2, b1) xz_distance = hypot(box[0]+1, box[2]+1) y_start = f.coord1[1] y_end = f.coord2[1] for y in range(y_start, y_end+1): for offset in utils.search_2d(xz_distance): check = utils.padd(f.coord1, offset) check = (check[0], y, check[2]) # ensure block is within fill area if check[0] < b1[0] or check[0] > b2[0]: continue if check[2] < b1[2] or check[2] > b2[2]: continue if w.block_at(*check) == blocks.AIR: self.state = self.select_item return self.last_block = check else: # for self.state = self.cleanup print('Aborting, no air left') return def select_item(self): f = self.g.filling name = blocks.BLOCKS[f.block] item = items.ITEMS['minecraft:'+name]['protocol_id'] if self.g.game.select_item([item]): #self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW) self.state = self.find_next_block else: print('No blocks, aborting') self.state = self.cleanup def find_next_block(self): w = self.g.world f = self.g.filling print('Finding next block, last:', self.last_block) b1, b2 = utils.pboundingbox(f.coord1, f.coord2) box = utils.psub(b2, b1) xz_distance = hypot(box[0]+1, box[2]+1) y_start = f.coord1[1] y_end = f.coord2[1] for y in range(y_start, y_end+1): if y not in self.iterators: self.iterators[y] = utils.search_2d(xz_distance) for offset in self.iterators[y]: check = utils.padd(f.coord1, offset) check = (check[0], y, check[2]) # ensure block is within fill area if check[0] < b1[0] or check[0] > b2[0]: continue if check[2] < b1[2] or check[2] > b2[2]: continue if w.block_at(*check) == blocks.AIR: print('Found next block:', check) self.next_block = check self.state = self.check_block_distance return # if there's nothing left to fill self.g.filling = None self.state = self.cleanup def check_block_distance(self): w = self.g.world p = utils.pint(self.g.pos) head = utils.padd(p, path.BLOCK_ABOVE) if utils.phyp(head, self.next_block) < 4: self.state = self.fill_block else: self.state = self.nav_to_block def nav_to_block(self): w = self.g.world p = utils.pint(self.g.pos) c = self.g.chunks tmp = c.get_block_at(*self.next_block) c.set_block_at(*self.next_block, blocks.STONE) pos = utils.padd(self.next_block, path.BLOCK_ABOVE) navpath = w.path_to_place(p, pos) c.set_block_at(*self.next_block, tmp) if navpath: self.g.path = navpath[:-1] self.state = self.going_to_block else: print('Cant get to that block') self.state = self.cleanup #self.bad_sand.append(self.sand) #self.state = self.find_new_sand def going_to_block(self): if not len(self.g.path): self.state = self.fill_block def fill_block(self): print('Filling block', self.next_block) self.g.game.place_block(self.next_block, BlockFace.TOP) self.g.look_at = self.next_block self.wait_time = 0.25 self.state = self.wait_for_block def wait_for_block(self): w = self.g.world if w.block_at(*self.next_block) != blocks.AIR: self.last_block = self.next_block self.state = self.check_obstruction elif self.wait_time > 0: self.wait_time -= utils.TICK else: print('Block didnt appear') self.state = self.check_obstruction def check_obstruction(self): p = utils.pint(self.g.pos) f = self.g.filling print('last', self.last_block) print('p', p) if self.last_block[1] >= p[1] and f.block not in blocks.NON_SOLID_IDS: print('Obstructed, going to last block') self.state = self.nav_to_last_block else: self.state = self.cleanup def nav_to_last_block(self): w = self.g.world p = utils.pint(self.g.pos) c = self.g.chunks pos = utils.padd(self.last_block, path.BLOCK_ABOVE) navpath = w.path_to_place(p, pos) if navpath: self.g.path = navpath self.state = self.going_to_last_block else: print('Cant get to that block') self.state = self.cleanup def going_to_last_block(self): if not len(self.g.path): self.state = self.cleanup 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.iterators = {} self.wait_time = 0 self.last_block = None self.next_block = None def run(self): self.state()