|
|
|
@ -2,6 +2,7 @@ import re |
|
|
|
|
import time |
|
|
|
|
import importlib |
|
|
|
|
import random |
|
|
|
|
from itertools import count |
|
|
|
|
from math import hypot |
|
|
|
|
|
|
|
|
|
from panda3d.core import LPoint3f |
|
|
|
@ -1107,6 +1108,209 @@ class CheckThreatsStates: |
|
|
|
|
self.state() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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_block |
|
|
|
|
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) |
|
|
|
|
y_start = f.coord1[1] |
|
|
|
|
y_end = f.coord2[1] |
|
|
|
|
distance = utils.phyp(f.coord1, f.coord2) |
|
|
|
|
|
|
|
|
|
self.next_block = f.coord1 |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
if w.block_at(*check) == blocks.AIR: |
|
|
|
|
self.state = self.select_block |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
self.last_block = check |
|
|
|
|
|
|
|
|
|
def select_block(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] |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
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 |
|
|
|
|
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): |
|
|
|
|
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 |
|
|
|
|
else: |
|
|
|
|
print('Block didnt appear') |
|
|
|
|
|
|
|
|
|
self.state = self.check_obstruction |
|
|
|
|
|
|
|
|
|
def check_obstruction(self): |
|
|
|
|
p = utils.pint(self.g.pos) |
|
|
|
|
print('last', self.last_block) |
|
|
|
|
print('p', p) |
|
|
|
|
if self.last_block[1] >= p[1]: |
|
|
|
|
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.wait_time = 0 |
|
|
|
|
self.last_block = None |
|
|
|
|
self.next_block = None |
|
|
|
|
|
|
|
|
|
def run(self): |
|
|
|
|
self.state() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class JobStates: |
|
|
|
|
def idle(self): |
|
|
|
|
return [] |
|
|
|
@ -1121,6 +1325,7 @@ class JobStates: |
|
|
|
|
self.clear_leaves_states = ClearLeavesStates(self.g) |
|
|
|
|
self.grab_sapling_states = GrabSaplingStates(self.g) |
|
|
|
|
self.grab_sand_states = GrabSandStates(self.g) |
|
|
|
|
self.fill_blocks_states = FillBlocksStates(self.g) |
|
|
|
|
self.check_threats_states = CheckThreatsStates(self.g) |
|
|
|
|
|
|
|
|
|
def run_machines(self, machines): |
|
|
|
@ -1190,6 +1395,13 @@ class JobStates: |
|
|
|
|
self.cache_items_states.silent = True |
|
|
|
|
return machines |
|
|
|
|
|
|
|
|
|
def fill_blocks(self): |
|
|
|
|
machines = [ |
|
|
|
|
self.fill_blocks_states, |
|
|
|
|
self.sleep_with_bed_states, |
|
|
|
|
] |
|
|
|
|
return machines |
|
|
|
|
|
|
|
|
|
def stop(self): |
|
|
|
|
self.init_machines() |
|
|
|
|
self.state = self.idle |
|
|
|
|