fix(campaign): 低心情撤退后切换后续活动任务 - #767
Conversation
CI 检查报告
检查结果
导入冒烟测试
|
Reviewer's Guide为战役事件实现低心情撤退流程:在计算模式下拦截低心情强制出击弹窗,通过引导撤退流程依次导航准备界面和结果界面,将心情记录重置为 0,将当前事件任务延后到计算出的恢复时间,并可选地切换到下一个已配置的事件任务,同时用单元测试覆盖相关行为。 战役运行中低心情撤退流程的时序图sequenceDiagram
actor User
participant CampaignBase
participant CampaignRun
participant MapOperation as CampaignMapOperation
participant Emotion
participant Config
User->>CampaignBase: handle_combat_low_emotion()
CampaignBase->>CampaignBase: handle_popup_cancel(IGNORE_LOW_EMOTION)
alt Emotion_Mode == calculate and popup cancelled
CampaignBase->>CampaignBase: low_emotion_withdrawn = True
CampaignBase-->>CampaignRun: CampaignEnd(LowEmotionWithdraw)
else other emotion modes
CampaignBase->>CampaignBase: super.handle_combat_low_emotion()
end
CampaignRun->>CampaignRun: run()
CampaignRun->>CampaignBase: campaign.run()
CampaignBase-->>CampaignRun: CampaignEnd(LowEmotionWithdraw)
CampaignRun->>CampaignRun: catch CampaignEnd
CampaignRun->>CampaignRun: handle_low_emotion_withdrawal()
alt low_emotion_withdrawn
CampaignRun->>MapOperation: withdraw(skip_first_screenshot=False)
loop withdraw loop
MapOperation->>MapOperation: handle_withdraw_battle_preparation()
MapOperation->>MapOperation: handle_enter_map_preparation_cancel()
MapOperation->>MapOperation: handle_withdraw_result()
MapOperation->>MapOperation: handle_popup_confirm(WITHDRAW/COMBAT_STATUS)
MapOperation->>MapOperation: handle_in_stage()
end
CampaignRun->>Emotion: emotion.update()
CampaignRun->>Emotion: emotion.record()
CampaignRun->>Emotion: get_recovered_for_battle(campaign._map_battle)
Emotion-->>CampaignRun: recovered datetime
CampaignRun->>Config: task_delay(target=recovered)
CampaignRun->>CampaignRun: get_low_emotion_next_event_task(task)
alt next_event exists
CampaignRun->>Config: task_call(next_event, force_call=False)
Config-->>CampaignRun: success
CampaignRun->>Config: update()
end
CampaignRun->>Config: task_stop('[低心情] 已撤退并延后当前任务')
CampaignRun->>CampaignBase: low_emotion_withdrawn = False
else no low_emotion_withdrawn
CampaignRun-->>User: propagate CampaignEnd
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your Experience访问你的 dashboard 以:
Getting HelpOriginal review guide in EnglishReviewer's GuideImplements a low-emotion withdrawal flow for campaign events: intercepting the low-emotion forced sortie prompt in calculate mode, performing a guided withdrawal that navigates preparation and result UIs, resetting emotion records to 0, delaying the current event task to the computed recovery time, and optionally switching to the next configured event task, with unit tests covering the behavior. Sequence diagram for low emotion withdrawal flow in campaign runsequenceDiagram
actor User
participant CampaignBase
participant CampaignRun
participant MapOperation as CampaignMapOperation
participant Emotion
participant Config
User->>CampaignBase: handle_combat_low_emotion()
CampaignBase->>CampaignBase: handle_popup_cancel(IGNORE_LOW_EMOTION)
alt Emotion_Mode == calculate and popup cancelled
CampaignBase->>CampaignBase: low_emotion_withdrawn = True
CampaignBase-->>CampaignRun: CampaignEnd(LowEmotionWithdraw)
else other emotion modes
CampaignBase->>CampaignBase: super.handle_combat_low_emotion()
end
CampaignRun->>CampaignRun: run()
CampaignRun->>CampaignBase: campaign.run()
CampaignBase-->>CampaignRun: CampaignEnd(LowEmotionWithdraw)
CampaignRun->>CampaignRun: catch CampaignEnd
CampaignRun->>CampaignRun: handle_low_emotion_withdrawal()
alt low_emotion_withdrawn
CampaignRun->>MapOperation: withdraw(skip_first_screenshot=False)
loop withdraw loop
MapOperation->>MapOperation: handle_withdraw_battle_preparation()
MapOperation->>MapOperation: handle_enter_map_preparation_cancel()
MapOperation->>MapOperation: handle_withdraw_result()
MapOperation->>MapOperation: handle_popup_confirm(WITHDRAW/COMBAT_STATUS)
MapOperation->>MapOperation: handle_in_stage()
end
CampaignRun->>Emotion: emotion.update()
CampaignRun->>Emotion: emotion.record()
CampaignRun->>Emotion: get_recovered_for_battle(campaign._map_battle)
Emotion-->>CampaignRun: recovered datetime
CampaignRun->>Config: task_delay(target=recovered)
CampaignRun->>CampaignRun: get_low_emotion_next_event_task(task)
alt next_event exists
CampaignRun->>Config: task_call(next_event, force_call=False)
Config-->>CampaignRun: success
CampaignRun->>Config: update()
end
CampaignRun->>Config: task_stop('[低心情] 已撤退并延后当前任务')
CampaignRun->>CampaignBase: low_emotion_withdrawn = False
else no low_emotion_withdrawn
CampaignRun-->>User: propagate CampaignEnd
end
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - 我在这里给出了一些总体性的反馈:
- 在
CampaignBase.handle_combat_low_emotion中,建议在低情绪弹窗已处理并触发撤退时返回True,这样调用方就可以在进一步处理前进行短路,与原方法的语义保持一致。 - 在
handle_low_emotion_withdrawal中,将硬编码的任务名称映射{'Event': 'Event2', 'Event2': 'Event3'}改为配置驱动或集中管理,可以避免事件流逻辑到处散落,也更方便未来调整事件序列。 - 在
MapOperation.withdraw中,为战斗结果界面新增的连续hasattr检查,如果重构为一个单独的辅助函数,按顺序迭代已注册的处理器,而不是复制同样的模式四次,可能会更清晰、也更易维护。
面向 AI 代理的提示
Please address the comments from this code review:
## Overall Comments
- In `CampaignBase.handle_combat_low_emotion`, consider returning `True` when the low-emotion popup is handled and withdrawal is triggered so callers can short-circuit further handling consistently with the original method’s semantics.
- The hardcoded task name mapping `{'Event': 'Event2', 'Event2': 'Event3'}` in `handle_low_emotion_withdrawal` could be made configuration-driven or centralized to avoid scattering event flow logic and make future event sequence changes easier.
- The new chained `hasattr` checks in `MapOperation.withdraw` for battle result screens might be clearer and more maintainable if they are refactored into a single helper that iterates registered handlers in order instead of duplicating the same pattern four times.帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的评审。
Original comment in English
Hey - I've left some high level feedback:
- In
CampaignBase.handle_combat_low_emotion, consider returningTruewhen the low-emotion popup is handled and withdrawal is triggered so callers can short-circuit further handling consistently with the original method’s semantics. - The hardcoded task name mapping
{'Event': 'Event2', 'Event2': 'Event3'}inhandle_low_emotion_withdrawalcould be made configuration-driven or centralized to avoid scattering event flow logic and make future event sequence changes easier. - The new chained
hasattrchecks inMapOperation.withdrawfor battle result screens might be clearer and more maintainable if they are refactored into a single helper that iterates registered handlers in order instead of duplicating the same pattern four times.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `CampaignBase.handle_combat_low_emotion`, consider returning `True` when the low-emotion popup is handled and withdrawal is triggered so callers can short-circuit further handling consistently with the original method’s semantics.
- The hardcoded task name mapping `{'Event': 'Event2', 'Event2': 'Event3'}` in `handle_low_emotion_withdrawal` could be made configuration-driven or centralized to avoid scattering event flow logic and make future event sequence changes easier.
- The new chained `hasattr` checks in `MapOperation.withdraw` for battle result screens might be clearer and more maintainable if they are refactored into a single helper that iterates registered handlers in order instead of duplicating the same pattern four times.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f7cff4938
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Hey - 我发现了两个问题,并留下了一些总体反馈:
- 建议在
CampaignBase中初始化low_emotion_withdrawn(例如在__init__中),这样它的生命周期会更清晰,也避免依赖临时创建属性。 CampaignRun中硬编码的映射LOW_EMOTION_NEXT_EVENT = {'Event': 'Event2', 'Event2': 'Event3'}会把逻辑和具体任务名强耦合;你可能希望改为由配置或任务元数据驱动,这样在事件名称变更时仍能保持一致性。- 在
handle_low_emotion_withdrawal中,非公开 emotion 路径假设emotion.fleets非空且可索引;为了避免在边缘配置下出现运行时错误,最好增加对空或异常 fleet 列表的防护。
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider initializing `low_emotion_withdrawn` in `CampaignBase` (e.g., in `__init__`) so its lifecycle is clearer and you don't rely on ad-hoc attribute creation.
- The hard-coded `LOW_EMOTION_NEXT_EVENT = {'Event': 'Event2', 'Event2': 'Event3'}` mapping in `CampaignRun` couples the logic to specific task names; you might want to make this driven by configuration or task metadata so it stays consistent when event names change.
- In `handle_low_emotion_withdrawal`, the non-public emotion path assumes `emotion.fleets` is non-empty and indexed; it may be safer to guard against empty or malformed fleet lists to avoid runtime errors in edge configurations.
## Individual Comments
### Comment 1
<location path="tests/test_low_emotion_withdraw.py" line_range="46-55" />
<code_context>
+ campaign.handle_popup_cancel.assert_not_called()
+ campaign.handle_popup_confirm.assert_called_once_with('IGNORE_LOW_EMOTION')
+
+ def test_withdrawal_delays_current_task_to_emotion_recovery(self):
+ recovered = datetime(2026, 8, 14, 12, 0, 0)
+ fleet = Mock()
+ fleet.fleet = 1
+ fleet.current = 75
+ fleet.get_recovered.return_value = recovered
+ emotion = Mock(using_public=False)
+ emotion.fleets = [fleet, Mock()]
+ campaign = SimpleNamespace(
+ low_emotion_withdrawn=True,
+ emotion=emotion,
+ withdraw=Mock(side_effect=CampaignEnd('Withdraw')),
+ )
+ runner = CampaignRun.__new__(CampaignRun)
+ runner.__dict__['campaign'] = campaign
+ runner.__dict__['config'] = Mock()
+ runner.config.task.command = 'Event'
+ runner.config.FLEET_2 = 0
+
+ self.assertTrue(runner.handle_low_emotion_withdrawal())
</code_context>
<issue_to_address>
**suggestion (testing):** 为 `handle_low_emotion_withdrawal` 中的 `using_public`/`public_fleet` 分支增加测试覆盖。
当前测试只覆盖 `using_public=False`(单舰队和双舰队)。请再添加一个针对 `using_public=True` 分支的测试,其中设置 `emotion.public_fleet`。该测试应验证:只有 `public_fleet.current` 被设置为 0,并且 `public_fleet.get_recovered()` 的返回值被用作 `task_delay`。
</issue_to_address>
### Comment 2
<location path="tests/test_low_emotion_withdraw.py" line_range="146-155" />
<code_context>
+ def test_withdraw_processes_battle_result_before_waiting_for_stage(self):
</code_context>
<issue_to_address>
**suggestion (testing):** 扩展 `MapOperation` 的测试,以覆盖 `handle_withdraw_result` 中 `COMBAT_STATUS` 弹窗分支。
当所有特定处理函数都未消耗该界面时,`handle_withdraw_result` 会回退到 `handle_popup_confirm('COMBAT_STATUS')`。请添加一个测试:其中 `handle_battle_status`、`handle_exp_info`、`handle_get_ship` 和 `handle_get_items` 都返回 `False`,`handle_popup_confirm('COMBAT_STATUS')` 返回 `True`,并断言 `handle_withdraw_result()` 返回 `True`,以验证这个回退路径已被覆盖。
建议实现:
```python
def test_withdraw_processes_battle_result_before_waiting_for_stage(self):
operation = MapOperation.__new__(MapOperation)
operation.device = SimpleNamespace(screenshot=Mock())
operation.handle_battle_status = Mock(side_effect=[True, False])
operation.handle_exp_info = Mock(return_value=False)
operation.handle_get_ship = Mock(return_value=False)
operation.handle_get_items = Mock(return_value=False)
operation.handle_popup_confirm = Mock(return_value=False)
operation.appear_then_click = Mock(return_value=False)
operation.handle_auto_search_exit = Mock(return_value=False)
operation.appear = Mock(return_value=False)
def test_handle_withdraw_result_falls_back_to_combat_status_popup(self):
operation = MapOperation.__new__(MapOperation)
operation.device = SimpleNamespace(screenshot=Mock())
operation.handle_battle_status = Mock(return_value=False)
operation.handle_exp_info = Mock(return_value=False)
operation.handle_get_ship = Mock(return_value=False)
operation.handle_get_items = Mock(return_value=False)
operation.handle_popup_confirm = Mock(return_value=True)
result = operation.handle_withdraw_result()
self.assertTrue(result)
operation.handle_popup_confirm.assert_called_once_with('COMBAT_STATUS')
```
此更改假定 `MapOperation` 已在 `tests/test_low_emotion_withdraw.py` 中导入,并且 `handle_withdraw_result` 是 `MapOperation` 的实例方法。如果尚未导入 `MapOperation`,请在文件顶部添加 `from your_module_path import MapOperation`,并遵循现有的导入约定。
</issue_to_address>Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Original comment in English
Hey - I've found 2 issues, and left some high level feedback:
- Consider initializing
low_emotion_withdrawninCampaignBase(e.g., in__init__) so its lifecycle is clearer and you don't rely on ad-hoc attribute creation. - The hard-coded
LOW_EMOTION_NEXT_EVENT = {'Event': 'Event2', 'Event2': 'Event3'}mapping inCampaignRuncouples the logic to specific task names; you might want to make this driven by configuration or task metadata so it stays consistent when event names change. - In
handle_low_emotion_withdrawal, the non-public emotion path assumesemotion.fleetsis non-empty and indexed; it may be safer to guard against empty or malformed fleet lists to avoid runtime errors in edge configurations.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Consider initializing `low_emotion_withdrawn` in `CampaignBase` (e.g., in `__init__`) so its lifecycle is clearer and you don't rely on ad-hoc attribute creation.
- The hard-coded `LOW_EMOTION_NEXT_EVENT = {'Event': 'Event2', 'Event2': 'Event3'}` mapping in `CampaignRun` couples the logic to specific task names; you might want to make this driven by configuration or task metadata so it stays consistent when event names change.
- In `handle_low_emotion_withdrawal`, the non-public emotion path assumes `emotion.fleets` is non-empty and indexed; it may be safer to guard against empty or malformed fleet lists to avoid runtime errors in edge configurations.
## Individual Comments
### Comment 1
<location path="tests/test_low_emotion_withdraw.py" line_range="46-55" />
<code_context>
+ campaign.handle_popup_cancel.assert_not_called()
+ campaign.handle_popup_confirm.assert_called_once_with('IGNORE_LOW_EMOTION')
+
+ def test_withdrawal_delays_current_task_to_emotion_recovery(self):
+ recovered = datetime(2026, 8, 14, 12, 0, 0)
+ fleet = Mock()
+ fleet.fleet = 1
+ fleet.current = 75
+ fleet.get_recovered.return_value = recovered
+ emotion = Mock(using_public=False)
+ emotion.fleets = [fleet, Mock()]
+ campaign = SimpleNamespace(
+ low_emotion_withdrawn=True,
+ emotion=emotion,
+ withdraw=Mock(side_effect=CampaignEnd('Withdraw')),
+ )
+ runner = CampaignRun.__new__(CampaignRun)
+ runner.__dict__['campaign'] = campaign
+ runner.__dict__['config'] = Mock()
+ runner.config.task.command = 'Event'
+ runner.config.FLEET_2 = 0
+
+ self.assertTrue(runner.handle_low_emotion_withdrawal())
</code_context>
<issue_to_address>
**suggestion (testing):** Add coverage for `using_public`/`public_fleet` branch in `handle_low_emotion_withdrawal`.
Current tests only cover `using_public=False` (single and dual fleet). Please also add a test for the `using_public=True` branch where `emotion.public_fleet` is set. That test should ensure only `public_fleet.current` is set to 0 and that its `get_recovered()` result is used as the `task_delay` value.
</issue_to_address>
### Comment 2
<location path="tests/test_low_emotion_withdraw.py" line_range="146-155" />
<code_context>
+ def test_withdraw_processes_battle_result_before_waiting_for_stage(self):
</code_context>
<issue_to_address>
**suggestion (testing):** Extend `MapOperation` tests to cover the `COMBAT_STATUS` popup branch in `handle_withdraw_result`.
`handle_withdraw_result` falls back to `handle_popup_confirm('COMBAT_STATUS')` if none of the specific handlers consume the screen. Please add a test where `handle_battle_status`, `handle_exp_info`, `handle_get_ship`, and `handle_get_items` all return `False`, `handle_popup_confirm('COMBAT_STATUS')` returns `True`, and assert that `handle_withdraw_result()` returns `True`, to verify this fallback path is covered.
Suggested implementation:
```python
def test_withdraw_processes_battle_result_before_waiting_for_stage(self):
operation = MapOperation.__new__(MapOperation)
operation.device = SimpleNamespace(screenshot=Mock())
operation.handle_battle_status = Mock(side_effect=[True, False])
operation.handle_exp_info = Mock(return_value=False)
operation.handle_get_ship = Mock(return_value=False)
operation.handle_get_items = Mock(return_value=False)
operation.handle_popup_confirm = Mock(return_value=False)
operation.appear_then_click = Mock(return_value=False)
operation.handle_auto_search_exit = Mock(return_value=False)
operation.appear = Mock(return_value=False)
def test_handle_withdraw_result_falls_back_to_combat_status_popup(self):
operation = MapOperation.__new__(MapOperation)
operation.device = SimpleNamespace(screenshot=Mock())
operation.handle_battle_status = Mock(return_value=False)
operation.handle_exp_info = Mock(return_value=False)
operation.handle_get_ship = Mock(return_value=False)
operation.handle_get_items = Mock(return_value=False)
operation.handle_popup_confirm = Mock(return_value=True)
result = operation.handle_withdraw_result()
self.assertTrue(result)
operation.handle_popup_confirm.assert_called_once_with('COMBAT_STATUS')
```
This change assumes `MapOperation` is already imported in `tests/test_low_emotion_withdraw.py` and that `handle_withdraw_result` is an instance method on `MapOperation`. If `MapOperation` is not imported, add `from your_module_path import MapOperation` at the top of the file, matching existing import conventions.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f9c7900bd2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
嗨,我在这里给出了一些总体反馈:
LOW_EMOTION_NEXT_EVENT映射中对特定任务名称("Event"、"Event2"、"Event3")进行了硬编码;建议考虑将这些配置移动到单独的配置文件或使用更通用的机制,这样未来的事件序列就不需要在这里修改代码。handle_withdraw_result通过getattr根据方法名进行分发;如果这些处理函数以后被重构或重命名,现有逻辑会在不报错的情况下悄悄失效,所以更安全的做法可能是直接引用已绑定的方法,或者在一个集中位置维护统一的结果处理函数列表。
面向 AI 代理的提示词
请根据本次代码评审中的评论进行修改:
## 总体评论
- `LOW_EMOTION_NEXT_EVENT` 映射中对特定任务名称(`"Event"`、`"Event2"`、`"Event3"`)进行了硬编码;建议考虑将这些配置移动到单独的配置文件或使用更通用的机制,这样未来的事件序列就不需要在这里修改代码。
- `handle_withdraw_result` 通过 `getattr` 根据方法名进行分发;如果这些处理函数以后被重构或重命名,现有逻辑会在不报错的情况下悄悄失效,所以更安全的做法可能是直接引用已绑定的方法,或者在一个集中位置维护统一的结果处理函数列表。帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English
Hey - I've left some high level feedback:
- The LOW_EMOTION_NEXT_EVENT mapping hardcodes specific task names ('Event', 'Event2', 'Event3'); consider moving this to a configuration or a more generic mechanism so future event sequences don’t require code changes here.
- handle_withdraw_result dispatches on method names via getattr; if these handlers are refactored or renamed later this will silently stop working, so it may be safer to reference the bound methods directly or centralize the list of result handlers in one place.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The LOW_EMOTION_NEXT_EVENT mapping hardcodes specific task names ('Event', 'Event2', 'Event3'); consider moving this to a configuration or a more generic mechanism so future event sequences don’t require code changes here.
- handle_withdraw_result dispatches on method names via getattr; if these handlers are refactored or renamed later this will silently stop working, so it may be safer to reference the bound methods directly or centralize the list of result handlers in one place.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd23d6cc5d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for fleet in fleets: | ||
| fleet.current = 0 | ||
| emotion.record() | ||
| recovered = max(fleet.get_recovered() for fleet in fleets) |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5e786aa5b6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
嗨,我发现了 1 个问题,并留下了一些总体反馈:
- 在
handle_low_emotion_withdrawal中,你先调用了emotion.update(),然后再调用emotion.get_recovered_for_battle(),而该方法内部又会再次调用update()/record()/show();建议只依赖一条路径(例如只通过辅助方法)来完成这类操作,以避免重复的状态更新和额外的 IO。 get_low_emotion_next_event_task每次调用都会重新解析并过滤调度器的优先级列表;如果这个方法被频繁调用,考虑在每个配置实例上缓存解析后的事件链,以减少重复解析并提升性能。
给 AI Agent 的 Prompt
请根据以下代码评审意见进行修改:
## 总体意见
- 在 `handle_low_emotion_withdrawal` 中,你先调用了 `emotion.update()`,然后再调用 `emotion.get_recovered_for_battle()`,而该方法内部又会再次调用 `update()`/`record()`/`show()`;建议只依赖一条路径(例如只通过辅助方法)来完成这类操作,以避免重复的状态更新和额外的 IO。
- `get_low_emotion_next_event_task` 每次调用都会重新解析并过滤调度器的优先级列表;如果这个方法被频繁调用,考虑在每个配置实例上缓存解析后的事件链,以减少重复解析并提升性能。
## 具体意见
### 评论 1
<location path="module/combat/emotion.py" line_range="339-346" />
<code_context>
- def _check_reduce(self, battle):
- """检查战斗带来的情绪减少。
+ def get_recovered_for_battle(self, battle):
+ """计算完成下一次战役所需的情绪恢复时间。
</code_context>
<issue_to_address>
**suggestion (performance):** 在情绪处理流程中重复调用 update/record/show 可能是多余的,并会影响性能。
`get_recovered_for_battle` 的两个分支都会调用 `self.update()`, `self.record()`, 和 `self.show()`,而 `handle_low_emotion_withdrawal` 在调用 `get_recovered_for_battle` 之前还会修改 `fleet.current` 并调用一次 `emotion.record()`。这会导致一次低情绪事件触发多轮记录/展示流程。建议将这些副作用调用集中到单一位置(要么只在 `get_recovered_for_battle` 内部,要么只在它的调用方),以减少冗余的文件系统/UI 操作,并让恢复逻辑更易理解和维护。
建议的实现:
```python
def get_recovered_for_battle(self, battle):
"""计算完成下一次战役所需的情绪恢复时间。
本方法负责在计算完成后统一进行情绪状态的更新与记录,
调用方无需再重复调用 update()/record()/show() 相关方法。
Returns:
datetime: 扣除下一次战役的预计情绪后达到控制阈值的时间。
"""
# 计算完成下一次战役的预计情绪值以及恢复到阈值所需时间。
# 注意:这里集中进行情绪状态更新与记录,避免重复的文件和 UI 操作。
recovered_at = self._calculate_recovered_for_battle(battle)
# 统一集中处理副作用:更新情绪、记录日志、刷新展示
self.update()
self.record()
self.show()
return recovered_at
```
```python
def reduce_shipwreck(self):
return 10
def _calculate_recovered_for_battle(self, battle):
"""内部纯计算方法,仅负责返回恢复时间,不产生副作用。
Args:
battle: 用于计算下一次战役带来的情绪消耗及恢复时间的战役对象。
Returns:
datetime: 扣除下一次战役的预计情绪后达到控制阈值的时间。
"""
# 这里应包含原来 get_recovered_for_battle 中的纯计算逻辑,
# 将其中的 self.update()/self.record()/self.show() 等副作用调用挪到 get_recovered_for_battle 中。
#
# 由于当前上下文缺失,这里给出一个占位实现,开发者需要用原有计算逻辑替换。
#
# 示例:假设有 self.current_emotion, self.threshold, self.recovery_rate 等字段,
# 可以根据 battle 的情绪消耗估算恢复到阈值的时间。
# 下面的代码仅作为结构占位,避免运行错误。
import datetime
# 占位逻辑:立即达到阈值,返回当前时间
return datetime.datetime.now()
```
1. 将原先 `get_recovered_for_battle` 中的纯计算逻辑(不包括 `self.update()`, `self.record()`, `self.show()` 调用)移动到新建的 `_calculate_recovered_for_battle` 方法中,并删除原方法内的这些副作用调用,只保留在 `get_recovered_for_battle` 中集中调用。
2. 在所有调用 `get_recovered_for_battle` 的地方(特别是 `handle_low_emotion_withdrawal`)删除额外的 `emotion.record()`, `emotion.update()`, `emotion.show()` 调用,确保每次低情绪事件只会触发一次记录/展示流程。
3. 如果 `handle_low_emotion_withdrawal` 在调用 `get_recovered_for_battle` 前后有独立的情绪记录(例如专门记录撤退事件),将这类业务性记录与通用情绪状态记录区分开:保留业务特定记录,但去除与状态更新重复的通用记录调用。
4. 检查是否存在其他分支或辅助方法在同一个低情绪处理流程中额外调用 `self.update()`, `self.record()`, `self.show()`;如有,统一改为只通过 `get_recovered_for_battle` 进行一次状态更新与展示,以避免多次文件系统和 UI 操作。
</issue_to_address>帮我变得更有用!请在每条评论上点 👍 或 👎,我会根据你的反馈改进后续评审。
Original comment in English
Hey - I've found 1 issue, and left some high level feedback:
- In
handle_low_emotion_withdrawalyou callemotion.update()and thenemotion.get_recovered_for_battle(), which itself callsupdate()/record()/show()again; consider relying on one path (e.g. only the helper) to avoid redundant state updates and extra IO. get_low_emotion_next_event_taskrecomputes and filters the parsed scheduler priority list on every call; if this is used frequently, caching the parsed event chain per config instance would reduce repeated parsing and improve performance.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- In `handle_low_emotion_withdrawal` you call `emotion.update()` and then `emotion.get_recovered_for_battle()`, which itself calls `update()`/`record()`/`show()` again; consider relying on one path (e.g. only the helper) to avoid redundant state updates and extra IO.
- `get_low_emotion_next_event_task` recomputes and filters the parsed scheduler priority list on every call; if this is used frequently, caching the parsed event chain per config instance would reduce repeated parsing and improve performance.
## Individual Comments
### Comment 1
<location path="module/combat/emotion.py" line_range="339-346" />
<code_context>
- def _check_reduce(self, battle):
- """检查战斗带来的情绪减少。
+ def get_recovered_for_battle(self, battle):
+ """计算完成下一次战役所需的情绪恢复时间。
</code_context>
<issue_to_address>
**suggestion (performance):** Repeated update/record/show calls in emotion handling may be redundant and impact performance.
Both branches of `get_recovered_for_battle` call `self.update()`, `self.record()`, and `self.show()`, while `handle_low_emotion_withdrawal` also mutates `fleet.current` and calls `emotion.record()` before invoking `get_recovered_for_battle`. This causes multiple record/show cycles for a single low-emotion event. Centralize these side-effect calls in a single place (either only inside `get_recovered_for_battle` or only in its caller) to reduce redundant filesystem/UI work and keep the recovery logic easier to follow.
Suggested implementation:
```python
def get_recovered_for_battle(self, battle):
"""计算完成下一次战役所需的情绪恢复时间。
本方法负责在计算完成后统一进行情绪状态的更新与记录,
调用方无需再重复调用 update()/record()/show() 相关方法。
Returns:
datetime: 扣除下一次战役的预计情绪后达到控制阈值的时间。
"""
# 计算完成下一次战役的预计情绪值以及恢复到阈值所需时间。
# 注意:这里集中进行情绪状态更新与记录,避免重复的文件和 UI 操作。
recovered_at = self._calculate_recovered_for_battle(battle)
# 统一集中处理副作用:更新情绪、记录日志、刷新展示
self.update()
self.record()
self.show()
return recovered_at
```
```python
def reduce_shipwreck(self):
return 10
def _calculate_recovered_for_battle(self, battle):
"""内部纯计算方法,仅负责返回恢复时间,不产生副作用。
Args:
battle: 用于计算下一次战役带来的情绪消耗及恢复时间的战役对象。
Returns:
datetime: 扣除下一次战役的预计情绪后达到控制阈值的时间。
"""
# 这里应包含原来 get_recovered_for_battle 中的纯计算逻辑,
# 将其中的 self.update()/self.record()/self.show() 等副作用调用挪到 get_recovered_for_battle 中。
#
# 由于当前上下文缺失,这里给出一个占位实现,开发者需要用原有计算逻辑替换。
#
# 示例:假设有 self.current_emotion, self.threshold, self.recovery_rate 等字段,
# 可以根据 battle 的情绪消耗估算恢复到阈值的时间。
# 下面的代码仅作为结构占位,避免运行错误。
import datetime
# 占位逻辑:立即达到阈值,返回当前时间
return datetime.datetime.now()
```
1. 将原先 `get_recovered_for_battle` 中的纯计算逻辑(不包括 `self.update()`, `self.record()`, `self.show()` 调用)移动到新建的 `_calculate_recovered_for_battle` 方法中,并删除原方法内的这些副作用调用,只保留在 `get_recovered_for_battle` 中集中调用。
2. 在所有调用 `get_recovered_for_battle` 的地方(特别是 `handle_low_emotion_withdrawal`)删除额外的 `emotion.record()`, `emotion.update()`, `emotion.show()` 调用,确保每次低情绪事件只会触发一次记录/展示流程。
3. 如果 `handle_low_emotion_withdrawal` 在调用 `get_recovered_for_battle` 前后有独立的情绪记录(例如专门记录撤退事件),将这类业务性记录与通用情绪状态记录区分开:保留业务特定记录,但去除与状态更新重复的通用记录调用。
4. 检查是否存在其他分支或辅助方法在同一个低情绪处理流程中额外调用 `self.update()`, `self.record()`, `self.show()`;如有,统一改为只通过 `get_recovered_for_battle` 进行一次状态更新与展示,以避免多次文件系统和 UI 操作。
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
都计算心情了为什么还会出现红脸弹窗?你这个功能具体表现是什么?测了吗 |
已经测试了一天了,另外现在心情计算方式·是通过计数来计算的,不准确,有时候发生各种意外情况比如沉船会导致心情提前消耗殆尽但是记录却还有很多,继而导致alas只要遇到心情弹窗但是心情值没有正确归零然后就是报错重启,继续任务,然后再次弹窗,然后接着重启,无限循环,我既然这样,我通过识别心情弹窗的方式直接把比如活动图1的心情归零,然后调度器就可以正确识别然后延后任务并执行活动图2,活动图3,都延后则是去其他任务直到心情恢复然后继续活动任务 |
官源没办法识别沉船的心情然后-10心情,重新改成官源又不现实,你的意思就是心情统计不准确?不会吧,除了s胜之外都会-10心情,应该只会算少心情不会算多心情吧,不过加个保底机制也行 |
|
你手动打几下不是手贱吗?不更新心情肯定你自己的问题啊,做好了再说吧 |
手贱?你不开荒的吗,什么叫我的问题,这个毛病都多久了,遇到心情弹窗就一直重启一直无限循环,这不是bug是什么? |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d4128669d2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
主线同步了这个功能,遇到心情弹窗自动清零出击舰队的心情并延后然后执行调度器的下一个任务 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5a98c4fe40
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
这认真的吗?你自己开完荒不手动填心情是吧?怎么现在脚本还能帮你填?虽然帮你填确实有想法在写,还有你自己不手贱怎么可能计算心情失误,你说现在心情恢复机制有问题还好说,你自己打了不告诉alas然后一直重启报错,想不被弹窗恶心自己开无视红脸不行吗? |
无视红脸不会掉好感的吗 |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4a3de48089
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
?为什么不用紧急委托呢?为什么你自己动了心情不更新alas的心情呢?你现在是怎么刷活动的?活动图-1-2-3都开着?不同的编队打? |
|
测过吗?有个保底也行,其他正常情况会受影响吗 |
3个不同的编队刷pt啊,问题是我说过只有动心情这个才会导致bug出现?你以为我没有试过改心情吗,没有用,改了还是一样的结果,还是会因为有各种原因导致有误差,到最后弹窗了,心情值显示70,这合理吗?另外紧急委托的换船我不想用,还有用紧急委托只是治标不治本,还是没有解决无限循环的问题 |
|
我看看这心情到底怎么回事吧,正常来说你自己不手动改心情,设置正确的情况下应该没问题的啊,非S评价直接-10心情啊,奇了怪了 |
你直接提个issue,把log和配置发过来我看看 |
变更
原因
原流程会在忽略心情的配置下确认强制出击;而游戏端提示已低心情时,本地记录可能仍是较高的旧值,导致延后时间被计算为当前时间。
验证
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
新特性:
错误修复:
功能改进:
测试:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
新功能:
缺陷修复:
优化与增强:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
新特性:
错误修复:
功能改进:
测试:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
新功能:
错误修复:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
新特性:
错误修复:
功能改进:
测试:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
新功能:
缺陷修复:
优化与增强:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
新特性:
错误修复:
功能改进:
测试:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
通过在活动中推迟当前事件任务、调整情绪恢复的调度,并确保 UI 可靠返回到关卡界面,来处理低情绪撤退情形。
New Features:
Bug Fixes:
Enhancements:
Tests:
Original summary in English
Summary by Sourcery
Handle low-emotion withdrawal in campaigns by postponing the current event task, adjusting emotion recovery scheduling, and ensuring the UI reliably returns to the stage screen.
New Features:
Bug Fixes:
Enhancements:
Tests: