Port over MCWorld class
This commit is contained in:
		
							
								
								
									
										1
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								bot.py
									
									
									
									
									
								
							@@ -181,6 +181,7 @@ def bot(global_state):
 | 
			
		||||
    g.chat = ChatManager(g)
 | 
			
		||||
 | 
			
		||||
    g.game = game.Game(g)
 | 
			
		||||
    g.world = game.MCWorld(g)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        while not g.pos:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										157
									
								
								game.py
									
									
									
									
									
								
							
							
						
						
									
										157
									
								
								game.py
									
									
									
									
									
								
							@@ -1,6 +1,7 @@
 | 
			
		||||
import re
 | 
			
		||||
import time
 | 
			
		||||
import importlib
 | 
			
		||||
from math import hypot
 | 
			
		||||
 | 
			
		||||
from panda3d.core import LPoint3f
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +16,151 @@ importlib.reload(path)
 | 
			
		||||
import blocks
 | 
			
		||||
importlib.reload(blocks)
 | 
			
		||||
 | 
			
		||||
class MCWorld:
 | 
			
		||||
    def __init__(self, global_state):
 | 
			
		||||
        self.g = global_state
 | 
			
		||||
        self.l = self.g.local_state
 | 
			
		||||
 | 
			
		||||
    def block_at(self, x, y, z):
 | 
			
		||||
        return self.g.chunks.get_block_at(x, y, z)
 | 
			
		||||
 | 
			
		||||
    def find_blocks(self, center, distance, block_ids, limit=0):
 | 
			
		||||
        # search in a spiral from center to all blocks with ID
 | 
			
		||||
        result = []
 | 
			
		||||
        for n in count():
 | 
			
		||||
            offset = utils.spiral(n)
 | 
			
		||||
            check = utils.padd(center, offset)
 | 
			
		||||
            if self.block_at(*check) in block_ids:
 | 
			
		||||
                if hypot(*offset) < distance:
 | 
			
		||||
                    result.append(check)
 | 
			
		||||
            if limit and len(result) == limit:
 | 
			
		||||
                return result
 | 
			
		||||
            if offset[0] > distance:
 | 
			
		||||
                return result
 | 
			
		||||
 | 
			
		||||
    def find_trees(self, center, distance):
 | 
			
		||||
        logs = []
 | 
			
		||||
        for i in range(5):
 | 
			
		||||
            check = utils.padd(center, alternate(i, 3))
 | 
			
		||||
            logs.extend(self.find_blocks(check, distance, blocks.LOG_IDS, 50))
 | 
			
		||||
 | 
			
		||||
        trees = []
 | 
			
		||||
        for log in logs:
 | 
			
		||||
            # crawl to the bottom log
 | 
			
		||||
            while self.block_at(*utils.padd(log, path.BLOCK_BELOW)) in blocks.LOG_IDS:
 | 
			
		||||
                log = utils.padd(log, path.BLOCK_BELOW)
 | 
			
		||||
 | 
			
		||||
            # make sure we are on the ground
 | 
			
		||||
            if self.block_at(*utils.padd(log, path.BLOCK_BELOW)) in blocks.NON_SOLID_IDS:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            # crawl to the top log to count
 | 
			
		||||
            log_count = 1
 | 
			
		||||
            while self.block_at(*utils.padd(log, path.BLOCK_ABOVE)) in blocks.LOG_IDS:
 | 
			
		||||
                log = utils.padd(log, path.BLOCK_ABOVE)
 | 
			
		||||
                log_count += 1
 | 
			
		||||
 | 
			
		||||
            # make sure it's a good tree
 | 
			
		||||
            if self.block_at(*utils.padd(log, path.BLOCK_ABOVE)) in blocks.LEAF_IDS and log_count > 2:
 | 
			
		||||
                # crawl back to the bottom log
 | 
			
		||||
                while self.block_at(*utils.padd(log, path.BLOCK_BELOW)) in blocks.LOG_IDS:
 | 
			
		||||
                    log = utils.padd(log, path.BLOCK_BELOW)
 | 
			
		||||
                trees.append(log)
 | 
			
		||||
 | 
			
		||||
        trees.sort(key=lambda x: phyp(center, x))
 | 
			
		||||
        return trees
 | 
			
		||||
 | 
			
		||||
    def find_tree_openings(self, tree):
 | 
			
		||||
        # returns coords in a cardinal direction where we can stand by tree
 | 
			
		||||
        maze_solver = MazeSolver(self.g.chunks)
 | 
			
		||||
        result = []
 | 
			
		||||
 | 
			
		||||
        # TODO: make sure only non-solid and leaves between
 | 
			
		||||
        # make sure traversable too
 | 
			
		||||
 | 
			
		||||
        for distance in range(5):
 | 
			
		||||
            for direction in CHECK_DIRECTIONS:
 | 
			
		||||
                offset = pmul(direction, distance+1)
 | 
			
		||||
                if maze_solver.check_traverse(tree, offset):
 | 
			
		||||
                    result.append(utils.padd(tree, offset))
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def path_to_place(self, start, place):
 | 
			
		||||
        maze_solver = MazeSolver(self.g.chunks)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            s = maze_solver.astar(start, place)
 | 
			
		||||
            return list(s) if s else None
 | 
			
		||||
        except AStarTimeout:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
    def find_bed_areas(self, center, distance):
 | 
			
		||||
        air = []
 | 
			
		||||
        for i in range(5):
 | 
			
		||||
            check = utils.padd(center, alternate(i, 1))
 | 
			
		||||
            air.extend(self.find_blocks(check, distance, [0], 200))
 | 
			
		||||
 | 
			
		||||
        areas = []
 | 
			
		||||
        for a in air:
 | 
			
		||||
            # check for ground around the area
 | 
			
		||||
            if len(self.find_blocks(utils.padd(a, path.BLOCK_BELOW), 2, blocks.NON_SOLID_IDS, 9)):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            # check for air around the area
 | 
			
		||||
            if len(self.find_blocks(a, 2, [0], 9)) < 9:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            # check for air above the area
 | 
			
		||||
            if len(self.find_blocks(utils.padd(a, path.BLOCK_ABOVE), 2, [0], 9)) < 9:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            areas.append(a)
 | 
			
		||||
 | 
			
		||||
        areas.sort(key=lambda x: phyp(center, x))
 | 
			
		||||
        return areas
 | 
			
		||||
 | 
			
		||||
    def sand_adjacent_safe(self, sand):
 | 
			
		||||
        for direction in CHECK_DIRECTIONS:
 | 
			
		||||
            if self.block_at(*utils.padd(sand, direction)) in blocks.AVOID_IDS:
 | 
			
		||||
                return False
 | 
			
		||||
        return True
 | 
			
		||||
 | 
			
		||||
    def find_sand(self, center, distance, origin):
 | 
			
		||||
        sand = []
 | 
			
		||||
        for i in range(10):
 | 
			
		||||
            check = utils.padd(center, alternate(i, 1))
 | 
			
		||||
            sand.extend(self.find_blocks(check, distance, [66], 20))
 | 
			
		||||
 | 
			
		||||
        safe_sand = []
 | 
			
		||||
        for s in sand:
 | 
			
		||||
            # make sure it has solid below
 | 
			
		||||
            if self.block_at(*utils.padd(s, path.BLOCK_BELOW)) in blocks.NON_SOLID_IDS:
 | 
			
		||||
                continue
 | 
			
		||||
            # make sure it has solid two below - prevent hanging sand
 | 
			
		||||
            if self.block_at(*utils.padd(s, path.BLOCK_BELOW2)) in blocks.NON_SOLID_IDS:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            # and walkable air above
 | 
			
		||||
            if self.block_at(*utils.padd(s, path.BLOCK_ABOVE)) not in blocks.NON_SOLID_IDS:
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            if not self.sand_adjacent_safe(s):
 | 
			
		||||
                continue
 | 
			
		||||
 | 
			
		||||
            safe_sand.append(s)
 | 
			
		||||
 | 
			
		||||
        safe_sand.sort(key=lambda x: utils.phyp_bias(center, x, origin))
 | 
			
		||||
        return safe_sand
 | 
			
		||||
 | 
			
		||||
    def find_bed_openings(self, area):
 | 
			
		||||
        # returns coords in a cardinal direction where we can stand by bed
 | 
			
		||||
        result = []
 | 
			
		||||
 | 
			
		||||
        for direction in CHECK_DIRECTIONS:
 | 
			
		||||
            result.append(utils.padd(area, direction))
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Game:
 | 
			
		||||
    def __init__(self, global_state):
 | 
			
		||||
        self.g = global_state
 | 
			
		||||
