From a87cc85eabba92a3148e7d6a2fecb6c225dc3c70 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sat, 1 May 2021 21:31:21 +0000 Subject: [PATCH] Improve trading villager selection based on profession --- main.py | 2 +- mosfet/game.py | 7 +++++++ mosfet/info/items.py | 1 + mosfet/info/mobs.py | 25 +++++++++++++++++++++++++ mosfet/job.py | 4 ++++ mosfet/jobs/grab_supplies.py | 5 ++++- mosfet/jobs/sell_to_villager.py | 30 +++++++++++++++++++++++++----- mosfet/protocol/packets.py | 2 +- mosfet/protocol/types.py | 21 ++++++++++++++------- 9 files changed, 82 insertions(+), 15 deletions(-) diff --git a/main.py b/main.py index cbba0d1..258beea 100644 --- a/main.py +++ b/main.py @@ -71,7 +71,7 @@ def main(): event_handler.on_any_event = reload_bot observer = Observer() - observer.schedule(event_handler, '.', recursive=True) + observer.schedule(event_handler, 'mosfet', recursive=True) observer.start() try: diff --git a/mosfet/game.py b/mosfet/game.py index e051474..f484505 100644 --- a/mosfet/game.py +++ b/mosfet/game.py @@ -393,6 +393,13 @@ class Game: obj.item_id = entry.value.item_id obj.item_count = entry.value.item_count + mob = self.g.mobs.get(packet.entity_id, None) + if mob: + for entry in packet.metadata: + if mob.type == mobs.VILLAGER: + if entry.index == 17: + mob.profession = entry.value[1] + player = self.g.players.get(packet.entity_id, None) if player: return diff --git a/mosfet/info/items.py b/mosfet/info/items.py index 8df4feb..ddf4f8b 100644 --- a/mosfet/info/items.py +++ b/mosfet/info/items.py @@ -103,6 +103,7 @@ WHEAT_ID = get_id('wheat') WHEAT_SEEDS_ID = get_id('wheat_seeds') BEETROOT_SEEDS_ID = get_id('beetroot_seeds') PUMPKIN_ID = get_id('pumpkin') +BEETROOT_ID = get_id('beetroot') EMERALD_ID = get_id('emerald') BERRIES_ID = get_id('sweet_berries') diff --git a/mosfet/info/mobs.py b/mosfet/info/mobs.py index 7c1e6e4..f996206 100644 --- a/mosfet/info/mobs.py +++ b/mosfet/info/mobs.py @@ -1,8 +1,33 @@ +from mosfet.info import items import json with open('minecraft_data/registries.json') as f: MOBS = json.load(f)['minecraft:entity_type']['entries'] +VILLAGER = 93 +ARMORER = 1 +BUTCHER = 2 +CARTOGRAPHER = 3 +CLERIC = 4 +FARMER = 5 +FISHERMAN = 6 +FLETCHER = 7 +LEATHERWORKER = 8 +LIBRARIAN = 9 +MASON = 10 +NITWIT = 11 +SHEPHERD = 12 +TOOLSMITH = 13 +WEAPONSMITH = 14 + +TRADES = { + ARMORER: [items.IRON_INGOT_ID], + BUTCHER: [items.BERRIES_ID], + FARMER: [items.PUMPKIN_ID, items.WHEAT_ID, items.POTATO_ID, items.CARROT_ID, items.BEETROOT_ID], + TOOLSMITH: [items.IRON_INGOT_ID], + WEAPONSMITH: [items.IRON_INGOT_ID], +} + EVIL = [ 'blaze', 'cave_spider', diff --git a/mosfet/job.py b/mosfet/job.py index cff6bf8..3ed6bcb 100644 --- a/mosfet/job.py +++ b/mosfet/job.py @@ -235,6 +235,8 @@ class JobStates: tuple([items.IRON_INGOT_ID]): (64, 3), tuple([items.WHEAT_ID]): (64, 3), tuple([items.POTATO_ID]): (64, 3), + tuple([items.CARROT_ID]): (64, 3), + tuple([items.BEETROOT_ID]): (64, 3), } items.set_needed(set([ @@ -243,6 +245,8 @@ class JobStates: items.IRON_INGOT_ID, items.WHEAT_ID, items.POTATO_ID, + items.CARROT_ID, + items.BEETROOT_ID, ])) return machines diff --git a/mosfet/jobs/grab_supplies.py b/mosfet/jobs/grab_supplies.py index e17e080..54a7092 100644 --- a/mosfet/jobs/grab_supplies.py +++ b/mosfet/jobs/grab_supplies.py @@ -102,7 +102,10 @@ class GrabSuppliesStates: print('No path, blacklisting barrel') time.sleep(0.1) self.bad_barrels.append(self.barrel) - self.state = self.choose_barrel + if len(self.bad_barrels) > 3: + self.state = self.cleanup + else: + self.state = self.choose_barrel def going_to_barrel(self): if utils.pint(self.g.pos) == self.opening: diff --git a/mosfet/jobs/sell_to_villager.py b/mosfet/jobs/sell_to_villager.py index 1033f80..ecc7543 100644 --- a/mosfet/jobs/sell_to_villager.py +++ b/mosfet/jobs/sell_to_villager.py @@ -31,8 +31,29 @@ class SellToVillagerStates: for v in w.find_villagers(p, 100): print('Found villager:', v) - if v not in self.bad_villagers and v not in self.spent_villagers: - break + + if v in self.bad_villagers: + print('In bad villager list') + continue + + if v in self.spent_villagers: + print('In spent villager list') + continue + + if 'profession' not in v: + print('Villager has unknown profession') + continue + + if v.profession not in mobs.TRADES: + print('Villager doesnt sell stuff we collect') + continue + + trades = mobs.TRADES[v.profession] + if not self.g.game.count_items(trades): + print('We dont have anything to sell him') + continue + + break else: # for print('No good villagers left, aborting.') self.spent_villagers = [] @@ -59,7 +80,7 @@ class SellToVillagerStates: if self.villager not in self.good_villagers: self.bad_villagers.append(self.villager) print('Added to bad villager list') - self.state = self.cleanup + self.state = self.find_villager return navpath = w.path_to_place(p, self.openings[0]) @@ -144,8 +165,7 @@ class SellToVillagerStates: print('Villager has been spent, aborting') self.g.game.close_window() self.spent_villagers.append(self.villager) - self.state = self.wait - self.wait_time = 10 + self.state = self.find_villager return def click_trade(self): diff --git a/mosfet/protocol/packets.py b/mosfet/protocol/packets.py index e940dd1..f8b3a50 100644 --- a/mosfet/protocol/packets.py +++ b/mosfet/protocol/packets.py @@ -304,7 +304,7 @@ class EntityMetadataPacket(Packet): self.metadata = [] for _ in range(99): entry = Entry.read(file_object, self.context) - if not entry: break + if not entry: break # hit an unimplemented type, stops parsing self.metadata.append(entry) diff --git a/mosfet/protocol/types.py b/mosfet/protocol/types.py index fa5783d..c86e183 100644 --- a/mosfet/protocol/types.py +++ b/mosfet/protocol/types.py @@ -141,7 +141,7 @@ class Slot(Type): class Entry(Type): - types = { + simple_types = { 0: Byte, 1: VarInt, 2: Float, @@ -169,12 +169,19 @@ class Entry(Type): index = UnsignedByte.read(file_object) if index == 0xff: return None type = VarInt.read(file_object) - try: - value = Entry.types[type].read(file_object) - except TypeError: - value = Entry.types[type].read_with_context(file_object, context) - except KeyError: - return None + + if type == 10: # optional position + present = Boolean.read(file_object) + value = Position.read_with_context(file_object, context) if present else None + elif type == 16: # villager data + value = (VarInt.read(file_object), VarInt.read(file_object), VarInt.read(file_object)) + else: + try: + value = Entry.simple_types[type].read(file_object) + except TypeError: + value = Entry.simple_types[type].read_with_context(file_object, context) + except KeyError: + return None # unimplemented data type, stops parsing entries return Entry(index, type, value)