Detect monsters and flee to safety
This commit is contained in:
		@@ -16,12 +16,13 @@ for name, data in JSON_BLOCKS.items():
 | 
				
			|||||||
    for state in data['states']:
 | 
					    for state in data['states']:
 | 
				
			||||||
        BLOCKS[state['id']] = name.replace('minecraft:', '')
 | 
					        BLOCKS[state['id']] = name.replace('minecraft:', '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
BREAK_DISTANCE = 5
 | 
					BREAK_DISTANCE = 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AIR = 0
 | 
					AIR = 0
 | 
				
			||||||
SAND = 66
 | 
					SAND = 66
 | 
				
			||||||
SINGLE_SNOW = 3921
 | 
					SINGLE_SNOW = 3921
 | 
				
			||||||
SOUL_TORCH = 4008
 | 
					SOUL_TORCH = 4008
 | 
				
			||||||
 | 
					EMERALD_BLOCK = 5407
 | 
				
			||||||
 | 
					
 | 
				
			||||||
TEST_BLOCK = (616, 78, 496)
 | 
					TEST_BLOCK = (616, 78, 496)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -246,6 +247,7 @@ TRAPPED_CHESTS = [
 | 
				
			|||||||
INDEXED = [
 | 
					INDEXED = [
 | 
				
			||||||
    'chest',
 | 
					    'chest',
 | 
				
			||||||
    'trapped_chest',
 | 
					    'trapped_chest',
 | 
				
			||||||
 | 
					    'emerald_block',
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								bot.py
									
									
									
									
									
								
							@@ -203,6 +203,8 @@ def init(global_state):
 | 
				
			|||||||
    g.job = jobs.JobStates(g)
 | 
					    g.job = jobs.JobStates(g)
 | 
				
			||||||
    g.chopped_tree = False
 | 
					    g.chopped_tree = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    g.queue_afk = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def bot(global_state):
 | 
					def bot(global_state):
 | 
				
			||||||
    g = global_state
 | 
					    g = global_state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										448
									
								
								game.py
									
									
									
									
									
								
							
							
						
						
									
										448
									
								
								game.py
									
									
									
									
									
								
							@@ -2,6 +2,7 @@ import re
 | 
				
			|||||||
import time
 | 
					import time
 | 
				
			||||||
import importlib
 | 
					import importlib
 | 
				
			||||||
import random
 | 
					import random
 | 
				
			||||||
 | 
					import functools
 | 
				
			||||||
from math import hypot
 | 
					from math import hypot
 | 
				
			||||||
from itertools import count
 | 
					from itertools import count
 | 
				
			||||||
from munch import Munch
 | 
					from munch import Munch
 | 
				
			||||||
@@ -19,6 +20,7 @@ from protocol.packets import (
 | 
				
			|||||||
    ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
 | 
					    ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
 | 
				
			||||||
    ClientWindowConfirmationPacket, EntityMetadataPacket,
 | 
					    ClientWindowConfirmationPacket, EntityMetadataPacket,
 | 
				
			||||||
    SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket,
 | 
					    SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket,
 | 
				
			||||||
 | 
					    EntityActionPacket,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from protocol.types import Slot
 | 
					from protocol.types import Slot
 | 
				
			||||||
@@ -33,6 +35,8 @@ import items
 | 
				
			|||||||
importlib.reload(items)
 | 
					importlib.reload(items)
 | 
				
			||||||
import data
 | 
					import data
 | 
				
			||||||
importlib.reload(data)
 | 
					importlib.reload(data)
 | 
				
			||||||
 | 
					import mobs
 | 
				
			||||||
 | 
					importlib.reload(mobs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MCWorld:
 | 
					class MCWorld:
 | 
				
			||||||
    def __init__(self, global_state):
 | 
					    def __init__(self, global_state):
 | 
				
			||||||
@@ -41,6 +45,13 @@ class MCWorld:
 | 
				
			|||||||
    def block_at(self, x, y, z):
 | 
					    def block_at(self, x, y, z):
 | 
				
			||||||
        return self.g.chunks.get_block_at(x, y, z)
 | 
					        return self.g.chunks.get_block_at(x, y, z)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def check_air_column(self, pos, distance):
 | 
				
			||||||
 | 
					        for i in range(distance):
 | 
				
			||||||
 | 
					            check = utils.padd(pos, (0, i, 0))
 | 
				
			||||||
 | 
					            if self.block_at(*check) not in blocks.NON_SOLID_IDS:
 | 
				
			||||||
 | 
					                return False
 | 
				
			||||||
 | 
					        return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def find_blocks_3d(self, center, block_ids, distance=0, y_limit=0):
 | 
					    def find_blocks_3d(self, center, block_ids, distance=0, y_limit=0):
 | 
				
			||||||
        for offset in utils.search_3d(distance, y_limit):
 | 
					        for offset in utils.search_3d(distance, y_limit):
 | 
				
			||||||
            check = utils.padd(center, offset)
 | 
					            check = utils.padd(center, offset)
 | 
				
			||||||
@@ -189,10 +200,9 @@ class MCWorld:
 | 
				
			|||||||
        return safe_sand
 | 
					        return safe_sand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def check_sand_slice(self, center):
 | 
					    def check_sand_slice(self, center):
 | 
				
			||||||
        # checks if a 5x5x1 slice has diggable sand in it
 | 
					        # checks if a 5x5x1 slice has sand in it
 | 
				
			||||||
        for i in range(9):
 | 
					        for i in range(9):
 | 
				
			||||||
            s = utils.padd(center, utils.spiral(i))
 | 
					            s = utils.padd(center, utils.spiral(i))
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if self.block_at(*s) != blocks.SAND:
 | 
					            if self.block_at(*s) != blocks.SAND:
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            # make sure it has solid below
 | 
					            # make sure it has solid below
 | 
				
			||||||
@@ -206,18 +216,17 @@ class MCWorld:
 | 
				
			|||||||
                continue
 | 
					                continue
 | 
				
			||||||
            if not self.sand_adjacent_safe(s):
 | 
					            if not self.sand_adjacent_safe(s):
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
 | 
					 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def find_sand_slice(self, center, distance, bad_slices=[]):
 | 
					    def find_sand_slice(self, center, distance, y_limit=0, bad_slices=[], prev_layer=0):
 | 
				
			||||||
        # returns the centre coord of the next 5x5x1 slice that still has
 | 
					        # returns the centre coord of the next 5x5x1 slice that still has
 | 
				
			||||||
        # diggable sand in it. lower slices are only valid if there's an
 | 
					        # diggable sand in it. lower slices are only valid if there's an
 | 
				
			||||||
        # adjacent slice farther at the same level. this should ensure an
 | 
					        # adjacent slice farther at the same level. this should ensure an
 | 
				
			||||||
        # upside down pyramid gets excavated so the edges are still climbable
 | 
					        # upside down pyramid gets excavated so the edges are still climbable
 | 
				
			||||||
        for v in count():
 | 
					        for v in count(prev_layer):
 | 
				
			||||||
            peak = utils.padd(center, (0, 20-v, 0))
 | 
					            peak = utils.padd(center, (0, 10-v, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            slices = []
 | 
					            slices = []
 | 
				
			||||||
            layer = 0
 | 
					            layer = 0
 | 
				
			||||||
@@ -228,14 +237,16 @@ class MCWorld:
 | 
				
			|||||||
                check = utils.padd(peak, offset)
 | 
					                check = utils.padd(peak, offset)
 | 
				
			||||||
                check = utils.padd(check, (0, layer, 0))
 | 
					                check = utils.padd(check, (0, layer, 0))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if utils.phyp(center, check) >= distance:
 | 
					                if y_limit and check[1] - center[1] > y_limit:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					                if utils.phyp_king(center, check) > distance:
 | 
				
			||||||
                    break
 | 
					                    break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if self.check_sand_slice(check) and check not in bad_slices:
 | 
					                if self.check_sand_slice(check) and check not in bad_slices:
 | 
				
			||||||
                    slices.append(check)
 | 
					                    slices.append(check)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if len(slices):
 | 
					            if len(slices):
 | 
				
			||||||
                return slices[-1]
 | 
					                return v, slices[-1]
 | 
				
			||||||
            elif v > 40:
 | 
					            elif v > 40:
 | 
				
			||||||
                return None, None
 | 
					                return None, None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -262,6 +273,31 @@ class MCWorld:
 | 
				
			|||||||
        for a in self.find_blocks_3d(center, blocks.LEAF_IDS, distance, 10):
 | 
					        for a in self.find_blocks_3d(center, blocks.LEAF_IDS, distance, 10):
 | 
				
			||||||
            yield a
 | 
					            yield a
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_monsters(self, center, distance):
 | 
				
			||||||
 | 
					        # finds monsters within distance
 | 
				
			||||||
 | 
					        result = []
 | 
				
			||||||
 | 
					        for eid, mob in self.g.mobs.items():
 | 
				
			||||||
 | 
					            if mob.type not in mobs.EVIL_IDS:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            pos = utils.pint((mob.x, mob.y, mob.z))
 | 
				
			||||||
 | 
					            if utils.phyp(center, pos) > distance:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            result.append(mob)
 | 
				
			||||||
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_threats(self, center, distance):
 | 
				
			||||||
 | 
					        # finds monsters on the surface within distance
 | 
				
			||||||
 | 
					        monsters = self.find_monsters(center, distance)
 | 
				
			||||||
 | 
					        result = []
 | 
				
			||||||
 | 
					        for mob in monsters:
 | 
				
			||||||
 | 
					            pos = utils.pint((mob.x, mob.y, mob.z))
 | 
				
			||||||
 | 
					            # check distance number of blocks above, close enough?
 | 
				
			||||||
 | 
					            if not self.check_air_column(pos, distance):
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            result.append(mob)
 | 
				
			||||||
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Game:
 | 
					class Game:
 | 
				
			||||||
    def __init__(self, global_state):
 | 
					    def __init__(self, global_state):
 | 
				
			||||||
@@ -365,7 +401,7 @@ class Game:
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if text == 'zzz':
 | 
					        if text.startswith('zzz'):
 | 
				
			||||||
            text = '!zzz'
 | 
					            text = '!zzz'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if text.startswith('! '):
 | 
					        if text.startswith('! '):
 | 
				
			||||||
@@ -382,166 +418,205 @@ class Game:
 | 
				
			|||||||
            command = text
 | 
					            command = text
 | 
				
			||||||
            data = None
 | 
					            data = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if command == 'ping':
 | 
					        try:
 | 
				
			||||||
            reply = 'pong'
 | 
					            if command == 'ping':
 | 
				
			||||||
 | 
					                reply = 'pong'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if command == 'echo' and data:
 | 
					            if command == 'echo' and data:
 | 
				
			||||||
            reply = data
 | 
					                reply = data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if command == 'respawn':
 | 
					            if command == 'respawn':
 | 
				
			||||||
            packet = serverbound.play.ClientStatusPacket()
 | 
					                packet = serverbound.play.ClientStatusPacket()
 | 
				
			||||||
            packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN
 | 
					                packet.action_id = serverbound.play.ClientStatusPacket.RESPAWN
 | 
				
			||||||
            self.g.connection.write_packet(packet)
 | 
					                self.g.connection.write_packet(packet)
 | 
				
			||||||
            reply = 'ok'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'pos':
 | 
					 | 
				
			||||||
            reply = str(utils.pint(self.g.pos))[1:-1]
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'afk':
 | 
					 | 
				
			||||||
            reply = '/afk'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'error':
 | 
					 | 
				
			||||||
            reply = 'ok'
 | 
					 | 
				
			||||||
            raise
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'break':
 | 
					 | 
				
			||||||
            self.break_block(blocks.TEST_BLOCK)
 | 
					 | 
				
			||||||
            reply = 'ok'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'gather' and data:
 | 
					 | 
				
			||||||
            if data == 'wood':
 | 
					 | 
				
			||||||
                self.g.job.state = self.g.job.gather_wood
 | 
					 | 
				
			||||||
                reply = 'ok'
 | 
					 | 
				
			||||||
            elif data == 'sand':
 | 
					 | 
				
			||||||
                self.g.job.state = self.g.job.gather_sand
 | 
					 | 
				
			||||||
                reply = 'ok'
 | 
					                reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if reply:
 | 
					            if command == 'pos':
 | 
				
			||||||
                for i in self.g.inv.values():
 | 
					                reply = str(utils.pint(self.g.pos))[1:-1]
 | 
				
			||||||
                    print(i.item_id)
 | 
					 | 
				
			||||||
                    if i.item_id in items.BED_IDS:
 | 
					 | 
				
			||||||
                        break
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    reply += ', I need a bed'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if command == 'farm' and data:
 | 
					            if command == 'afk':
 | 
				
			||||||
            if data == 'wood':
 | 
					 | 
				
			||||||
                self.g.job.state = self.g.job.farm_wood
 | 
					 | 
				
			||||||
                reply = 'ok'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if reply:
 | 
					 | 
				
			||||||
                for i in self.g.inv.values():
 | 
					 | 
				
			||||||
                    print(i.item_id)
 | 
					 | 
				
			||||||
                    if i.item_id in items.BED_IDS:
 | 
					 | 
				
			||||||
                        break
 | 
					 | 
				
			||||||
                else:
 | 
					 | 
				
			||||||
                    reply += ', I need a bed'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'stop':
 | 
					 | 
				
			||||||
            self.g.job.stop()
 | 
					 | 
				
			||||||
            self.g.path = []
 | 
					 | 
				
			||||||
            self.g.look_at = None
 | 
					 | 
				
			||||||
            reply = 'ok'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'inv':
 | 
					 | 
				
			||||||
            inv_list = []
 | 
					 | 
				
			||||||
            for i in self.g.inv.values():
 | 
					 | 
				
			||||||
                if i.present:
 | 
					 | 
				
			||||||
                    inv_list.append('{}:{} x {}'.format(items.ITEM_NAMES[i.item_id], str(i.item_id), i.item_count))
 | 
					 | 
				
			||||||
            inv_list.sort()
 | 
					 | 
				
			||||||
            result = '\n'.join(inv_list)
 | 
					 | 
				
			||||||
            print(result or 'Empty')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'drop':
 | 
					 | 
				
			||||||
            self.drop_stack()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'time':
 | 
					 | 
				
			||||||
            reply = str(self.g.time)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'select' and data:
 | 
					 | 
				
			||||||
            item = int(data)
 | 
					 | 
				
			||||||
            if self.select_item([item]):
 | 
					 | 
				
			||||||
                reply = 'ok'
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                reply = 'not found'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'dump' and data:
 | 
					 | 
				
			||||||
            item = int(data)
 | 
					 | 
				
			||||||
            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)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'close':
 | 
					 | 
				
			||||||
            if self.g.window:
 | 
					 | 
				
			||||||
                self.close_window()
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                reply = 'nothing open'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'click' and data:
 | 
					 | 
				
			||||||
            if self.g.window:
 | 
					 | 
				
			||||||
                slot, button, mode = [int(x) for x in data.split(' ')]
 | 
					 | 
				
			||||||
                try:
 | 
					 | 
				
			||||||
                    item = self.g.window.contents[slot]
 | 
					 | 
				
			||||||
                except KeyError:
 | 
					 | 
				
			||||||
                    item = Slot(present=False, item_id=None, item_count=None, nbt=None)
 | 
					 | 
				
			||||||
                print(item)
 | 
					 | 
				
			||||||
                self.click_window(slot, button, mode, item)
 | 
					 | 
				
			||||||
            else:
 | 
					 | 
				
			||||||
                reply = 'nothing open'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'loaded':
 | 
					 | 
				
			||||||
            reply = str(self.g.chunks.get_loaded_area())
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'gapple':
 | 
					 | 
				
			||||||
            self.g.job.state = self.g.job.find_gapple
 | 
					 | 
				
			||||||
            if data:
 | 
					 | 
				
			||||||
                self.g.job.find_gapple_states.count = int(data)
 | 
					 | 
				
			||||||
            reply = 'ok'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'objects':
 | 
					 | 
				
			||||||
            for k, v in self.g.objects.items():
 | 
					 | 
				
			||||||
                if data and v.item_id != int(data): continue
 | 
					 | 
				
			||||||
                print(str(k) + ':', v)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'cache':
 | 
					 | 
				
			||||||
            self.g.job.state = self.g.job.cache_items
 | 
					 | 
				
			||||||
            self.g.job.cache_items_states.minimum = 0
 | 
					 | 
				
			||||||
            self.g.job.cache_items_states.silent = True
 | 
					 | 
				
			||||||
            reply = 'ok'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'spiral' and data:
 | 
					 | 
				
			||||||
            for i in range(int(data)):
 | 
					 | 
				
			||||||
                print(utils.spiral(i))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'sand_slice':
 | 
					 | 
				
			||||||
            try:
 | 
					 | 
				
			||||||
                result = self.g.world.find_sand_slice(utils.pint(self.g.pos), 50)
 | 
					 | 
				
			||||||
                reply = str(result)
 | 
					 | 
				
			||||||
            except:
 | 
					 | 
				
			||||||
                import traceback
 | 
					 | 
				
			||||||
                print(traceback.format_exc())
 | 
					 | 
				
			||||||
                reply = 'error'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if command == 'zzz':
 | 
					 | 
				
			||||||
            if not self.g.afk:
 | 
					 | 
				
			||||||
                reply = '/afk'
 | 
					                reply = '/afk'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if command == 'print':
 | 
					            if command == 'error':
 | 
				
			||||||
            try:
 | 
					                reply = 'ok'
 | 
				
			||||||
 | 
					                raise
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'break':
 | 
				
			||||||
 | 
					                self.break_block(blocks.TEST_BLOCK)
 | 
				
			||||||
 | 
					                reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'gather' and data:
 | 
				
			||||||
 | 
					                if data == 'wood':
 | 
				
			||||||
 | 
					                    self.g.job.state = self.g.job.gather_wood
 | 
				
			||||||
 | 
					                    reply = 'ok'
 | 
				
			||||||
 | 
					                elif data == 'sand':
 | 
				
			||||||
 | 
					                    self.g.job.state = self.g.job.gather_sand
 | 
				
			||||||
 | 
					                    reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if reply:
 | 
				
			||||||
 | 
					                    for i in self.g.inv.values():
 | 
				
			||||||
 | 
					                        print(i.item_id)
 | 
				
			||||||
 | 
					                        if i.item_id in items.BED_IDS:
 | 
				
			||||||
 | 
					                            break
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        reply += ', I need a bed'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'farm' and data:
 | 
				
			||||||
 | 
					                if data == 'wood':
 | 
				
			||||||
 | 
					                    self.g.job.state = self.g.job.farm_wood
 | 
				
			||||||
 | 
					                    reply = 'ok'
 | 
				
			||||||
 | 
					                elif data == 'sand':
 | 
				
			||||||
 | 
					                    self.g.job.state = self.g.job.farm_sand
 | 
				
			||||||
 | 
					                    reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if reply:
 | 
				
			||||||
 | 
					                    for i in self.g.inv.values():
 | 
				
			||||||
 | 
					                        if i.item_id in items.BED_IDS:
 | 
				
			||||||
 | 
					                            break
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        reply += ', I need a bed'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'stop':
 | 
				
			||||||
 | 
					                self.g.job.stop()
 | 
				
			||||||
 | 
					                self.g.path = []
 | 
				
			||||||
 | 
					                self.g.look_at = None
 | 
				
			||||||
 | 
					                reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'inv':
 | 
				
			||||||
 | 
					                inv_list = []
 | 
				
			||||||
 | 
					                for i in self.g.inv.values():
 | 
				
			||||||
 | 
					                    if i.present:
 | 
				
			||||||
 | 
					                        inv_list.append('{}:{} x {}'.format(items.ITEM_NAMES[i.item_id], str(i.item_id), i.item_count))
 | 
				
			||||||
 | 
					                inv_list.sort()
 | 
				
			||||||
 | 
					                result = '\n'.join(inv_list)
 | 
				
			||||||
 | 
					                print(result or 'Empty')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'drop':
 | 
				
			||||||
 | 
					                self.drop_stack()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'time':
 | 
				
			||||||
 | 
					                reply = str(self.g.time)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'select' and data:
 | 
				
			||||||
 | 
					                item = int(data)
 | 
				
			||||||
 | 
					                if self.select_item([item]):
 | 
				
			||||||
 | 
					                    reply = 'ok'
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    reply = 'not found'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'dump' and data:
 | 
				
			||||||
 | 
					                item = int(data)
 | 
				
			||||||
 | 
					                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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'close':
 | 
				
			||||||
 | 
					                if self.g.window:
 | 
				
			||||||
 | 
					                    self.close_window()
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    reply = 'nothing open'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'click' and data:
 | 
				
			||||||
 | 
					                if self.g.window:
 | 
				
			||||||
 | 
					                    slot, button, mode = [int(x) for x in data.split(' ')]
 | 
				
			||||||
 | 
					                    try:
 | 
				
			||||||
 | 
					                        item = self.g.window.contents[slot]
 | 
				
			||||||
 | 
					                    except KeyError:
 | 
				
			||||||
 | 
					                        item = Slot(present=False, item_id=None, item_count=None, nbt=None)
 | 
				
			||||||
 | 
					                    print(item)
 | 
				
			||||||
 | 
					                    self.click_window(slot, button, mode, item)
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    reply = 'nothing open'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'loaded':
 | 
				
			||||||
 | 
					                reply = str(self.g.chunks.get_loaded_area())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'gapple':
 | 
				
			||||||
 | 
					                self.g.job.state = self.g.job.find_gapple
 | 
				
			||||||
 | 
					                if data:
 | 
				
			||||||
 | 
					                    self.g.job.find_gapple_states.count = int(data)
 | 
				
			||||||
 | 
					                reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'objects':
 | 
				
			||||||
 | 
					                if data == 'clear':
 | 
				
			||||||
 | 
					                    self.g.objects = {}
 | 
				
			||||||
 | 
					                    reply = 'ok'
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    for k, v in self.g.objects.items():
 | 
				
			||||||
 | 
					                        if data and v.item_id != int(data): continue
 | 
				
			||||||
 | 
					                        print(str(k) + ':', v, items.ITEM_NAMES[v.item_id])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'mobs':
 | 
				
			||||||
 | 
					                if data == 'clear':
 | 
				
			||||||
 | 
					                    self.g.mobs = {}
 | 
				
			||||||
 | 
					                    reply = 'ok'
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    all_mobs = sorted(list(self.g.mobs.items()), key=lambda x: x[1].type)
 | 
				
			||||||
 | 
					                    for k, v in all_mobs:
 | 
				
			||||||
 | 
					                        if data and v.type != int(data): continue
 | 
				
			||||||
 | 
					                        print(str(k) + ':', v, mobs.MOB_NAMES[v.type])
 | 
				
			||||||
 | 
					                    reply = str(len(all_mobs)) + ' mobs'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'monsters':
 | 
				
			||||||
 | 
					                monsters = sorted(list(self.g.mobs.items()), key=lambda x: x[1].type)
 | 
				
			||||||
 | 
					                count = 0
 | 
				
			||||||
 | 
					                for k, v in monsters:
 | 
				
			||||||
 | 
					                    if v.type not in mobs.EVIL_IDS: continue
 | 
				
			||||||
 | 
					                    if data and v.type != int(data): continue
 | 
				
			||||||
 | 
					                    count += 1
 | 
				
			||||||
 | 
					                    print(str(k) + ':', v, mobs.MOB_NAMES[v.type])
 | 
				
			||||||
 | 
					                reply = str(count) + ' monsters'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'threats':
 | 
				
			||||||
 | 
					                distance = int(data) if data else 20
 | 
				
			||||||
 | 
					                p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					                threats = self.g.world.find_threats(p, distance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for t in threats:
 | 
				
			||||||
 | 
					                    print(str(t.entity_id) + ':', t, mobs.MOB_NAMES[t.type])
 | 
				
			||||||
 | 
					                reply = str(len(threats)) + ' threats'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'cache':
 | 
				
			||||||
 | 
					                self.g.job.state = self.g.job.cache_items
 | 
				
			||||||
 | 
					                self.g.job.cache_items_states.minimum = 0
 | 
				
			||||||
 | 
					                self.g.job.cache_items_states.silent = True
 | 
				
			||||||
 | 
					                reply = 'ok'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'spiral' and data:
 | 
				
			||||||
 | 
					                for i in range(int(data)):
 | 
				
			||||||
 | 
					                    print(utils.spiral(i))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'sand_slice':
 | 
				
			||||||
 | 
					                result = self.g.world.find_sand_slice(utils.pint(self.g.pos), 50)
 | 
				
			||||||
 | 
					                reply = str(result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'zzz':
 | 
				
			||||||
 | 
					                if not self.g.afk:
 | 
				
			||||||
 | 
					                    if self.g.path:
 | 
				
			||||||
 | 
					                        travel_time = int(len(self.g.path) * 0.4) + 2
 | 
				
			||||||
 | 
					                        reply = 'give me ' + str(travel_time) + ' secs, moving'
 | 
				
			||||||
 | 
					                        self.g.queue_afk = True
 | 
				
			||||||
 | 
					                    else:
 | 
				
			||||||
 | 
					                        reply = '/afk'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if command == 'print' and sender == 'tanner6':
 | 
				
			||||||
 | 
					                data = data.replace('^', '.')
 | 
				
			||||||
                reply = str(eval(data))
 | 
					                reply = str(eval(data))
 | 
				
			||||||
            except BaseException as e:
 | 
					
 | 
				
			||||||
                import traceback
 | 
					        except BaseException as e:
 | 
				
			||||||
                print(traceback.format_exc())
 | 
					            import traceback
 | 
				
			||||||
                reply = 'Error: {} - {}\n'.format(e.__class__.__name__, e)
 | 
					            print(traceback.format_exc())
 | 
				
			||||||
 | 
					            reply = 'Error: {} - {}\n'.format(e.__class__.__name__, e)
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if reply:
 | 
					        if reply:
 | 
				
			||||||
            print(reply)
 | 
					            print(reply)
 | 
				
			||||||
@@ -567,8 +642,8 @@ class Game:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def break_block(self, location):
 | 
					    def break_block(self, location):
 | 
				
			||||||
        p = utils.pint(self.g.pos)
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
        if utils.phyp(p, location) > blocks.BREAK_DISTANCE:
 | 
					        #if utils.phyp(p, location) > blocks.BREAK_DISTANCE + 1:
 | 
				
			||||||
            return False
 | 
					        #    return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bid = self.g.chunks.get_block_at(*location)
 | 
					        bid = self.g.chunks.get_block_at(*location)
 | 
				
			||||||
        if bid == 0:
 | 
					        if bid == 0:
 | 
				
			||||||
@@ -596,6 +671,7 @@ class Game:
 | 
				
			|||||||
            self.g.breaking = None
 | 
					            self.g.breaking = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_break_animation(self, packet):
 | 
					    def handle_break_animation(self, packet):
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
        print(packet)
 | 
					        print(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_break_ack(self, packet):
 | 
					    def handle_break_ack(self, packet):
 | 
				
			||||||
@@ -761,22 +837,28 @@ class Game:
 | 
				
			|||||||
                obj.item_count = entry.value.item_count
 | 
					                obj.item_count = entry.value.item_count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_spawn_living(self, packet):
 | 
					    def handle_spawn_living(self, packet):
 | 
				
			||||||
        print(packet)
 | 
					        self.g.mobs[packet.entity_id] = Munch(
 | 
				
			||||||
        return
 | 
					            entity_id=packet.entity_id,
 | 
				
			||||||
 | 
					            entity_uuid=packet.entity_uuid,
 | 
				
			||||||
 | 
					            type=packet.type,
 | 
				
			||||||
 | 
					            x=packet.x,
 | 
				
			||||||
 | 
					            y=packet.y,
 | 
				
			||||||
 | 
					            z=packet.z,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_entity_position(self, packet):
 | 
					    def handle_entity_position(self, packet):
 | 
				
			||||||
        obj = self.g.objects.get(packet.entity_id, None)
 | 
					        mob = self.g.mobs.get(packet.entity_id, None)
 | 
				
			||||||
        if obj:
 | 
					        if mob:
 | 
				
			||||||
            pass
 | 
					            mob.x += packet.delta_x / 4096.0
 | 
				
			||||||
            #obj.x += packet.delta_x
 | 
					            mob.y += packet.delta_y / 4096.0
 | 
				
			||||||
            #obj.y += packet.delta_y
 | 
					            mob.z += packet.delta_z / 4096.0
 | 
				
			||||||
            #obj.z += packet.delta_z
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_entity_position_rotation(self, packet):
 | 
					    def handle_entity_position_rotation(self, packet):
 | 
				
			||||||
        obj = self.g.objects.get(packet.entity_id, None)
 | 
					        mob = self.g.mobs.get(packet.entity_id, None)
 | 
				
			||||||
        if obj:
 | 
					        if mob:
 | 
				
			||||||
            print('object rotation found:', packet)
 | 
					            mob.x += packet.delta_x / 4096.0
 | 
				
			||||||
            raise
 | 
					            mob.y += packet.delta_y / 4096.0
 | 
				
			||||||
 | 
					            mob.z += packet.delta_z / 4096.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def handle_entity_velocity(self, packet):
 | 
					    def handle_entity_velocity(self, packet):
 | 
				
			||||||
        obj = self.g.objects.get(packet.entity_id, None)
 | 
					        obj = self.g.objects.get(packet.entity_id, None)
 | 
				
			||||||
@@ -790,6 +872,16 @@ class Game:
 | 
				
			|||||||
        for eid in packet.entity_ids:
 | 
					        for eid in packet.entity_ids:
 | 
				
			||||||
            if eid in self.g.objects:
 | 
					            if eid in self.g.objects:
 | 
				
			||||||
                del self.g.objects[eid]
 | 
					                del self.g.objects[eid]
 | 
				
			||||||
 | 
					            if eid in self.g.mobs:
 | 
				
			||||||
 | 
					                del self.g.mobs[eid]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def leave_bed(self):
 | 
				
			||||||
 | 
					        packet = EntityActionPacket()
 | 
				
			||||||
 | 
					        packet.entity_id = self.g.eid
 | 
				
			||||||
 | 
					        packet.action_id = 2
 | 
				
			||||||
 | 
					        packet.jump_boost = 0
 | 
				
			||||||
 | 
					        self.g.connection.write_packet(packet)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def tick(self):
 | 
					    def tick(self):
 | 
				
			||||||
        if self.g.breaking:
 | 
					        if self.g.breaking:
 | 
				
			||||||
@@ -805,6 +897,10 @@ class Game:
 | 
				
			|||||||
            else:
 | 
					            else:
 | 
				
			||||||
                self.g.dumping = None
 | 
					                self.g.dumping = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if not len(self.g.path):
 | 
					        if not self.g.path:
 | 
				
			||||||
            self.g.correction_count = 0
 | 
					            self.g.correction_count = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if self.g.queue_afk:
 | 
				
			||||||
 | 
					                self.g.chat.send('/afk')
 | 
				
			||||||
 | 
					                self.g.queue_afk = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										153
									
								
								jobs.py
									
									
									
									
									
								
							
							
						
						
									
										153
									
								
								jobs.py
									
									
									
									
									
								
							@@ -20,6 +20,8 @@ import items
 | 
				
			|||||||
importlib.reload(items)
 | 
					importlib.reload(items)
 | 
				
			||||||
import data
 | 
					import data
 | 
				
			||||||
importlib.reload(data)
 | 
					importlib.reload(data)
 | 
				
			||||||
 | 
					import mobs
 | 
				
			||||||
 | 
					importlib.reload(mobs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FindGappleStates:
 | 
					class FindGappleStates:
 | 
				
			||||||
@@ -308,12 +310,13 @@ class GatherSandStates:
 | 
				
			|||||||
        w = self.g.world
 | 
					        w = self.g.world
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        print('using origin', self.origin)
 | 
					        print('using origin', self.origin)
 | 
				
			||||||
        s = w.find_sand_slice(self.origin, 50, self.bad_slices)
 | 
					        start = time.time()
 | 
				
			||||||
        print('Found slice:', s)
 | 
					        self.prev_layer, s = w.find_sand_slice(self.origin, 200, 10, self.bad_slices, self.prev_layer)
 | 
				
			||||||
 | 
					        print('Found slice:', s, 'in', time.time() - start, 'seconds')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if s:
 | 
					        if s:
 | 
				
			||||||
            self.slice = s
 | 
					            self.slice = s
 | 
				
			||||||
            #self.bad_slices.append(s)
 | 
					            self.bad_slices.append(s)
 | 
				
			||||||
            self.state = self.find_new_sand
 | 
					            self.state = self.find_new_sand
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            print('No slices remaining.')
 | 
					            print('No slices remaining.')
 | 
				
			||||||
@@ -323,24 +326,23 @@ class GatherSandStates:
 | 
				
			|||||||
        print('Finding new sand...')
 | 
					        print('Finding new sand...')
 | 
				
			||||||
        w = self.g.world
 | 
					        w = self.g.world
 | 
				
			||||||
        p = utils.pint(self.g.pos)
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					        head = utils.padd(p, path.BLOCK_ABOVE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        sand = w.find_sand(self.slice, 2, p)
 | 
					        for sand in w.find_sand(self.slice, 2, p):
 | 
				
			||||||
        print('Found sand:', sand)
 | 
					            if sand not in self.bad_sand:
 | 
				
			||||||
 | 
					                print('Found sand:', sand)
 | 
				
			||||||
        if not len(sand):
 | 
					                break
 | 
				
			||||||
 | 
					        else: # for
 | 
				
			||||||
 | 
					            print('No good sands left, aborting.')
 | 
				
			||||||
            self.state = self.cleanup
 | 
					            self.state = self.cleanup
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        for check in sand:
 | 
					        self.sand = sand
 | 
				
			||||||
            if check in self.bad_sand:
 | 
					 | 
				
			||||||
                continue
 | 
					 | 
				
			||||||
            self.sand = check
 | 
					 | 
				
			||||||
            break
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if utils.phyp(p, self.sand) > blocks.BREAK_DISTANCE:
 | 
					        if utils.phyp(head, self.sand) < blocks.BREAK_DISTANCE:
 | 
				
			||||||
            self.state = self.nav_to_sand
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            self.state = self.dig_sand
 | 
					            self.state = self.dig_sand
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.state = self.nav_to_sand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def nav_to_sand(self):
 | 
					    def nav_to_sand(self):
 | 
				
			||||||
        w = self.g.world
 | 
					        w = self.g.world
 | 
				
			||||||
@@ -356,6 +358,7 @@ class GatherSandStates:
 | 
				
			|||||||
            self.g.path = navpath[:-1]
 | 
					            self.g.path = navpath[:-1]
 | 
				
			||||||
            self.state = self.going_to_sand
 | 
					            self.state = self.going_to_sand
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
 | 
					            print('Cant get to that sand')
 | 
				
			||||||
            self.bad_sand.append(self.sand)
 | 
					            self.bad_sand.append(self.sand)
 | 
				
			||||||
            self.state = self.find_new_sand
 | 
					            self.state = self.find_new_sand
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -387,8 +390,10 @@ class GatherSandStates:
 | 
				
			|||||||
        self.state = self.idle
 | 
					        self.state = self.idle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.origin = utils.pint(self.g.pos)
 | 
					        self.origin = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					        self.origin = (2019, 64, 238)
 | 
				
			||||||
        self.slice = None
 | 
					        self.slice = None
 | 
				
			||||||
        self.bad_slices = []
 | 
					        self.bad_slices = []
 | 
				
			||||||
 | 
					        self.prev_layer = 0
 | 
				
			||||||
        self.sand = None
 | 
					        self.sand = None
 | 
				
			||||||
        self.bad_sand = []
 | 
					        self.bad_sand = []
 | 
				
			||||||
        self.wait_time = 0
 | 
					        self.wait_time = 0
 | 
				
			||||||
@@ -519,7 +524,7 @@ class SleepWithBedStates:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    def going_to_area(self):
 | 
					    def going_to_area(self):
 | 
				
			||||||
        if utils.pint(self.g.pos) == self.opening:
 | 
					        if utils.pint(self.g.pos) == self.opening:
 | 
				
			||||||
            self.g.look_at = self.area
 | 
					            self.g.look_at = utils.padd(self.area, path.BLOCK_BELOW)
 | 
				
			||||||
            self.state = self.place_bed
 | 
					            self.state = self.place_bed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def place_bed(self):
 | 
					    def place_bed(self):
 | 
				
			||||||
@@ -535,8 +540,16 @@ class SleepWithBedStates:
 | 
				
			|||||||
            self.state = self.sleep_bed
 | 
					            self.state = self.sleep_bed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def sleep_bed(self):
 | 
					    def sleep_bed(self):
 | 
				
			||||||
        if self.g.time < 100:
 | 
					        w = self.g.world
 | 
				
			||||||
            print('Woke up')
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        threats = w.find_threats(p, 30)
 | 
				
			||||||
 | 
					        if threats:
 | 
				
			||||||
 | 
					            print('Waking up due to threats')
 | 
				
			||||||
 | 
					            self.g.game.leave_bed()
 | 
				
			||||||
 | 
					            self.state = self.break_bed
 | 
				
			||||||
 | 
					        elif self.g.time < 100:
 | 
				
			||||||
 | 
					            print('Woke up time')
 | 
				
			||||||
            self.state = self.break_bed
 | 
					            self.state = self.break_bed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def break_bed(self):
 | 
					    def break_bed(self):
 | 
				
			||||||
@@ -1004,6 +1017,96 @@ class GrabSaplingStates:
 | 
				
			|||||||
        self.state()
 | 
					        self.state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CheckThreatsStates:
 | 
				
			||||||
 | 
					    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, 40)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if threats:
 | 
				
			||||||
 | 
					            print('Found', len(threats), 'threats, fleeing')
 | 
				
			||||||
 | 
					            self.state = self.find_safety
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            print('Aborting, no threats')
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def find_safety(self):
 | 
				
			||||||
 | 
					        w = self.g.world
 | 
				
			||||||
 | 
					        p = utils.pint(self.g.pos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        safety = w.find_blocks_indexed(p, [blocks.EMERALD_BLOCK])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not safety:
 | 
				
			||||||
 | 
					            print('No emerald blocks found, aborting')
 | 
				
			||||||
 | 
					            self.state = self.cleanup
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        safety.sort(key=lambda s: utils.phyp(p, s))
 | 
				
			||||||
 | 
					        print('Found emerald blocks:', safety)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for s in safety:
 | 
				
			||||||
 | 
					            s = utils.padd(s, path.BLOCK_ABOVE)
 | 
				
			||||||
 | 
					            navpath = w.path_to_place(p, s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if navpath:
 | 
				
			||||||
 | 
					                self.g.path = navpath
 | 
				
			||||||
 | 
					                self.state = self.going_to_safety
 | 
				
			||||||
 | 
					                self.safety = s
 | 
				
			||||||
 | 
					                print('Going to safety', self.safety)
 | 
				
			||||||
 | 
					                return
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                print('Cant get to safety', self.safety)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        print('Cant get to safety, aborting')
 | 
				
			||||||
 | 
					        self.state = self.cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def going_to_safety(self):
 | 
				
			||||||
 | 
					        if utils.pint(self.g.pos) == self.safety:
 | 
				
			||||||
 | 
					            print('At safety spot, waiting to be moved')
 | 
				
			||||||
 | 
					            self.state = self.wait_for_move
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self):
 | 
				
			||||||
 | 
					        self.state()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class JobStates:
 | 
					class JobStates:
 | 
				
			||||||
    def idle(self):
 | 
					    def idle(self):
 | 
				
			||||||
        return []
 | 
					        return []
 | 
				
			||||||
@@ -1018,6 +1121,7 @@ class JobStates:
 | 
				
			|||||||
        self.clear_leaves_states = ClearLeavesStates(self.g)
 | 
					        self.clear_leaves_states = ClearLeavesStates(self.g)
 | 
				
			||||||
        self.grab_sapling_states = GrabSaplingStates(self.g)
 | 
					        self.grab_sapling_states = GrabSaplingStates(self.g)
 | 
				
			||||||
        self.grab_sand_states = GrabSandStates(self.g)
 | 
					        self.grab_sand_states = GrabSandStates(self.g)
 | 
				
			||||||
 | 
					        self.check_threats_states = CheckThreatsStates(self.g)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def run_machines(self, machines):
 | 
					    def run_machines(self, machines):
 | 
				
			||||||
        for m in machines:
 | 
					        for m in machines:
 | 
				
			||||||
@@ -1040,6 +1144,18 @@ class JobStates:
 | 
				
			|||||||
        ]
 | 
					        ]
 | 
				
			||||||
        return machines
 | 
					        return machines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def farm_sand(self):
 | 
				
			||||||
 | 
					        machines = [
 | 
				
			||||||
 | 
					            self.check_threats_states,
 | 
				
			||||||
 | 
					            self.gather_sand_states,
 | 
				
			||||||
 | 
					            self.grab_sand_states,
 | 
				
			||||||
 | 
					            self.cache_items_states,
 | 
				
			||||||
 | 
					            self.sleep_with_bed_states,
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					        self.sleep_with_bed_states.silent = True
 | 
				
			||||||
 | 
					        self.cache_items_states.silent = True
 | 
				
			||||||
 | 
					        return machines
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def cache_items(self):
 | 
					    def cache_items(self):
 | 
				
			||||||
        machines = [
 | 
					        machines = [
 | 
				
			||||||
            self.cache_items_states,
 | 
					            self.cache_items_states,
 | 
				
			||||||
@@ -1070,7 +1186,6 @@ class JobStates:
 | 
				
			|||||||
            self.sleep_with_bed_states,
 | 
					            self.sleep_with_bed_states,
 | 
				
			||||||
            self.cache_items_states,
 | 
					            self.cache_items_states,
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
 | 
					 | 
				
			||||||
        self.sleep_with_bed_states.silent = True
 | 
					        self.sleep_with_bed_states.silent = True
 | 
				
			||||||
        self.cache_items_states.silent = True
 | 
					        self.cache_items_states.silent = True
 | 
				
			||||||
        return machines
 | 
					        return machines
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										50
									
								
								mobs.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								mobs.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
				
			|||||||
 | 
					import json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					with open('mcdata/registries.json') as f:
 | 
				
			||||||
 | 
					    MOBS = json.load(f)['minecraft:entity_type']['entries']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EVIL = [
 | 
				
			||||||
 | 
					    'blaze',
 | 
				
			||||||
 | 
					    'cave_spider',
 | 
				
			||||||
 | 
					    'creeper',
 | 
				
			||||||
 | 
					    'drowned',
 | 
				
			||||||
 | 
					    'elder_guardian',
 | 
				
			||||||
 | 
					    'ender_dragon',
 | 
				
			||||||
 | 
					    'enderman',
 | 
				
			||||||
 | 
					    'endermite',
 | 
				
			||||||
 | 
					    'evoker',
 | 
				
			||||||
 | 
					    'ghast',
 | 
				
			||||||
 | 
					    'giant',
 | 
				
			||||||
 | 
					    'guardian',
 | 
				
			||||||
 | 
					    'hoglin',
 | 
				
			||||||
 | 
					    'husk',
 | 
				
			||||||
 | 
					    'illusioner',
 | 
				
			||||||
 | 
					    'magma_cube',
 | 
				
			||||||
 | 
					    'phantom',
 | 
				
			||||||
 | 
					    'piglin',
 | 
				
			||||||
 | 
					    'piglin_brute',
 | 
				
			||||||
 | 
					    'pillager',
 | 
				
			||||||
 | 
					    'ravager',
 | 
				
			||||||
 | 
					    'shulker',
 | 
				
			||||||
 | 
					    'silverfish',
 | 
				
			||||||
 | 
					    'skeleton',
 | 
				
			||||||
 | 
					    'skeleton_horse',
 | 
				
			||||||
 | 
					    'slime',
 | 
				
			||||||
 | 
					    'spider',
 | 
				
			||||||
 | 
					    'stray',
 | 
				
			||||||
 | 
					    'vex',
 | 
				
			||||||
 | 
					    'vindicator',
 | 
				
			||||||
 | 
					    'witch',
 | 
				
			||||||
 | 
					    'wither',
 | 
				
			||||||
 | 
					    'zoglin',
 | 
				
			||||||
 | 
					    'zombie',
 | 
				
			||||||
 | 
					    'zombie_villager',
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EVIL_IDS = set()
 | 
				
			||||||
 | 
					for mob_name in EVIL:
 | 
				
			||||||
 | 
					    EVIL_IDS.add(MOBS['minecraft:'+mob_name]['protocol_id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					MOB_NAMES = {}
 | 
				
			||||||
 | 
					for mob_name, mob in MOBS.items():
 | 
				
			||||||
 | 
					    MOB_NAMES[MOBS[mob_name]['protocol_id']] = mob_name.replace('minecraft:', '')
 | 
				
			||||||
@@ -23,6 +23,7 @@ def get_packets(old_get_packets):
 | 
				
			|||||||
        mc_packets.add(packets.SpawnLivingEntityPacket)
 | 
					        mc_packets.add(packets.SpawnLivingEntityPacket)
 | 
				
			||||||
        mc_packets.add(packets.EntityPositionRotationPacket)
 | 
					        mc_packets.add(packets.EntityPositionRotationPacket)
 | 
				
			||||||
        mc_packets.add(packets.DestroyEntitiesPacket)
 | 
					        mc_packets.add(packets.DestroyEntitiesPacket)
 | 
				
			||||||
 | 
					        mc_packets.add(packets.EntityActionPacket)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return mc_packets
 | 
					        return mc_packets
 | 
				
			||||||
    return lambda x: wrapper(old_get_packets, x)
 | 
					    return lambda x: wrapper(old_get_packets, x)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -361,3 +361,16 @@ class DestroyEntitiesPacket(Packet):
 | 
				
			|||||||
        for _ in range(self.count):
 | 
					        for _ in range(self.count):
 | 
				
			||||||
            eid = VarInt.read(file_object)
 | 
					            eid = VarInt.read(file_object)
 | 
				
			||||||
            self.entity_ids.append(eid)
 | 
					            self.entity_ids.append(eid)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class EntityActionPacket(Packet):
 | 
				
			||||||
 | 
					    # Sent by the client when it performs an action
 | 
				
			||||||
 | 
					    # https://wiki.vg/Protocol#Entity_Action
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    id = 0x1C
 | 
				
			||||||
 | 
					    packet_name = 'entity action'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    definition = [
 | 
				
			||||||
 | 
					        {'entity_id': VarInt},
 | 
				
			||||||
 | 
					        {'action_id': VarInt},
 | 
				
			||||||
 | 
					        {'jump_boost': VarInt},
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user