Clear leaves when low on saplings

This commit is contained in:
Tanner Collin 2020-10-17 23:35:43 -06:00
parent 69b0c057d6
commit 90388cf110
3 changed files with 134 additions and 50 deletions

5
bot.py
View File

@ -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

22
game.py
View File

@ -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:

159
jobs.py
View File

@ -163,6 +163,7 @@ class GatherWoodStates:
if not len(self.openings):
print('Unable to get to tree', 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
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)
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.state = self.wait_place
# self.wait_time = 1
self.area = area
navpath = w.path_to_place(p, self.area)
#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
if not navpath:
print('Unable to get to open area', self.area)
self.bad_areas.append(self.area)
self.state = self.cleanup
return
#def find_open_spot(self):
# print('Finding an open spot to stand...')
# w = self.g.world
# p = utils.pint(self.g.pos)
self.g.path = navpath
self.state = self.going_to_area
print('Going to area', self.area)
# 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
def going_to_area(self):
if utils.pint(self.g.pos) == self.area:
self.state = self.cleanup
# 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
# 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 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):