Begin villager trading job
This commit is contained in:
		
							
								
								
									
										9
									
								
								bot.py
									
									
									
									
									
								
							
							
						
						
									
										9
									
								
								bot.py
									
									
									
									
									
								
							@@ -205,7 +205,6 @@ def init(global_state):
 | 
			
		||||
    g.item_lock = False
 | 
			
		||||
    g.command_lock = False
 | 
			
		||||
 | 
			
		||||
    g.window = None
 | 
			
		||||
    g.trades = []
 | 
			
		||||
 | 
			
		||||
    g.job = jobs.JobStates(g)
 | 
			
		||||
@@ -252,6 +251,7 @@ def bot(global_state):
 | 
			
		||||
        print('Chunks loaded.')
 | 
			
		||||
 | 
			
		||||
        init(g)
 | 
			
		||||
        g.game.close_window()
 | 
			
		||||
        print('Initialized.')
 | 
			
		||||
 | 
			
		||||
        while g.running:
 | 
			
		||||
@@ -270,10 +270,3 @@ def bot(global_state):
 | 
			
		||||
        g.connection.early_outgoing_packet_listeners = []
 | 
			
		||||
 | 
			
		||||
print('Bot module loaded.')
 | 
			
		||||
 | 
			
		||||
print(mcdata.mcd.blockCollisionShapes['blocks']['brewing_stand'])
 | 
			
		||||
print(mcdata.mcd.blockCollisionShapes['shapes']['107'])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										44
									
								
								game.py
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								game.py
									
									
									
									
									
								
							@@ -309,6 +309,40 @@ class MCWorld:
 | 
			
		||||
            result.append(mob)
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def find_villagers(self, center, distance):
 | 
			
		||||
        # finds villagers within distance
 | 
			
		||||
        result = []
 | 
			
		||||
        for eid, mob in copy(self.g.mobs).items():
 | 
			
		||||
            type_name = mobs.MOB_NAMES[mob.type]
 | 
			
		||||
            if type_name != 'villager' : continue
 | 
			
		||||
            pos = utils.pint((mob.x, mob.y, mob.z))
 | 
			
		||||
            if utils.phyp(center, pos) > distance:
 | 
			
		||||
                continue
 | 
			
		||||
            result.append(mob)
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
    def find_villager_openings(self, villager):
 | 
			
		||||
        # returns coords in a cardinal direction where we can stand by a villager
 | 
			
		||||
        maze_solver = path.Pathfinder(self.g.chunks)
 | 
			
		||||
        result = []
 | 
			
		||||
 | 
			
		||||
        for distance in range(3):
 | 
			
		||||
            for direction in path.CHECK_DIRECTIONS:
 | 
			
		||||
                offset = utils.pmul(direction, distance+1)
 | 
			
		||||
 | 
			
		||||
                if not maze_solver.check_traverse(villager, offset):
 | 
			
		||||
                    continue
 | 
			
		||||
 | 
			
		||||
                # check for line of sight
 | 
			
		||||
                for check in range(distance+1):
 | 
			
		||||
                    offset2 = utils.pmul(direction, check+1)
 | 
			
		||||
                    offset2 = utils.padd(offset2, path.BLOCK_ABOVE)
 | 
			
		||||
                    check = utils.padd(villager, offset2)
 | 
			
		||||
                    if self.block_at(*check) not in blocks.NON_SOLID_IDS:
 | 
			
		||||
                        break
 | 
			
		||||
                else:  # for
 | 
			
		||||
                    result.append(utils.padd(villager, offset))
 | 
			
		||||
        return result
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Game:
 | 
			
		||||
@@ -642,7 +676,12 @@ class Game:
 | 
			
		||||
                    self.g.job.state = self.g.job.loiter
 | 
			
		||||
                    reply = 'ok'
 | 
			
		||||
 | 
			
		||||
                if command == 'trade':
 | 
			
		||||
                    self.g.job.state = self.g.job.trade
 | 
			
		||||
                    reply = 'ok'
 | 
			
		||||
 | 
			
		||||
                if command == 'stop':
 | 
			
		||||
                    self.close_window()
 | 
			
		||||
                    bot.init(self.g)
 | 
			
		||||
                    reply = 'ok'
 | 
			
		||||
 | 
			
		||||
@@ -773,7 +812,8 @@ class Game:
 | 
			
		||||
 | 
			
		||||
                if command == 'test':
 | 
			
		||||
                    reply = 'ok'
 | 
			
		||||
                    self.select_next_item()
 | 
			
		||||
                    r = self.g.world.find_villager_openings((615, 78, 493))
 | 
			
		||||
                    print(r)
 | 
			
		||||
 | 
			
		||||
            ################# Authorized commands ##########################
 | 
			
		||||
            if authed:
 | 
			
		||||
@@ -965,6 +1005,7 @@ class Game:
 | 
			
		||||
        w.count += 1
 | 
			
		||||
 | 
			
		||||
    def close_window(self):
 | 
			
		||||
        if self.g.window:
 | 
			
		||||
            packet = CloseWindowPacket()
 | 
			
		||||
            packet.window_id = self.g.window.data.window_id
 | 
			
		||||
            self.g.connection.write_packet(packet)
 | 
			
		||||
