diff --git a/jobs.py b/jobs.py index c30efa0..f091529 100644 --- a/jobs.py +++ b/jobs.py @@ -1121,7 +1121,7 @@ class FillBlocksStates: return if self.last_block: - self.state = self.select_block + self.state = self.select_item else: self.state = self.find_last_block @@ -1131,28 +1131,29 @@ class FillBlocksStates: 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] - distance = utils.phyp(f.coord1, f.coord2) - self.next_block = f.coord1 + 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]) - for offset in utils.search_3d(distance): - check = utils.padd(f.coord1, offset) + # 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 - # 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 - if w.block_at(*check) == blocks.AIR: - self.state = self.select_block - return + self.last_block = check - self.last_block = check - - def select_block(self): + def select_item(self): f = self.g.filling name = blocks.BLOCKS[f.block] item = items.ITEMS['minecraft:'+name]['protocol_id'] @@ -1175,21 +1176,14 @@ class FillBlocksStates: y_start = f.coord1[1] y_end = f.coord2[1] - print('distance', xz_distance) - for y in range(y_start, y_end+1): - for i in count(): - offset = utils.spiral(i) - check = utils.padd(self.last_block, offset) + 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]) - print('layer', y) - print('offset', offset) - print('hypot', hypot(offset[0], offset[2])) - - if hypot(offset[0], offset[2]) > xz_distance: - break - # ensure block is within fill area if check[0] < b1[0] or check[0] > b2[0]: continue @@ -1245,23 +1239,20 @@ class FillBlocksStates: 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): - if self.wait_time > 0: - self.wait_time -= utils.TICK - else: - self.state = self.check_block - - def check_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 + self.state = self.check_obstruction def check_obstruction(self): p = utils.pint(self.g.pos) @@ -1303,6 +1294,7 @@ class FillBlocksStates: self.g = global_state self.state = self.idle + self.iterators = {} self.wait_time = 0 self.last_block = None self.next_block = None diff --git a/utils.py b/utils.py index 87197de..b6e5a51 100644 --- a/utils.py +++ b/utils.py @@ -107,6 +107,33 @@ def break_time(block_id, held_item=0, in_water=False, on_ground=True, enchantmen return time +def search_2d(distance=0): + def get_neighbors(x,y,z): + return [ + (x+1, y+0, z+0), + #(x+1, y+0, z+1), + (x+0, y+0, z-1), + #(x-1, y+0, z+1), + (x-1, y+0, z+0), + #(x-1, y+0, z-1), + (x+0, y+0, z+1), + #(x+1, y+0, z-1), + ] + + to_visit = collections.deque([(0, 0, 0)]) + visited = set() + + while to_visit: + cur = to_visit.pop() + if cur in visited: + continue + if distance and hypot(*cur) > distance: + continue + for neighbor in get_neighbors(*cur): + to_visit.appendleft(neighbor) + visited.add(cur) + yield cur + def search_3d(distance=0, y_limit=0): def get_neighbors(x,y,z): return [