diff --git a/policy/context.py b/policy/context.py index f144801..031a187 100644 --- a/policy/context.py +++ b/policy/context.py @@ -119,7 +119,12 @@ class PolicyContext: if inventory_item(old) == inventory_item(new): return elif action == "combat_select_card": - if len(screen.get("selected_cards") or []) <= len(pending.screen.get("selected_cards") or []): + # Upgrade previews do not expose selected_cards. A ready upgrade + # confirmation is completion evidence for the accepted selection. + upgrade_ready = screen.get("mode") == "upgrade_select" and screen.get("can_confirm") + selection_grew = (len(screen.get("selected_cards") or []) + > len(pending.screen.get("selected_cards") or [])) + if not upgrade_ready and not selection_grew: return elif action == "select_bundle": if not screen.get("preview_showing") or not screen.get("can_confirm"): diff --git a/test_run.py b/test_run.py index a1900a9..a1ee1dd 100755 --- a/test_run.py +++ b/test_run.py @@ -402,6 +402,25 @@ result = invoke(fake, "--no-jev", "--steps", "5", "--max-duplicate-waits", "0") check("hand selection waits for selected count, not the separate selected-card index", [a[0][0] for a in fake.actions], ["combat_select_card", "combat_confirm_selection", "menu_select"]) +# Upgrade previews do not populate SelectedHandCardContainer, so the mod +# reports upgrade_select + can_confirm without selected_cards (live floor 12). +upgrade_hand = dict(hand, hand_select=dict(hand["hand_select"], + prompt="Choose a card to Upgrade.")) +upgrade_preview = dict(upgrade_hand, hand_select=dict(upgrade_hand["hand_select"], + mode="upgrade_select", prompt="Confirm Card to Upgrade", can_confirm=True)) +upgrade_loading = dict(upgrade_preview, hand_select=dict(upgrade_preview["hand_select"], + can_confirm=False)) +fake = FakeSts2([menu, upgrade_hand, upgrade_hand, upgrade_hand, upgrade_loading, + {"state_type": "overlay"}, upgrade_preview, upgrade_preview, menu], + action_ok=[False, True]) +result = invoke(fake, "--no-jev", "--steps", "8", "--max-duplicate-waits", "0") +check("upgrade selection retries rejection, waits for ready preview, then confirms once", + fake.actions, [(("combat_select_card",), {"card_index": 2}), + (("combat_select_card",), {"card_index": 2}), + (("combat_confirm_selection",), {}), + (("menu_select",), {"option": "singleplayer"})]) +check("upgrade preview transition completes without a timeout", result.rc, 0) + fake = FakeSts2([menu] + [dict(shop, animation_tick=i) for i in range(100)]) result = invoke(fake, "--steps", "100", "--stuck-seconds", "10", clock=itertools.count()) check("pending purchase times out despite unrelated observation changes",