minecraft-bot/jobs.py

446 lines
12 KiB
Python

import re
import time
import importlib
from math import hypot
from panda3d.core import LPoint3f
from minecraft.networking.types import BlockFace
import utils
importlib.reload(utils)
import path
importlib.reload(path)
import blocks
importlib.reload(blocks)
class LumberjackStates:
def bair(self, p):
return self.g.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS
def blog(self, p):
return self.g.chunks.get_block_at(*p) in blocks.LOG_IDS
def idle(self):
return None
def init(self):
self.state = self.find_new_tree
def find_new_tree(self):
print('Finding new tree...')
w = self.g.world
p = utils.pint(self.g.pos)
trees = w.find_trees(p, 100)
print('Found trees:', trees)
while trees[0] in self.bad_trees:
trees.pop(0)
self.tree = trees[0]
self.openings = w.find_tree_openings(self.tree)
self.state = self.choose_opening
def choose_opening(self):
w = self.g.world
p = utils.pint(self.g.pos)
print('openings:', self.openings)
if not len(self.openings):
print('Unable to get to tree', self.tree)
self.bad_trees.append(self.tree)
self.state = self.cleanup
return
path = w.path_to_place(p, self.openings[0])
if path:
self.g.path = path
self.state = self.going_to_tree
else:
self.openings.pop(0)
def going_to_tree(self):
if utils.pint(self.g.pos) == self.openings[0]:
self.g.look_at = self.tree
self.state = self.clear_leaves
def clear_leaves(self):
if not self.g.breaking:
p = utils.pint(self.g.pos)
diff = psub(self.tree, p)
for x in diffrange(diff[0]):
for z in diffrange(diff[2]):
for y in range(2):
check = utils.padd(p, (x, y, z))
if check == self.tree:
break
if not self.bair(check):
print('Breaking leaf')
self.g.game.break_block(check)
return
self.state = self.clear_trunk_base
def clear_trunk_base(self):
if not self.g.breaking:
base = self.tree
above = utils.padd(self.tree, path.BLOCK_ABOVE)
if self.blog(base):
self.g.game.break_block(base)
print('breaking base')
elif self.blog(above):
self.g.game.break_block(above)
print('breaking above')
else:
w = self.g.world
p = utils.pint(self.g.pos)
path = w.path_to_place(p, self.tree)
if path:
self.g.path = path
self.state = self.going_to_trunk_base
else:
self.openings.pop(0)
self.state = self.choose_opening
def going_to_trunk_base(self):
if utils.pint(self.g.pos) == self.tree:
self.g.look_at = utils.padd(self.tree, path.BLOCK_ABOVE2)
self.state = self.clear_trunk
def clear_trunk(self):
if not self.g.breaking:
check = self.tree
count = 0
while self.bair(check) and count < 6:
check = utils.padd(check, path.BLOCK_ABOVE)
count += 1
if self.blog(check):
print('breaking log', check)
self.g.game.break_block(check)
else:
print('Finished clearing tree')
self.wait_time = 0.5
self.state = self.wait
def wait(self):
# wait for the last log to fall
if self.wait_time > 0:
self.wait_time -= 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.l = self.g.local_state
self.state = self.idle
self.tree = None
self.openings = []
self.bad_trees = []
self.wait_time = 0
def run(self):
self.state()
class GatherSandStates:
def bair(self, p):
return self.g.chunks.get_block_at(*p) in blocks.NON_SOLID_IDS
def bsand(self, p):
return self.g.chunks.get_block_at(*p) == 66
def idle(self):
return None
def init(self):
self.state = self.find_new_sand
def find_new_sand(self):
print('Finding new sand...')
w = self.g.world
p = utils.pint(self.g.pos)
sand = w.find_sand(p, 150, self.origin)
print('Found sand:', sand)
while sand[0] in self.bad_sand:
sand.pop(0)
self.sand = sand[0]
self.state = self.nav_to_sand
def nav_to_sand(self):
w = self.g.world
p = utils.pint(self.g.pos)
w.chunks.set_block_at(*self.sand, 0)
path = w.path_to_place(p, self.sand)
w.chunks.set_block_at(*self.sand, 66)
if path:
self.g.path = path[:-1]
self.state = self.going_to_sand
else:
self.bad_sand.append(self.sand)
self.state = self.find_new_sand
def going_to_sand(self):
if not len(self.g.path):
self.g.look_at = self.sand
self.state = self.dig_sand
def dig_sand(self):
if not self.g.breaking:
if self.bsand(self.sand):
self.g.game.break_block(self.sand)
print('digging sand')
else:
self.state = self.get_sand
def get_sand(self):
w = self.g.world
p = utils.pint(self.g.pos)
path = w.path_to_place(p, self.sand)
if path:
self.g.path = path
self.state = self.going_to_item
else:
self.bad_sand.append(self.sand)
self.state = self.find_new_sand
def going_to_item(self):
if utils.pint(self.g.pos) == self.sand:
self.g.look_at = self.sand
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.l = self.g.local_state
self.state = self.idle
self.origin = utils.pint(self.g.pos)
self.sand = None
self.bad_sand = []
self.wait_time = 0
def run(self):
self.state()
class SleepWithBedStates:
def idle(self):
return None
def init(self):
if self.g.time >= 12000:
self.state = self.find_bed_spot
else:
print('Aborting sleep, not night')
self.state = self.cleanup
def find_bed_spot(self):
print('Finding a bed spot...')
w = self.g.world
p = utils.pint(self.g.pos)
areas = w.find_bed_areas(p, 100)
print('Found areas:', areas)
if len(areas):
while areas[0] in self.bad_areas:
areas.pop(0)
self.area = areas[0]
elif self.last_area:
self.area = self.last_area
else:
print('Unable to find area, and no last area')
self.state = self.cleanup
return
openings = w.find_bed_openings(self.area)
for o in openings:
path = w.path_to_place(p, o)
self.opening = o
if path: break
else: # for
print('Unable to get to bed area', self.area)
self.bad_areas.append(self.area)
self.state = self.cleanup
return
self.g.path = path
self.state = self.going_to_area
self.last_area = self.area
def going_to_area(self):
if utils.pint(self.g.pos) == self.opening:
self.g.look_at = self.area
self.state = self.select_bed
def select_bed(self):
for slot, item in self.g.inv.items():
if item.item_id in items.BED_IDS:
print('Found bed in slot', slot)
self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW)
choose_slot(self.connection, slot)
self.state = self.place_bed
break
else: # for
say(self.connection, 'I need a bed')
self.state = self.cleanup
def place_bed(self):
place_block(self.connection, self.area, BlockFace.TOP)
self.state = self.use_bed
def use_bed(self):
if self.g.time >= 12542:
print('Sleeping')
place_block(self.connection, self.area, BlockFace.TOP)
say(self.connection, 'zzz')
self.state = self.sleep_bed
def sleep_bed(self):
if self.g.time < 100:
print('Woke up')
self.state = self.break_bed
def break_bed(self):
self.g.game.break_block(self.area)
self.state = self.collect_bed
def collect_bed(self):
if not self.g.breaking:
self.g.path = [utils.padd(self.area, utils.spiral(n)) for n in range(9)]
self.wait_time = 4
self.state = self.wait
def wait(self):
# wait to pick up bed
if self.wait_time > 0:
self.wait_time -= 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.l = self.g.local_state
self.state = self.idle
self.area = None
self.opening = None
self.bad_areas = []
self.last_area = None
self.wait_time = 0
def run(self):
self.state()
class JobStates:
def idle(self):
return None
def sleep_with_bed(self):
s = self.sleep_with_bed_states
if s.state == s.idle:
s.state = s.init
elif s.state == s.done:
s.state = s.init
# check time, etc
if self.prev_state:
print('Reverting to prev state')
self.state = self.prev_state
return
s.run()
def gather_sand(self):
s = self.gather_sand_states
if s.state == s.idle:
s.state = s.init
elif s.state == s.done:
s.state = s.init
# check time, etc
if self.survive:
self.prev_state = self.gather_sand
self.state = self.sleep_with_bed
return
s.run()
def lumberjack(self):
s = self.lumberjack_states
if s.state == s.idle:
s.state = s.init
elif s.state == s.done:
s.state = s.init
# check time, etc
if self.survive:
self.prev_state = self.lumberjack
self.state = self.sleep_with_bed
return
s.run()
def stop(self):
self.lumberjack_states = LumberjackStates(self.g)
self.gather_sand_states = GatherSandStates(self.g)
self.sleep_with_bed_states = SleepWithBedStates(self.g)
self.state = self.idle
def __init__(self, global_state):
self.g = global_state
self.l = self.g.local_state
self.state = self.idle
self.prev_state = None
self.lumberjack_states = LumberjackStates(self.g)
self.gather_sand_states = GatherSandStates(self.g)
self.sleep_with_bed_states = SleepWithBedStates(self.g)
self.survive = False
def run(self):
self.state()