Avoid redundant cache chest visits
This commit is contained in:
@@ -20,7 +20,7 @@ class CacheItemsStates:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
self.skip_slots = []
|
self.skip_inventory_slots = set()
|
||||||
self.skip_items = []
|
self.skip_items = []
|
||||||
self.failed_transfer_slots = set()
|
self.failed_transfer_slots = set()
|
||||||
self.pending_transfer = None
|
self.pending_transfer = None
|
||||||
@@ -30,8 +30,8 @@ class CacheItemsStates:
|
|||||||
self.container_item_ids = None
|
self.container_item_ids = None
|
||||||
|
|
||||||
num_stacks = self.g.game.count_inventory_slots()
|
num_stacks = self.g.game.count_inventory_slots()
|
||||||
minimum = getattr(
|
minimum = self.__dict__.pop(
|
||||||
self, 'minimum', self.g.get('minimum_cache_slots', 27))
|
'minimum', self.g.get('minimum_cache_slots', 27))
|
||||||
print('Inventory amount:', num_stacks)
|
print('Inventory amount:', num_stacks)
|
||||||
if num_stacks == 0:
|
if num_stacks == 0:
|
||||||
self.state = self.cleanup
|
self.state = self.cleanup
|
||||||
@@ -79,8 +79,7 @@ class CacheItemsStates:
|
|||||||
if key in self.checked_labeled_chests:
|
if key in self.checked_labeled_chests:
|
||||||
continue
|
continue
|
||||||
self.checked_labeled_chests.add(key)
|
self.checked_labeled_chests.add(key)
|
||||||
if not any(item.present and item.item_id in container['item_ids']
|
if not self._has_transferable_item(container['item_ids']):
|
||||||
for item in self.g.inv.values()):
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.area = container['position']
|
self.area = container['position']
|
||||||
@@ -97,6 +96,7 @@ class CacheItemsStates:
|
|||||||
self.opening = opening_position
|
self.opening = opening_position
|
||||||
self.open_interaction = opening
|
self.open_interaction = opening
|
||||||
self.g.path = navpath
|
self.g.path = navpath
|
||||||
|
self.g.look_at = None
|
||||||
self.state = self.going_to_trapped_chest
|
self.state = self.going_to_trapped_chest
|
||||||
return
|
return
|
||||||
self.bad_openings.add(opening_position)
|
self.bad_openings.add(opening_position)
|
||||||
@@ -128,6 +128,7 @@ class CacheItemsStates:
|
|||||||
self.opening = opening_position
|
self.opening = opening_position
|
||||||
self.open_interaction = opening
|
self.open_interaction = opening
|
||||||
self.g.path = navpath
|
self.g.path = navpath
|
||||||
|
self.g.look_at = None
|
||||||
self.state = self.going_to_trapped_chest
|
self.state = self.going_to_trapped_chest
|
||||||
return
|
return
|
||||||
self.bad_openings.add(opening_position)
|
self.bad_openings.add(opening_position)
|
||||||
@@ -140,6 +141,8 @@ class CacheItemsStates:
|
|||||||
self.g.look_at = self.open_interaction['look_at']
|
self.g.look_at = self.open_interaction['look_at']
|
||||||
self.wait_time = 0.5
|
self.wait_time = 0.5
|
||||||
self.state = self.turn_to_trapped_chest
|
self.state = self.turn_to_trapped_chest
|
||||||
|
else:
|
||||||
|
self.g.look_at = None
|
||||||
|
|
||||||
def turn_to_trapped_chest(self):
|
def turn_to_trapped_chest(self):
|
||||||
self.g.look_at = self.open_interaction['look_at']
|
self.g.look_at = self.open_interaction['look_at']
|
||||||
@@ -191,6 +194,7 @@ class CacheItemsStates:
|
|||||||
return
|
return
|
||||||
|
|
||||||
self.g.path = navpath
|
self.g.path = navpath
|
||||||
|
self.g.look_at = None
|
||||||
self.state = self.going_to_area
|
self.state = self.going_to_area
|
||||||
|
|
||||||
def going_to_area(self):
|
def going_to_area(self):
|
||||||
@@ -198,6 +202,8 @@ class CacheItemsStates:
|
|||||||
self.g.look_at = self.open_interaction['look_at']
|
self.g.look_at = self.open_interaction['look_at']
|
||||||
self.wait_time = 0.5
|
self.wait_time = 0.5
|
||||||
self.state = self.turn_to_cache_spot
|
self.state = self.turn_to_cache_spot
|
||||||
|
else:
|
||||||
|
self.g.look_at = None
|
||||||
|
|
||||||
def turn_to_cache_spot(self):
|
def turn_to_cache_spot(self):
|
||||||
self.g.look_at = self.open_interaction['look_at']
|
self.g.look_at = self.open_interaction['look_at']
|
||||||
@@ -255,6 +261,24 @@ class CacheItemsStates:
|
|||||||
keep.add(max(stacks, key=lambda pair: pair[1].item_count)[0])
|
keep.add(max(stacks, key=lambda pair: pair[1].item_count)[0])
|
||||||
return keep
|
return keep
|
||||||
|
|
||||||
|
def _has_transferable_item(self, item_ids):
|
||||||
|
item_ids = set(item_ids)
|
||||||
|
needed_slots = self._needed_inventory_slots_to_keep()
|
||||||
|
planned_skip_items = set(self.skip_items)
|
||||||
|
for inventory_slot, item in self.g.inv.items():
|
||||||
|
if (not item.present or item.item_id not in item_ids or
|
||||||
|
inventory_slot in self.skip_inventory_slots):
|
||||||
|
continue
|
||||||
|
if (item.item_id in items.NEEDED_ITEMS and
|
||||||
|
inventory_slot in needed_slots):
|
||||||
|
continue
|
||||||
|
if (item.item_id in items.WANTED_ITEMS and
|
||||||
|
item.item_id not in planned_skip_items):
|
||||||
|
planned_skip_items.add(item.item_id)
|
||||||
|
continue
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def _window_player_slot(self, window_slot):
|
def _window_player_slot(self, window_slot):
|
||||||
offset = window_slot - self.g.window.container_slots
|
offset = window_slot - self.g.window.container_slots
|
||||||
if 0 <= offset < 27:
|
if 0 <= offset < 27:
|
||||||
@@ -333,7 +357,8 @@ class CacheItemsStates:
|
|||||||
elif slot.item_id in items.NEEDED_ITEMS:
|
elif slot.item_id in items.NEEDED_ITEMS:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if (slot_num in self.skip_slots or
|
inventory_slot = self._window_player_slot(slot_num)
|
||||||
|
if (inventory_slot in self.skip_inventory_slots or
|
||||||
slot_num in self.failed_transfer_slots):
|
slot_num in self.failed_transfer_slots):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -344,7 +369,9 @@ class CacheItemsStates:
|
|||||||
for slot_num, slot in slot_list:
|
for slot_num, slot in slot_list:
|
||||||
if slot.item_id in items.WANTED_ITEMS and slot.item_id not in self.skip_items:
|
if slot.item_id in items.WANTED_ITEMS and slot.item_id not in self.skip_items:
|
||||||
print('skipping wanted item', slot)
|
print('skipping wanted item', slot)
|
||||||
self.skip_slots.append(slot_num)
|
inventory_slot = self._window_player_slot(slot_num)
|
||||||
|
if inventory_slot is not None:
|
||||||
|
self.skip_inventory_slots.add(inventory_slot)
|
||||||
self.skip_items.append(slot.item_id)
|
self.skip_items.append(slot.item_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -393,7 +420,7 @@ class CacheItemsStates:
|
|||||||
|
|
||||||
self.silent = False
|
self.silent = False
|
||||||
|
|
||||||
self.skip_slots = []
|
self.skip_inventory_slots = set()
|
||||||
self.failed_transfer_slots = set()
|
self.failed_transfer_slots = set()
|
||||||
self.pending_transfer = None
|
self.pending_transfer = None
|
||||||
self.transferred_to_labeled_chest = False
|
self.transferred_to_labeled_chest = False
|
||||||
|
|||||||
@@ -30,6 +30,39 @@ class CacheItemsTests(unittest.TestCase):
|
|||||||
'Found 11 labeled chests; found 0 trapped chests: []',
|
'Found 11 labeled chests; found 0 trapped chests: []',
|
||||||
output.getvalue())
|
output.getvalue())
|
||||||
|
|
||||||
|
def test_wanted_single_stack_is_not_considered_transferable(self):
|
||||||
|
wanted_id = items.WHEAT_SEEDS_ID
|
||||||
|
old_wanted = items.WANTED_ITEMS
|
||||||
|
items.WANTED_ITEMS = set(old_wanted) | {wanted_id}
|
||||||
|
try:
|
||||||
|
state = CacheItemsStates(Munch(inv={
|
||||||
|
9: Munch(present=True, item_id=wanted_id, item_count=56),
|
||||||
|
}))
|
||||||
|
self.assertFalse(state._has_transferable_item({wanted_id}))
|
||||||
|
|
||||||
|
state.g.inv[10] = Munch(
|
||||||
|
present=True, item_id=wanted_id, item_count=12)
|
||||||
|
self.assertTrue(state._has_transferable_item({wanted_id}))
|
||||||
|
finally:
|
||||||
|
items.WANTED_ITEMS = old_wanted
|
||||||
|
|
||||||
|
def test_manual_cache_threshold_override_is_consumed_once(self):
|
||||||
|
class FakeGame:
|
||||||
|
@staticmethod
|
||||||
|
def count_inventory_slots():
|
||||||
|
return 5
|
||||||
|
|
||||||
|
state = CacheItemsStates(Munch(
|
||||||
|
game=FakeGame(), minimum_cache_slots=27))
|
||||||
|
state.minimum = 0
|
||||||
|
|
||||||
|
state.init()
|
||||||
|
self.assertIs(state.state.__func__, state.find_trapped_chests.__func__)
|
||||||
|
self.assertNotIn('minimum', state.__dict__)
|
||||||
|
|
||||||
|
state.init()
|
||||||
|
self.assertIs(state.state.__func__, state.cleanup.__func__)
|
||||||
|
|
||||||
def test_successful_labeled_transfer_skips_placing_another_cache_chest(self):
|
def test_successful_labeled_transfer_skips_placing_another_cache_chest(self):
|
||||||
item_id = items.get_id('stone')
|
item_id = items.get_id('stone')
|
||||||
stack = Munch(present=True, item_id=item_id, item_count=16)
|
stack = Munch(present=True, item_id=item_id, item_count=16)
|
||||||
@@ -133,6 +166,27 @@ class CacheItemsTests(unittest.TestCase):
|
|||||||
self.assertFalse(state._opening_in_bad_region(FakeWorld(), candidate))
|
self.assertFalse(state._opening_in_bad_region(FakeWorld(), candidate))
|
||||||
self.assertNotIn(candidate, state.bad_openings)
|
self.assertNotIn(candidate, state.bad_openings)
|
||||||
|
|
||||||
|
def test_cache_travel_looks_along_path_then_turns_to_chest(self):
|
||||||
|
opening = (5, 64, 8)
|
||||||
|
chest_look = (4.9, 64.1, 7.8)
|
||||||
|
state = CacheItemsStates(Munch(
|
||||||
|
pos=(2.5, 64, 2.5), look_at=(1, 64, 1)))
|
||||||
|
state.opening = opening
|
||||||
|
state.open_interaction = {'look_at': chest_look}
|
||||||
|
|
||||||
|
state.going_to_trapped_chest()
|
||||||
|
self.assertIsNone(state.g.look_at)
|
||||||
|
|
||||||
|
state.g.pos = opening
|
||||||
|
state.going_to_trapped_chest()
|
||||||
|
self.assertEqual(state.g.look_at, chest_look)
|
||||||
|
self.assertIs(state.state.__func__, state.turn_to_trapped_chest.__func__)
|
||||||
|
|
||||||
|
state.g.pos = (2.5, 64, 2.5)
|
||||||
|
state.g.look_at = (1, 64, 1)
|
||||||
|
state.going_to_area()
|
||||||
|
self.assertIsNone(state.g.look_at)
|
||||||
|
|
||||||
def test_cache_chest_placement_sneaks_to_avoid_opening_support_container(self):
|
def test_cache_chest_placement_sneaks_to_avoid_opening_support_container(self):
|
||||||
calls = []
|
calls = []
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user