import unittest from unittest.mock import patch from munch import Munch from mosfet.bot import start_automation from mosfet.commands import Commands from mosfet.info import blocks, items from mosfet.job import JobStates from mosfet.jobs.gather_wood import GatherWoodStates from mosfet.jobs.grab_supplies import GrabSuppliesStates from mosfet.protocol.types import Slot from mosfet.world import World class FakeChunks: def __init__(self, states): self.states = states self.index = {} def get_block_at(self, x, y, z): return self.states.get((x, y, z), blocks.AIR) class GatherWoodPortTests(unittest.TestCase): def test_log_states_are_indexed_for_modern_chunk_search(self): self.assertTrue(blocks.LOG_IDS) self.assertTrue(blocks.LOG_IDS.issubset(blocks.INDEXED_IDS)) def test_mangrove_uses_its_26_3_propagule_and_unplantable_logs_are_skipped(self): self.assertEqual(items.get_sapling_id('mangrove'), items.get_id('mangrove_propagule')) self.assertIsNone(items.get_sapling_id('crimson')) class FakeWorld: def find_trees(self, _position, _distance): return [(0, 64, 0), (3, 64, 0)] @staticmethod def work_position_allowed(_position): return True def filter_work_positions(self, positions): return [position for position in positions if self.work_position_allowed(position)] def block_at(self, x, y, z): return (blocks.MCD_BLOCKS['crimson_stem']['minStateId'] if x == 0 else blocks.MCD_BLOCKS['mangrove_log']['minStateId']) state = GatherWoodStates( Munch(world=FakeWorld(), pos=(0, 64, 0))) state.find_new_tree() self.assertEqual(state.tree, (3, 64, 0)) self.assertEqual(state.type, 'mangrove') self.assertEqual(state.bad_trees, [(0, 64, 0)]) def test_tree_search_finds_indexed_26_3_log_states(self): oak_log = blocks.MCD_BLOCKS['oak_log']['minStateId'] oak_leaves = blocks.MCD_BLOCKS['oak_leaves']['minStateId'] stone = blocks.MCD_BLOCKS['stone']['minStateId'] states = { (0, 63, 0): stone, (0, 64, 0): oak_log, (0, 65, 0): oak_log, (0, 66, 0): oak_log, (1, 66, 0): oak_leaves, } chunks = FakeChunks(states) chunks.index[oak_log] = { (0, 64, 0), (0, 65, 0), (0, 66, 0), } world = World(Munch(chunks=chunks)) self.assertEqual(list(world.find_trees((0, 64, 0), 10)), [(0, 64, 0)]) def test_gather_wood_job_keeps_existing_machine_sequence(self): job = JobStates(Munch()) self.assertIsNotNone(job.gather_wood_states) self.assertEqual(job.gather_wood(), [ job.gather_wood_states, job.sleep_with_bed_states, job.eat_food_states, job.cache_items_states, ]) job.gather_wood_states.state = job.gather_wood_states.find_new_tree job.stop() self.assertIs(job.gather_wood_states.state.__func__, job.gather_wood_states.idle.__func__) def test_grab_supplies_reads_protocol_777_container_shape(self): axe_id = next(iter(items.AXE_IDS)) axe = Slot(present=True, item_id=axe_id, item_count=1) clicks = [] class FakeGame: def count_inventory_slots(self): return 10 def click_window(self, *args): clicks.append(args) g = Munch( item_lock=False, window=Munch(container_slots=27, contents={0: axe}), maximum_supply_slots=33, game=FakeGame(), ) state = GrabSuppliesStates(g) state.target_items = {axe_id} state.maximum_stacks = 9 state.grab_items() self.assertTrue(g.item_lock) self.assertEqual(state.count, 1) self.assertEqual(clicks, [(0, 0, 1, axe)]) def test_modern_automation_sets_supply_inventory_limit(self): g = Munch() with patch('mosfet.bot.threading.Thread') as thread: start_automation(g, initialize=False) self.assertEqual(g.maximum_supply_slots, 33) thread.return_value.start.assert_called_once() def test_farm_wood_job_keeps_legacy_machine_sequence(self): job = JobStates(Munch()) try: self.assertEqual(job.farm_wood(), [ job.grab_supplies_states, job.gather_wood_states, job.clear_leaves_states, job.plant_tree_states, job.grab_sapling_states, job.sleep_with_bed_states, job.eat_food_states, job.cache_items_states, ]) self.assertEqual(job.grab_supplies_states.supplies, { tuple(items.AXE_IDS): (1, 9), tuple(items.BED_IDS): (1, 1), (items.CHEST_ID,): (1, 1), tuple(items.FOOD_IDS): (1, 1), }) self.assertTrue(job.sleep_with_bed_states.silent) self.assertTrue(job.cache_items_states.silent) self.assertTrue(items.AXE_IDS.issubset(items.NEEDED_ITEMS)) self.assertTrue(items.SAPLING_IDS.issubset(items.WANTED_ITEMS)) job.grab_supplies_states.state = job.grab_supplies_states.find_supply_chests job.clear_leaves_states.state = job.clear_leaves_states.find_leaves job.plant_tree_states.state = job.plant_tree_states.check_feet job.grab_sapling_states.state = job.grab_sapling_states.find_saplings job.stop() for machine in (job.grab_supplies_states, job.clear_leaves_states, job.plant_tree_states, job.grab_sapling_states): self.assertIs(machine.state.__func__, machine.idle.__func__) finally: items.set_needed(set()) items.set_wanted(set()) def test_gather_and_farm_wood_commands_are_enabled(self): class FakeChat: def __init__(self): self.sent = [] def set_handler(self, handler): self.handler = handler def send(self, message): self.sent.append(message) job = JobStates(Munch()) chat = FakeChat() g = Munch(name='mosfet1', chat=chat, job=job, inv={0: Munch(item_id=next(iter(items.BED_IDS)))}) Commands(g).handle_chat(('CHAT', 'tester', 'tester: 1gather wood')) self.assertEqual(chat.sent, ['ok']) self.assertIs(job.state.__func__, job.gather_wood.__func__) chat.sent.clear() Commands(g).handle_chat(('CHAT', 'tester', 'tester: 1farm wood')) self.assertEqual(chat.sent, ['ok']) self.assertIs(job.state.__func__, job.farm_wood.__func__) if __name__ == '__main__': unittest.main()