import unittest from munch import Munch from mosfet.info import items from mosfet.jobs.grab_supplies import GrabSuppliesStates class GroundSupplyTests(unittest.TestCase): def test_default_needed_supplies_are_configured_by_constructor(self): state = GrabSuppliesStates(Munch()) self.assertEqual(items.FOOD, [ 'cooked_porkchop', 'cooked_beef', 'bread', 'cooked_chicken', 'cooked_cod', 'cooked_salmon', ]) self.assertEqual(items.FOOD_IDS, items.get_set({ 'cooked_porkchop', 'cooked_beef', 'bread', 'cooked_chicken', 'cooked_cod', 'cooked_salmon', })) self.assertEqual(state.supplies, { tuple(items.BED_IDS): (1, 1), (items.CHEST_ID,): (1, 1), tuple(items.FOOD_IDS): (1, 1), }) def test_chest_drop_is_checked_even_when_bed_is_missing(self): chest = Munch(entity_id=8, item_id=items.CHEST_ID, x=2.0, y=64.0, z=0.0) class FakeWorld: @staticmethod def find_objects(item_ids): return [chest] if items.CHEST_ID in item_ids else [] class FakeGame: @staticmethod def count_inventory_slots(): return 0 @staticmethod def count_items(_item_ids): return 0 state = GrabSuppliesStates(Munch( pos=(0.5, 64.0, 0.5), world=FakeWorld(), game=FakeGame(), maximum_supply_slots=33)) state.init() state.check_supplies() state.find_ground_items() self.assertIn(tuple(items.BED_IDS), state.checked_ground_groups) state.check_supplies() self.assertEqual(state.target_items, (items.CHEST_ID,)) self.assertIs(state.state.__func__, state.find_ground_items.__func__) def test_supply_selection_uses_only_addressed_supply_chests(self): position = (4, 64, 0) chest_record = { 'position': position, 'positions': (position,), 'labels': {'mosfet supplies'}, 'sign_positions': {(4, 64, 1)}, } class FakeWorld: @staticmethod def find_supply_chests(_center, _bot_name, _distance): return [chest_record] @staticmethod def find_blocks_indexed(*_args): raise AssertionError('grab_supplies must not search barrels') state = GrabSuppliesStates(Munch( name='mosfet1', pos=(0.5, 64.0, 0.5), world=FakeWorld())) state.find_supply_chests() state.choose_supply_chest() self.assertEqual(state.chest, position) self.assertIs(state.state.__func__, state.path_to_supply_chest.__func__) def test_unreachable_supply_chest_ends_task_without_searching_barrels(self): class FakeWorld: @staticmethod def path_to_place_faked(_start, _chest): return None position = (10, 64, 10) state = GrabSuppliesStates(Munch( pos=(0.5, 64.0, 0.5), world=FakeWorld(), chunks=Munch())) state.supply_chests = [{ 'position': position, 'positions': (position,), 'labels': {'mosfet supplies'}, }] state.choose_supply_chest() state.path_to_supply_chest() state.choose_supply_chest() self.assertIs(state.state.__func__, state.cleanup.__func__) def test_job_walks_to_and_picks_up_dropped_supply_before_barrels(self): axe_id = next(iter(items.AXE_IDS)) dropped_axe = Munch( entity_id=7, item_id=axe_id, item_count=1, x=3.2, y=64.0, z=0.2) class FakeWorld: def __init__(self): self.path_requests = [] def find_objects(self, item_ids): return ([dropped_axe] if axe_id in item_ids else []) def path_to_place(self, start, target): self.path_requests.append((start, target)) return [start, target] class FakeGame: def __init__(self): self.item_count = 0 def count_inventory_slots(self): return 5 def count_items(self, item_ids): return self.item_count if axe_id in item_ids else 0 world = FakeWorld() game = FakeGame() g = Munch( pos=(0.5, 64.0, 0.5), world=world, game=game, chunks=Munch(), objects={7: dropped_axe}, path=[], maximum_supply_slots=33, ) state = GrabSuppliesStates(g) state.supplies = {tuple(items.AXE_IDS): (1, 9)} state.init() state.check_supplies() state.find_ground_items() self.assertIs(state.state.__func__, state.going_to_ground_item.__func__) self.assertEqual(g.path[-1], (3, 64, 0)) self.assertEqual(world.path_requests, [((0, 64, 0), (3, 64, 0))]) g.pos = (3.5, 64.0, 0.5) state.going_to_ground_item() self.assertIs(state.state.__func__, state.wait_for_ground_item.__func__) game.item_count = 1 state.wait_for_ground_item() self.assertIs(state.state.__func__, state.check_supplies.__func__) state.check_supplies() self.assertIs(state.state.__func__, state.cleanup.__func__) # Nearby dropped tools are collected even when inventory already meets # the minimum, so tossing an axe during setup still gets noticed. game.item_count = 1 state.init() state.check_supplies() self.assertIs(state.state.__func__, state.find_ground_items.__func__) state.find_ground_items() self.assertEqual(state.ground_required_count, 2) if __name__ == '__main__': unittest.main()