diff --git a/bot.py b/bot.py index 01d8f24..3e09eef 100644 --- a/bot.py +++ b/bot.py @@ -61,6 +61,7 @@ def tick(global_state): g.chunks.unload_chunks(p) ########## object physics ########## + # note: it's possible the chunk data is out of date when this runs for eid, obj in copy(g.objects).items(): if obj.velocity_x: @@ -84,8 +85,8 @@ def tick(global_state): obj.velocity_z *= 0.5 # float object back up in case it clipped through multiple blocks - while g.chunks.get_block_at(floor(obj.x), floor(obj.y), floor(obj.z)) not in blocks.NON_SOLID_IDS: - obj.y += 1 + if g.chunks.get_block_at(floor(obj.x), floor(obj.y), floor(obj.z)) not in blocks.NON_SOLID_IDS: + obj.y += 0.05 if abs(obj.velocity_x) < 1: obj.velocity_x = 0 if abs(obj.velocity_z) < 1: obj.velocity_z = 0 diff --git a/game.py b/game.py index 34f05b6..b776beb 100644 --- a/game.py +++ b/game.py @@ -190,6 +190,10 @@ class MCWorld: result.append(obj) return result + def find_leaves(self, center, distance): + for a in self.find_blocks_3d(center, blocks.LEAF_IDS, distance, 10): + yield a + class Game: def __init__(self, global_state): @@ -374,12 +378,16 @@ class Game: if command == 'dump' and data: item = int(data) - if self.has_item([item]): + if self.count_items([item]): self.g.dumping = item reply = 'ok' else: reply = 'not found' + if command == 'count' and data: + item = int(data) + reply = str(self.count_items([item])) + if command == 'open': self.open_container(blocks.TEST_BLOCK) @@ -502,13 +510,13 @@ class Game: else: self.pick(slot) - def has_item(self, items): - # test if any from items is in inv + def count_items(self, items): + # count how many items are in inv + count = 0 for slot, item in self.g.inv.items(): if item.item_id in items: - return True - else: #for - return False + count += item.item_count + return count def select_item(self, items): # select the first match from items of inv @@ -661,7 +669,7 @@ class Game: if self.g.breaking: self.animate() - if time.time() >= self.g.break_time - 2*utils.TICK: + if time.time() >= self.g.break_time: #- 2*utils.TICK: self.break_finish() if self.g.dumping and not self.g.item_lock: diff --git a/jobs.py b/jobs.py index bd8bdb5..cd52043 100644 --- a/jobs.py +++ b/jobs.py @@ -163,7 +163,8 @@ class GatherWoodStates: if not len(self.openings): print('Unable to get to tree', self.tree) - self.bad_trees.append(self.tree) + if self.tree not in self.good_trees: + self.bad_trees.append(self.tree) self.state = self.cleanup return @@ -249,6 +250,7 @@ class GatherWoodStates: self.wait_time -= utils.TICK else: self.g.chopped_tree = True + self.good_trees.append(self.tree) self.state = self.cleanup def cleanup(self): @@ -267,6 +269,7 @@ class GatherWoodStates: self.tree = None self.openings = [] self.bad_trees = [] + self.good_trees = [] self.wait_time = 0 def run(self): @@ -678,46 +681,47 @@ class PlantTreeStates: p = utils.pint(self.g.pos) self.g.game.place_block(p, BlockFace.TOP) print('Placed sapling') - self.state = self.wait_place - self.wait_time = 1 + self.state = self.cleanup + # self.state = self.wait_place + # self.wait_time = 1 - def wait_place(self): - # wait a bit for chunk data to update - if self.wait_time > 0: - self.wait_time -= utils.TICK - else: - self.state = self.find_open_spot + #def wait_place(self): + # # wait a bit for chunk data to update + # if self.wait_time > 0: + # self.wait_time -= utils.TICK + # else: + # self.state = self.find_open_spot - def find_open_spot(self): - print('Finding an open spot to stand...') - w = self.g.world - p = utils.pint(self.g.pos) + #def find_open_spot(self): + # print('Finding an open spot to stand...') + # w = self.g.world + # p = utils.pint(self.g.pos) - for area in w.find_cache_areas(p, 20): - print('Found area:', area) - if area not in self.bad_areas: - break - else: # for - print('Unable to find area') - self.state = self.cleanup - return + # for area in w.find_cache_areas(p, 20): + # print('Found area:', area) + # if area not in self.bad_areas: + # break + # else: # for + # print('Unable to find area') + # self.state = self.cleanup + # return - self.area = area - navpath = w.path_to_place(p, self.area) + # self.area = area + # navpath = w.path_to_place(p, self.area) - if not navpath: - print('Unable to get to open area', self.area) - self.bad_areas.append(self.area) - self.state = self.cleanup - return + # if not navpath: + # print('Unable to get to open area', self.area) + # self.bad_areas.append(self.area) + # self.state = self.cleanup + # return - self.g.path = navpath - self.state = self.going_to_area - print('Going to area', self.area) + # self.g.path = navpath + # self.state = self.going_to_area + # print('Going to area', self.area) - def going_to_area(self): - if utils.pint(self.g.pos) == self.area: - self.state = self.cleanup + #def going_to_area(self): + # if utils.pint(self.g.pos) == self.area: + # self.state = self.cleanup def cleanup(self): self.g.look_at = None @@ -739,6 +743,68 @@ class PlantTreeStates: self.state() +class ClearLeavesStates: + def idle(self): + return None + + def init(self): + num_saplings = self.g.game.count_items(items.SAPLING_IDS) + print('Have', num_saplings, 'saplings in inventory') + if num_saplings < 8: + self.state = self.find_leaves + print('Clearing leaves...') + else: + print('Aborting clearing leaves') + self.state = self.cleanup + + def find_leaves(self): + w = self.g.world + p = utils.pint(self.g.pos) + + break_distance = 5 + + for l in w.find_leaves(p, break_distance): + self.leaves.append(l) + + self.state = self.break_leaves + + def break_leaves(self): + if not self.g.breaking: + if self.leaves: + leaf = self.leaves.pop(0) + self.g.look_at = leaf + self.g.game.break_block(leaf) + print('Breaking leaf', leaf) + else: + self.wait_time = 1 + self.state = self.wait + + def wait(self): + # wait for the items to drop + if self.wait_time > 0: + self.wait_time -= utils.TICK + else: + self.state = self.cleanup + + def cleanup(self): + self.g.look_at = None + 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.leaves = [] + self.wait_time = 0 + + def run(self): + self.state() + + class GrabSaplingStates: def idle(self): return None @@ -749,6 +815,7 @@ class GrabSaplingStates: def find_saplings(self): w = self.g.world + p = utils.pint(self.g.pos) saplings = w.find_objects(items.SAPLING_IDS) @@ -757,10 +824,9 @@ class GrabSaplingStates: self.state = self.cleanup return - random.shuffle(saplings) + saplings.sort(key=lambda s: utils.phyp(p, (s.x, s.y, s.z))) for s in saplings: - p = utils.pint(self.g.pos) s_pos = utils.pint((s.x, s.y, s.z)) check = utils.padd(s_pos, path.BLOCK_BELOW) @@ -782,12 +848,12 @@ class GrabSaplingStates: print('Going to sapling', self.sapling) return - print('Cant get to any saplings, aborting') + print('Cant get to any more saplings, aborting') self.state = self.cleanup def going_to_sapling(self): if utils.pint(self.g.pos) == self.sapling: - self.state = self.cleanup + self.state = self.find_saplings def cleanup(self): self.g.look_at = None @@ -887,9 +953,10 @@ class JobStates: s1 = self.gather_wood_states s2 = self.plant_tree_states - s3 = self.sleep_with_bed_states - s4 = self.cache_items_states - s5 = self.grab_sapling_states + s3 = self.clear_leaves_states + s4 = self.grab_sapling_states + s5 = self.sleep_with_bed_states + s6 = self.cache_items_states if s1.state == s1.idle: s1.state = s1.init @@ -897,6 +964,7 @@ class JobStates: s3.state = s3.init s4.state = s4.init s5.state = s5.init + s6.state = s6.init elif s1.state == s1.done: if s2.state != s2.done: s2.run() @@ -914,11 +982,16 @@ class JobStates: s5.run() return + if s6.state != s6.done: + s6.run() + return + s1.state = s1.init s2.state = s2.init s3.state = s3.init s4.state = s4.init s5.state = s5.init + s6.state = s6.init return s1.run() @@ -930,6 +1003,7 @@ class JobStates: self.cache_items_states = CacheItemsStates(self.g) self.find_gapple_states = FindGappleStates(self.g) self.plant_tree_states = PlantTreeStates(self.g) + self.clear_leaves_states = ClearLeavesStates(self.g) self.grab_sapling_states = GrabSaplingStates(self.g) self.state = self.idle @@ -944,6 +1018,7 @@ class JobStates: self.cache_items_states = CacheItemsStates(self.g) self.find_gapple_states = FindGappleStates(self.g) self.plant_tree_states = PlantTreeStates(self.g) + self.clear_leaves_states = ClearLeavesStates(self.g) self.grab_sapling_states = GrabSaplingStates(self.g) def tick(self):