minecraft-bot/jobs.py

439 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)
import items
importlib.reload(items)
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
navpath = w.path_to_place(p, self.openings[0])
if navpath:
self.g.path = navpath
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 = utils.psub(self.tree, p)
for x in utils.diffrange(diff[0]):
for z in utils.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)
navpath = w.path_to_place(p, self.tree)
if navpath:
self.g.path = navpath
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 -= 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.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, 50, self.origin)
print('Found sand:', sand)
for check in sand:
if check in self.bad_sand:
continue
self.sand = check
break
self.state = self.nav_to_sand
def nav_to_sand(self):
w = self.g.world
p = utils.pint(self.g.pos)
self.g.chunks.set_block_at(*self.sand, blocks.AIR)
navpath = w.path_to_place(p, self.sand)
self.g.chunks.set_block_at(*self.sand, blocks.SAND)
if navpath:
self.g.path = navpath[:-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)
navpath = w.path_to_place(p, self.sand)
if navpath:
self.g.path = navpath
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.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:
navpath = w.path_to_place(p, o)
self.opening = o
if navpath: 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 = navpath
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):
if self.game.select_item(items.BED_IDS):
self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW)
self.state = self.place_bed
else:
self.g.chat.send('I need a bed')
self.state = self.cleanup
def place_bed(self):
self.g.game.place_block(self.area, BlockFace.TOP)
self.state = self.use_bed
def use_bed(self):
if self.g.time >= 12542:
print('Sleeping')
self.g.game.place_block(self.area, BlockFace.TOP)
self.g.chat.send('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 -= 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.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
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
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.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)
def tick(self):
self.state()