@@ -1143,6 +1184,7 @@ class Game:
 | 
			
		||||
 | 
			
		||||
    def handle_trade_list(self, packet):
 | 
			
		||||
        print(packet)
 | 
			
		||||
        self.g.trades = packet.trades
 | 
			
		||||
 | 
			
		||||
    def tick(self):
 | 
			
		||||
        if self.g.breaking:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										124
									
								
								jobs.py
									
									
									
									
									
								
							
							
						
						
									
										124
									
								
								jobs.py
									
									
									
									
									
								
							@@ -1772,6 +1772,114 @@ class EatFoodStates:
 | 
			
		||||
        self.state()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class SellToVillagerStates:
 | 
			
		||||
    def idle(self):
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
    def init(self):
 | 
			
		||||
        self.state = self.find_villager
 | 
			
		||||
 | 
			
		||||
    def find_villager(self):
 | 
			
		||||
        print('Finding new villager...')
 | 
			
		||||
        w = self.g.world
 | 
			
		||||
        p = utils.pint(self.g.pos)
 | 
			
		||||
 | 
			
		||||
        for villager in w.find_villagers(p, 100):
 | 
			
		||||
            print('Found villager:', villager)
 | 
			
		||||
            if villager not in self.bad_villagers:
 | 
			
		||||
                break
 | 
			
		||||
        else: # for
 | 
			
		||||
            print('No good villagers left, aborting.')
 | 
			
		||||
            self.state = self.cleanup
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        self.villager = villager
 | 
			
		||||
        self.villager_pos = utils.pint((villager.x, villager.y, villager.z))
 | 
			
		||||
        self.state = self.find_openings
 | 
			
		||||
 | 
			
		||||
    def find_openings(self):
 | 
			
		||||
        w = self.g.world
 | 
			
		||||
        self.openings = w.find_villager_openings(self.villager_pos)
 | 
			
		||||
        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 villager:', self.villager)
 | 
			
		||||
            if self.villager not in self.good_villagers:
 | 
			
		||||
                self.bad_villagers.append(self.villager)
 | 
			
		||||
                print('Added to bad villager list')
 | 
			
		||||
            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_villager
 | 
			
		||||
        else:
 | 
			
		||||
            self.openings.pop(0)
 | 
			
		||||
 | 
			
		||||
    def going_to_villager(self):
 | 
			
		||||
        if utils.pint(self.g.pos) == self.openings[0]:
 | 
			
		||||
            print('Arrived at villager')
 | 
			
		||||
            self.g.look_at = self.villager_pos
 | 
			
		||||
            self.wait_time = 0.5
 | 
			
		||||
            self.state = self.wait_to_interact
 | 
			
		||||
 | 
			
		||||
    def wait_to_interact(self):
 | 
			
		||||
        if self.wait_time > 0:
 | 
			
		||||
            self.wait_time -= utils.TICK
 | 
			
		||||
        else:
 | 
			
		||||
            self.state = self.interact_villager
 | 
			
		||||
 | 
			
		||||
    def interact_villager(self):
 | 
			
		||||
        print('Interacting with villager')
 | 
			
		||||
        self.g.game.interact(self.villager.entity_id)
 | 
			
		||||
        self.g.game.animate()
 | 
			
		||||
        self.state = self.select_trade
 | 
			
		||||
 | 
			
		||||
    def select_trade(self):
 | 
			
		||||
        if not self.g.window or not self.g.trades:
 | 
			
		||||
            return
 | 
			
		||||
 | 
			
		||||
        print('Got trades window')
 | 
			
		||||
        self.state = self.freeze
 | 
			
		||||
 | 
			
		||||
    def freeze(self):
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    def wait(self):
 | 
			
		||||
        if self.wait_time > 0:
 | 
			
		||||
            self.wait_time -= utils.TICK
 | 
			
		||||
        else:
 | 
			
		||||
            self.state = self.cleanup
 | 
			
		||||
 | 
			
		||||
    def cleanup(self):
 | 
			
		||||
        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.villager = None
 | 
			
		||||
        self.villager_pos = None
 | 
			
		||||
        self.bad_villagers = []
 | 
			
		||||
        self.good_villagers = []
 | 
			
		||||
        self.openings = []
 | 
			
		||||
        self.wait_time = 0
 | 
			
		||||
 | 
			
		||||
    def run(self):
 | 
			
		||||
        self.state()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class JobStates:
 | 
			
		||||
    def idle(self):
 | 
			
		||||
@@ -1793,6 +1901,7 @@ class JobStates:
 | 
			
		||||
        self.gather_wart_states = GatherWartStates(self.g)
 | 
			
		||||
        self.gather_crop_states = GatherCropStates(self.g)
 | 
			
		||||
        self.eat_food_states = EatFoodStates(self.g)
 | 
			
		||||
        self.sell_to_villager = SellToVillagerStates(self.g)
 | 
			
		||||
 | 
			
		||||
    def run_machines(self, machines):
 | 
			
		||||
        for m in machines:
 | 
			
		||||
@@ -1922,6 +2031,21 @@ class JobStates:
 | 
			
		||||
        self.sleep_with_bed_states.silent = True
 | 
			
		||||
        return machines
 | 
			
		||||
 | 
			
		||||
    def trade(self):
 | 
			
		||||
        machines = [
 | 
			
		||||
            #self.grab_supplies_states,
 | 
			
		||||
            self.sell_to_villager,
 | 
			
		||||
            #self.sleep_with_bed_states,
 | 
			
		||||
            #self.eat_food_states,
 | 
			
		||||
            #self.cache_items_states,
 | 
			
		||||
        ]
 | 
			
		||||
        self.sleep_with_bed_states.silent = True
 | 
			
		||||
        self.cache_items_states.silent = True
 | 
			
		||||
        self.grab_supplies_states.supplies = {
 | 
			
		||||
            tuple(items.AXE_IDS): 9,
 | 
			
		||||
        }
 | 
			
		||||
        return machines
 | 
			
		||||
 | 
			
		||||
    def stop(self):
 | 
			
		||||
        self.init_machines()
 | 
			
		||||
        self.state = self.idle
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user