引导式 BP
引导式 BP
首次启动导览和页面 Product Tour 见 product-tour-and-onboarding.md。Product Tour 可以引导用户点击“开启对局引导”并等待相关 signal,但不替代 GameGuidanceService,也不重写对局引导的规则推进、计时器、导航和高亮业务逻辑。
源码入口:GameGuidanceService、GameRule.json。
核心服务
GameGuidanceService 实现对局引导功能。它依赖:
| 依赖 | 用途 |
|---|---|
ISharedDataService | 读取当前对局、设置 Ban 位数量、启动计时器 |
INavigationService | 切换后台页面 |
IInfoBarService | 显示非阻断提示 |
WeakReferenceMessenger | 发送高亮消息 |
规则文件路径固定为:
{AppDomain.CurrentDomain.BaseDirectory}\GameRule.json主项目文件中设置了 GameRule.json 总是复制到输出目录。
规则结构
GameRule.json 是 GameProgress -> GameProperty 的字典。GameProperty 包含:
| 字段 | 说明 |
|---|---|
SurCurrentBan | 当前局求生者 Ban 位数 |
HunCurrentBan | 当前局监管者 Ban 位数 |
SurGlobalBan | 全局求生者 Ban 位数 |
HunGlobalBan | 全局监管者 Ban 位数 |
WorkFlow | 步骤列表 |
每个步骤包含:
| 字段 | 说明 |
|---|---|
Action | GameAction,如 BanMap、PickSur |
Index | 需要高亮的索引列表,可为 null |
Time | 计时器秒数,可为 null |
启动流程
StartGuidance() 会:
- 读取当前
CurrentGame.GameProgress对应规则。 - 如果是
GameProgress.Free或规则不支持,提示自由赛不可用。 - 设置当前/全局 Ban 位数量。
- 从记录更新双方全局 Ban。
- 设置
IsGuidanceStarted = true。 - 立即进入下一步。
HandleStepChange 会:
- 在更新
_currentStep前读取当前步骤,作为步骤变化事件的上一步信息。 - 更新
_currentStep。 - 如果步骤不是
PickCamp,按_actionToPage导航到对应后台页面。 - 调用
_sharedDataService.TimerStart(thisStep.Time)。 - 等待 250ms,让待选框动画/页面状态就位。
- 构造包含当前步骤和上一步骤 payload 的
GameGuidanceStepChangedEventArgs。 - 触发权威步骤事件
GuidanceStepChanged,前台行为运行时通过Guidance.StepChanged消费它。 - 触发后台高亮事件
GuidanceHighlightChanged。 - 发送后台 UI 便利消息
HighlightMessage(thisStep.Action, thisStep.Index)。 - 返回本地化后的步骤名称。
地图呼吸灯由 MapBpPageViewModel 订阅 GuidanceStepChanged 和 GuidanceStateChanged 联动,引导服务不直接设置灯效。进入 BanMap / PickMap 步骤时自动打开地图 V2 呼吸灯,离开地图步骤、取消或完成引导时关闭。普通非地图步骤之间切换不改动手动设置的呼吸灯状态。启动时提前解析地图页 ViewModel,确保不开启页面导航时也能收到引导事件。
选中地图时,共享服务关闭呼吸灯总开关并发布所有地图的边框隐藏状态,无需等到推进下一步。
MoveToStepAsync 成功返回 null、失败返回错误文本,是允许直接定位的服务入口。Start/Next/Prev/Stop/Complete 及定位在存在 Application Dispatcher 时由服务层切回 UI,调用方不能从 OCR 线程直接写导航、计时器与共享状态。自动追赶只能逐步调用 Next/Prev;手动同步可直接定位。具体槽位目标、历史补偿与纠偏阈值统一见 SmartBP,避免在 Guidance 文档复制另一套对账算法。
行为事件 payload
Guidance.StepChanged 同时暴露当前步骤和上一步骤 payload。当前步骤 payload 适合启动动画,上一步骤 payload 适合停止由切换前引导步骤启动的动画。首次进入步骤时,所有 Previous* 值为 null,PreviousIndexesText 为 []。
Guidance.Cancelled 在用户取消当前引导时触发,Guidance.Stopped 在引导以停止/完成语义结束时触发。两者 payload 使用稳定机器值:Reason、Time、PreviousStepIndex、PreviousAction、PreviousIndexes 和 PreviousIndexesText,不包含本地化操作名。Loop 行为的 StopTriggers 应把这些事件与 Guidance.StepChanged 的上一步过滤一起配置,避免取消引导后循环动画残留。
列表索引的字符串过滤应优先使用 IndexesText / PreviousIndexesText,其格式稳定为 [1, 2]。高亮变化与清除事件只用于后台引导 UI,不暴露给前台行为触发器。
例如,启动求生者 1 号位呼吸灯:
Event.Action == PickSur
Event.IndexesText contains "1"停止由上一步启动的求生者 1 号位呼吸灯:
Event.PreviousAction == PickSur
Event.PreviousIndexesText contains "1"Action 到页面映射
| Action | 页面 |
|---|---|
BanMap / PickMap | MapBpPage |
BanSur | BanSurPage |
BanHun | BanHunPage |
PickSur / DistributeChara / PickHun | PickPage |
PickSurTalent / PickHunTalent | TalentPage |
PickCamp 当前不会触发页面切换。
维护建议
规则应跟随实际第五人格赛事规则变化维护,但本仓库中的 GameRule.json 不是外部权威规则源。修改规则时应:
- 明确对应哪个
GameProgress。 - 检查 Ban 位数量与页面控件容量一致。
- 确认
GameAction是否已映射到后台页面。 - 检查
Index是否能被对应页面的高亮逻辑理解。 - 自由赛
GameProgress.Free当前不支持引导式 BP,这是代码显式行为。
