Files
minecraft-bot/mosfet/jobs/check_threats.py
T

128 lines
3.7 KiB
Python

import re
import time
import importlib
import random
from itertools import count
from math import floor
from minecraft.networking.types import BlockFace
from mosfet.protocol.managers import ChunkNotLoadedException
from mosfet import utils
from mosfet import path
from mosfet.info import blocks
from mosfet.info import items
from mosfet.info import mcdata
from mosfet.info import mobs
class CheckThreatsStates:
THREAT_DISTANCE = 20
CLEAR_DISTANCE = 30
CHECK_INTERVAL = 2.0
def idle(self):
return None
def init(self):
self.state = self.find_threats
print('Checking for threats')
def find_threats(self):
w = self.g.world
p = utils.pint(self.g.pos)
threats = w.find_threats(p, self.THREAT_DISTANCE)
if threats:
print('Found', len(threats), 'threats, seeking safety:')
print(threats)
self.threats = threats
self.state = self.find_safety
else:
self.wait_time = self.CHECK_INTERVAL
self.state = self.wait
def find_safety(self):
w = self.g.world
p = utils.pint(self.g.pos)
safety_blocks = w.find_blocks_indexed(
p, [blocks.EMERALD_BLOCK], self.THREAT_DISTANCE * 4)
for block in safety_blocks:
spot = utils.padd(block, path.BLOCK_ABOVE)
if w.find_threats(spot, self.CLEAR_DISTANCE):
continue
navpath = w.path_to_place(p, spot)
if navpath is not None:
self.safety = spot
self.external_safety = True
self.g.path = navpath
self.state = self.going_to_safety
print('Going to emerald safety point', self.safety)
return
# No configured emerald safe point was reachable. Retreat to a clear,
# supported location that the modern navigator can actually reach.
for spot in w.find_bed_areas(p, self.CLEAR_DISTANCE * 2):
if w.find_threats(spot, self.CLEAR_DISTANCE):
continue
navpath = w.path_to_place(p, spot)
if navpath is not None:
self.safety = spot
self.external_safety = False
self.g.path = navpath
self.state = self.going_to_safety
print('Fleeing to clear area', self.safety)
return
print('No reachable safe area found')
self.wait_time = self.CHECK_INTERVAL
self.state = self.wait
def going_to_safety(self):
if utils.pint(self.g.pos) == self.safety:
if self.external_safety:
print('At emerald safety point, waiting for server move')
self.state = self.wait_for_move
else:
print('At clear retreat spot')
self.wait_time = 3
self.state = self.wait
def wait_for_move(self):
# wait for the server to move the bot when it's safe
# ie. a piston + daylight sensor
if utils.pint(self.g.pos) != self.safety:
print('Moved, resuming job')
self.state = self.wait
self.wait_time = 3
def wait(self):
# wait to land, etc
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.safety = None
self.wait_time = 0
self.threats = []
self.external_safety = False
def run(self):
self.state()