@@ -164,6 +310,17 @@ class Game:
 | 
			
		||||
        packet.hand = packet.HAND_MAIN
 | 
			
		||||
        self.g.connection.write_packet(packet)
 | 
			
		||||
 | 
			
		||||
    def place_block(self, location, face):
 | 
			
		||||
        packet = serverbound.play.PlayerBlockPlacementPacket()
 | 
			
		||||
        packet.hand = 0
 | 
			
		||||
        packet.location = pos
 | 
			
		||||
        packet.face = face
 | 
			
		||||
        packet.x = 0.5
 | 
			
		||||
        packet.y = 0.5
 | 
			
		||||
        packet.z = 0.5
 | 
			
		||||
        packet.inside_block = False
 | 
			
		||||
        self.g.connection.write_packet(packet)
 | 
			
		||||
 | 
			
		||||
    def tick(self):
 | 
			
		||||
        if self.l.breaking:
 | 
			
		||||
            self.animate()
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										12
									
								
								path.py
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								path.py
									
									
									
									
									
								
							@@ -49,6 +49,18 @@ PARKOUR_SOUTH = (0, 0, +2)
 | 
			
		||||
PARKOUR_EAST = (+2, 0, 0)
 | 
			
		||||
PARKOUR_WEST = (-2, 0, 0)
 | 
			
		||||
 | 
			
		||||
CHECK_NORTH = (0, 0, -1)
 | 
			
		||||
CHECK_SOUTH = (0, 0, +1)
 | 
			
		||||
CHECK_EAST = (+1, 0, 0)
 | 
			
		||||
CHECK_WEST = (-1, 0, 0)
 | 
			
		||||
 | 
			
		||||
CHECK_DIRECTIONS = [
 | 
			
		||||
    CHECK_NORTH,
 | 
			
		||||
    CHECK_SOUTH,
 | 
			
		||||
    CHECK_EAST,
 | 
			
		||||
    CHECK_WEST,
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
TRAVERSE = [
 | 
			
		||||
    TRAVERSE_NORTH,
 | 
			
		||||
    TRAVERSE_SOUTH,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user