Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 24 additions & 4 deletions autowsgr/ops/decisive/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import time
from typing import TYPE_CHECKING

import cv2

from autowsgr.combat.engine import run_combat
from autowsgr.combat.plan import CombatMode, CombatPlan, NodeDecision
from autowsgr.infra.logger import get_logger
Expand Down Expand Up @@ -153,11 +155,20 @@ def _handle_waiting_for_map(self) -> None:
phase == DecisivePhase.PREPARE_COMBAT
and self._state.stage == 1
and not self._has_chosen_fleet
and self._state.node != 'U' # 排除暂离后重进的情况
):
_log.warning('[决战] 首进第 1 小节将 PREPARE_COMBAT 修正为 CHOOSE_FLEET')
self._state.phase = DecisivePhase.CHOOSE_FLEET
return
if self._state.node != 'U':
_log.warning('[决战] 首进第 1 小节将 PREPARE_COMBAT 修正为 CHOOSE_FLEET')
self._state.phase = DecisivePhase.CHOOSE_FLEET
return
# node == 'U' 时,通过舰标检测区分暂离重进与 overlay 延迟加载
bgr = cv2.cvtColor(screen, cv2.COLOR_RGB2BGR)
icon_x = self._map._locate_ship_icon(bgr)
if icon_x is None:
_log.warning(
'[决战] 首进第 1 小节未检测到舰标,将 PREPARE_COMBAT 修正为 CHOOSE_FLEET'
)
self._state.phase = DecisivePhase.CHOOSE_FLEET
return

if phase is not None:
self._state.phase = phase
Expand Down Expand Up @@ -280,6 +291,7 @@ def _handle_prepare_combat(self) -> None:

# 先使用技能,再注册舰船,如果是未知节点,也判定一下技能是否使用
current_node = self._state.node
time.sleep(0.5) # 等待动画稳定后截图判定
skill_used = self._map.is_skill_used()
_log.debug('[决战] 节点: {}, 技能已使用检测: {}', current_node, skill_used)

Expand All @@ -300,6 +312,14 @@ def _handle_prepare_combat(self) -> None:
else:
_log.debug('[决战] 跳过技能使用: 节点={}, 技能已使用={}', current_node, skill_used)

# 首次进入且尚未选择过舰队时,使用技能后可能出现战备舰队获取 overlay,
# 先切回 WAITING_FOR_MAP 等待 overlay 稳定,避免直接点击编队超时。
if not skill_used not self._has_chosen_fleet:
_log.info('[决战] 首次进入,使用技能后等待 overlay 稳定')
self._wait_deadline = time.monotonic() + 10.0
self._state.phase = DecisivePhase.WAITING_FOR_MAP
return

# ── 恢复模式: 扫描当前舰队与可用舰船 ─────────────────────────
# 对齐 legacy: if fleet.empty() and not is_begin(): _check_fleet()
if self._resume_mode:
Expand Down
5 changes: 4 additions & 1 deletion autowsgr/ui/decisive/battle_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,14 @@
"""章节导航最大尝试次数。"""

MAX_CHAPTER: int = 6
MIN_CHAPTER: int = 4
MIN_CHAPTER: int = 1

# ── recognize_stage 检测点 ──

_STAGE_CHECK_POINTS: dict[int, list[tuple[float, float]]] = {
1: [(0.4115, 0.4019), (0.6604, 0.4630), (0.8396, 0.7093)],
2: [(0.4354, 0.3852), (0.5792, 0.6648), (0.8187, 0.5889)],
3: [(0.4219, 0.6648), (0.6531, 0.3944), (0.8042, 0.7444)],
4: [(0.381, 0.436), (0.596, 0.636), (0.778, 0.521)],
5: [(0.418, 0.378), (0.760, 0.477), (0.550, 0.750)],
6: [(0.606, 0.375), (0.532, 0.703), (0.862, 0.644)],
Expand Down
15 changes: 14 additions & 1 deletion autowsgr/ui/decisive/map_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ def confirm_stage_clear(self) -> list[str]:

# 掉落处理结束后,继续等待回到决战入口页,避免奖励弹窗残留导致后续状态识别超时
settle_deadline = time.monotonic() + 12.0
reward_ack_pos = (0.5, 0.5)
reward_ack_pos = (0.953, 0.954)
while time.monotonic() < settle_deadline:
screen = self._ctrl.screenshot()
if ImageChecker.find_any(screen, entry_templates, confidence=0.8) is not None:
Expand All @@ -639,6 +639,7 @@ def confirm_stage_clear(self) -> list[str]:
self._ctrl.click(*reward_ack_pos)
time.sleep(0.35)
confirm_operation(self._ctrl, timeout=0.8)
confirm_operation(self._ctrl, timeout=0.8)
continue

if confirm_operation(self._ctrl, timeout=0.8):
Expand All @@ -648,6 +649,18 @@ def confirm_stage_clear(self) -> list[str]:
else:
_log.warning('[地图控制器] 小关通关后未能确认已回到决战入口页')

# settle 循环结束后,如果仍未回到入口页,尝试从地图页返回
for _ in range(5):
screen = self._ctrl.screenshot()
if ImageChecker.find_any(screen, entry_templates, confidence=0.8) is not None:
_log.info('[地图控制器] 通过返回按钮回到决战入口页')
break
_log.debug('[地图控制器] 尝试点击返回按钮回到决战入口页')
self._ctrl.click(0.03, 0.06)
time.sleep(1.0)
else:
_log.warning('[地图控制器] 多次尝试后仍未能回到决战入口页')

if collected:
_log.info('[地图控制器] 小关通关共收集 {} 个掉落', len(collected))
return collected
Expand Down
Loading