diff --git a/CHANGELOG.md b/CHANGELOG.md index 5864bdac..5dfdb632 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,7 +44,9 @@ ### 对局与决策 -- 悬赏决策按 11 局官方截图的结构出卡:第 3 回合是固定的「接下来两场作战」组合,第 9 回合是一组首领悬赏加便宜的悬赏,第 11 回合是特异巨兽组合加 1 资金卡;多轮悬赏不再出现。 +- 悬赏决策按 22 局官方截图的结构出卡:第 3 回合是 10 套固定的「接下来两场作战」组合之一,第 9 回合是 6 组首领悬赏之一,第 11 回合从截图里见过的 7 组「下场战斗」悬赏中抽;每组里出 6 张不同的卡,多轮悬赏不再出现。 +- 绝境 / 终极第 11 回合按官方比例出悬赏决策、机密商店或战术决策(22 局里 14 / 4 / 4),不再出道具补给。 +- 机密商店和战术决策和官方一样可能出现两张相同的卡,各算一张,可以分别被选走。第 11 回合的机密商店按官方:2 件 VI 阶、至少 1 件 V 阶和 1 枚盟约之币;第 11 回合的战术决策只出增益卡。 - 隐秘核心的「伤害超过 X%」播报只算这一场领袖的伤害,上一回合的播报不会拖到下一回合。 - 播报按官方优先级排队,领袖伤害播报不会被升级调度中心等播报挤掉。 - 修复联防中隐德来希的心烛在超时时被算成漏怪、导致战斗结果被服务器拒绝的问题。 diff --git a/data/choices.json b/data/choices.json index 8573663e..19e9be0f 100644 --- a/data/choices.json +++ b/data/choices.json @@ -1 +1 @@ -{"events":{"artifact_paid_1":{"id":"artifact_paid_1","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_1_s":{"id":"artifact_paid_1_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_2":{"id":"artifact_paid_2","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_2_s":{"id":"artifact_paid_2_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_3":{"id":"artifact_paid_3","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_3_s":{"id":"artifact_paid_3_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_4":{"id":"artifact_paid_4","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_4_s":{"id":"artifact_paid_4_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_5":{"id":"artifact_paid_5","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_5_s":{"id":"artifact_paid_5_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"bossInitial_1":{"id":"bossInitial_1","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_1_s":{"id":"bossInitial_1_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_2":{"id":"bossInitial_2","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_2_s":{"id":"bossInitial_2_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_3":{"id":"bossInitial_3","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_3_s":{"id":"bossInitial_3_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_4":{"id":"bossInitial_4","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_4_s":{"id":"bossInitial_4_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_5":{"id":"bossInitial_5","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_5_s":{"id":"bossInitial_5_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_6":{"id":"bossInitial_6","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_6_s":{"id":"bossInitial_6_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_1":{"id":"bounty_hunter_1","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_1_s":{"id":"bounty_hunter_1_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_2":{"id":"bounty_hunter_2","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_2_s":{"id":"bounty_hunter_2_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_3":{"id":"bounty_hunter_3","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_3_s":{"id":"bounty_hunter_3_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_4":{"id":"bounty_hunter_4","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_4_s":{"id":"bounty_hunter_4_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_5":{"id":"bounty_hunter_5","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_5_s":{"id":"bounty_hunter_5_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_6":{"id":"bounty_hunter_6","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_6_s":{"id":"bounty_hunter_6_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_7":{"id":"bounty_hunter_7","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_7_s":{"id":"bounty_hunter_7_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_8":{"id":"bounty_hunter_8","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_8_s":{"id":"bounty_hunter_8_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_9":{"id":"bounty_hunter_9","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_9_s":{"id":"bounty_hunter_9_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_10":{"id":"bounty_hunter_10","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_10_s":{"id":"bounty_hunter_10_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_11":{"id":"bounty_hunter_11","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_11_s":{"id":"bounty_hunter_11_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_12":{"id":"bounty_hunter_12","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_12_s":{"id":"bounty_hunter_12_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_13":{"id":"bounty_hunter_13","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_13_s":{"id":"bounty_hunter_13_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_14":{"id":"bounty_hunter_14","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_14_s":{"id":"bounty_hunter_14_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_15":{"id":"bounty_hunter_15","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_15_s":{"id":"bounty_hunter_15_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"buff_select_1":{"id":"buff_select_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_1_s":{"id":"buff_select_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"buff_select_2":{"id":"buff_select_2","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_2_s":{"id":"buff_select_2_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"buff_select_3":{"id":"buff_select_3","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_3_s":{"id":"buff_select_3_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"buff_select_4":{"id":"buff_select_4","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_4_s":{"id":"buff_select_4_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"enemy_initial_1":{"id":"enemy_initial_1","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_1_s":{"id":"enemy_initial_1_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_2":{"id":"enemy_initial_2","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_2_s":{"id":"enemy_initial_2_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_3":{"id":"enemy_initial_3","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_3_s":{"id":"enemy_initial_3_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_4":{"id":"enemy_initial_4","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_4_s":{"id":"enemy_initial_4_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_5":{"id":"enemy_initial_5","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_5_s":{"id":"enemy_initial_5_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_6":{"id":"enemy_initial_6","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_6_s":{"id":"enemy_initial_6_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_7":{"id":"enemy_initial_7","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_7_s":{"id":"enemy_initial_7_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_8":{"id":"enemy_initial_8","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_8_s":{"id":"enemy_initial_8_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_9":{"id":"enemy_initial_9","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_9_s":{"id":"enemy_initial_9_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_10":{"id":"enemy_initial_10","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_10_s":{"id":"enemy_initial_10_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"equip_free_1":{"id":"equip_free_1","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_1_tr":{"id":"equip_free_1_tr","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":true},"equip_free_2":{"id":"equip_free_2","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_2_s":{"id":"equip_free_2_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"supply","solo":true,"training":false},"equip_free_3":{"id":"equip_free_3","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_3_s":{"id":"equip_free_3_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"supply","solo":true,"training":false},"equip_free_4":{"id":"equip_free_4","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_4_s":{"id":"equip_free_4_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"supply","solo":true,"training":false},"hardbuff_select_1":{"id":"hardbuff_select_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"hardbuff_select_1_s":{"id":"hardbuff_select_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":true,"training":false},"hardbuff_select_2":{"id":"hardbuff_select_2","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"hardbuff_select_2_s":{"id":"hardbuff_select_2_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":true,"training":false},"hardbuff_select_3":{"id":"hardbuff_select_3","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"hardbuff_select_3_s":{"id":"hardbuff_select_3_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":true,"training":false},"hunter_band_1":{"id":"hunter_band_1","choiceType":"PERSONAL_CHOOSE","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false,"usedBy":["chess_item_6_03_m","chess_item_6_01_m"]},"terrain_m01_1":{"id":"terrain_m01_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m01_1_s":{"id":"terrain_m01_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m02_1":{"id":"terrain_m02_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m02_1_s":{"id":"terrain_m02_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m02_2":{"id":"terrain_m02_2","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m02_2_s":{"id":"terrain_m02_2_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m03_1":{"id":"terrain_m03_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m03_1_s":{"id":"terrain_m03_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m04_1":{"id":"terrain_m04_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m04_1_s":{"id":"terrain_m04_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m06_1":{"id":"terrain_m06_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m06_1_s":{"id":"terrain_m06_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m07_1":{"id":"terrain_m07_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m07_1_s":{"id":"terrain_m07_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false}},"families":{"bounty":{"name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","cards":"bountyDrafts[schedule[*].bountyDraft] — the official draft structure of the round (initial: one of the R3 sets; boss: an R9 group + cheap fill; hunter: an R11 group — one 特异III giant + tier-II cards — + tier-I fill, one per faction series), over cards.bounty entries with draft: true and that draftPool"},"supply":{"name":"道具补给","desc":"无需消耗资金,获得装备补给。","cards":"random normal EQUIP items in schedule[*].supplyTiers (duplicates allowed)"},"shop":{"name":"机密商店","desc":"无需消耗资金,获得装备补给。","cards":"random normal EQUIP items of any tier I–VI (duplicates allowed)"},"tactic":{"name":"战术决策","desc":"选择战术增益。","cards":"cards.tactic (terrain cards only for the match stage)"}},"format":{"multi":{"cards":6,"pickOrder":"random","firstPickSec":30,"otherPickSec":16,"onTimeout":"autoPickRandom","eachPlayerPicks":1},"solo":{"cards":3,"timer":null},"opensAfterIncome":true},"cards":{"bounty":[{"effectId":"enemyeffect_1","name":"无人机护障·P·战术特训","desc":"为自身下场作战添加3只无人机护障·P,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1355_mrfly_2","count":3,"adds":[{"enemyKey":"enemy_1355_mrfly_2","count":4,"coin":2,"rounds":1,"payout":"perfect","buffKey":"next_battle_add_enemy_win_gain_coin"},{"enemyKey":"enemy_1355_mrfly_2","count":3,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":null},{"effectId":"enemyeffect_2","name":"法术大师A2·多轮战术特训","desc":"之后的每场作战添加2只法术大师A2,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":99,"multiRound":true,"enemyKey":"enemy_1041_lazerd_2","count":2,"adds":[{"enemyKey":"enemy_1041_lazerd_2","count":2,"coin":2,"rounds":99,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":null},{"effectId":"enemyeffect_3_2","name":"法术大师A2·悬赏","desc":"为自身下场作战添加1只法术大师A2,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1041_lazerd_2","count":1,"adds":[{"enemyKey":"enemy_1041_lazerd_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":3},{"effectId":"enemyeffect_3_2_e","name":"“萨科塔之眼”·悬赏","desc":"为自身下场作战添加1只“萨科塔之眼”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10084_hlegle","count":1,"adds":[{"enemyKey":"enemy_10084_hlegle","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_3_3","name":"元核孽生者·悬赏","desc":"为自身下场作战添加1只元核孽生者,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1439_dslntf","count":1,"adds":[{"enemyKey":"enemy_1439_dslntf","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":3},{"effectId":"enemyeffect_3_3_e","name":"幽灵组长·悬赏","desc":"为自身下场作战添加1只幽灵组长,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1026_aghost","count":1,"adds":[{"enemyKey":"enemy_1026_aghost","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_3_4","name":"山海众头目·悬赏","desc":"为自身下场作战添加1只山海众头目,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1299_ymkilr","count":1,"adds":[{"enemyKey":"enemy_1299_ymkilr","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":3},{"effectId":"enemyeffect_3_4_e","name":"重装防御者·悬赏","desc":"为自身下场作战添加1只重装防御者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1006_shield","count":1,"adds":[{"enemyKey":"enemy_1006_shield","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_3_5_e","name":"重弩突袭者·悬赏","desc":"为自身下场作战添加1只重弩突袭者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1404_msnip","count":1,"adds":[{"enemyKey":"enemy_1404_msnip","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_4","name":"山海众头目·多轮悬赏","desc":"之后的每场作战添加1只山海众头目,将其击倒者获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_1299_ymkilr","count":1,"adds":[{"enemyKey":"enemy_1299_ymkilr","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_5","name":"鸭爵·悬赏","desc":"为自身下场作战添加1只鸭爵,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2001_duckmi","count":1,"adds":[{"enemyKey":"enemy_2001_duckmi","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_5_1","name":"源石虫·特训","desc":"为自身下场作战添加1只源石虫,但不获得资金","tier":1,"coin":0,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1007_slime","count":1,"adds":[{"enemyKey":"enemy_1007_slime","count":1,"coin":0,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":5},{"effectId":"enemyeffect_6","name":"高普尼克·悬赏","desc":"为自身下场作战添加1只高普尼克,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2002_bearmi","count":1,"adds":[{"enemyKey":"enemy_2002_bearmi","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_7","name":"流泪小子·悬赏","desc":"为自身下场作战添加1只流泪小子,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2034_sythef","count":1,"adds":[{"enemyKey":"enemy_2034_sythef","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_8","name":"圆仔·悬赏","desc":"为自身下场作战添加1只圆仔,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2085_skzjxd","count":1,"adds":[{"enemyKey":"enemy_2085_skzjxd","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_10_1","name":"战术特训·飞行I","desc":"为自身下场战斗添加1只妖怪,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1005_yokai","count":1,"adds":[{"enemyKey":"enemy_1005_yokai","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":10},{"effectId":"enemyeffect_10_2","name":"战术特训·飞行II","desc":"为自身下场战斗添加1只暴鸰,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1040_bombd","count":1,"adds":[{"enemyKey":"enemy_1040_bombd","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":10},{"effectId":"enemyeffect_10_3","name":"战术特训·飞行III","desc":"为自身下场战斗添加1只帝国炮火中枢先兆者,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1112_emppnt_2","count":1,"adds":[{"enemyKey":"enemy_1112_emppnt_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":10},{"effectId":"enemyeffect_10_4","name":"悬赏·飞行I","desc":"为自身接下来两场作战添加1只妖怪,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1005_yokai","count":1,"adds":[{"enemyKey":"enemy_1005_yokai","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10},{"effectId":"enemyeffect_10_5","name":"悬赏·飞行II","desc":"为自身接下来两场作战添加1只暴鸰,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1040_bombd","count":1,"adds":[{"enemyKey":"enemy_1040_bombd","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10},{"effectId":"enemyeffect_10_6","name":"悬赏·飞行III","desc":"为自身接下来两场作战添加1只法术大师A1,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1041_lazerd","count":1,"adds":[{"enemyKey":"enemy_1041_lazerd","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10},{"effectId":"enemyeffect_10_7","name":"悬赏·飞行I","desc":"为自身下场战斗添加1只法术大师A2,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1041_lazerd_2","count":1,"adds":[{"enemyKey":"enemy_1041_lazerd_2","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":10},{"effectId":"enemyeffect_10_8","name":"悬赏·飞行II","desc":"为自身下场战斗添加1只枯朽萃聚使徒,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1321_wdarft","count":1,"adds":[{"enemyKey":"enemy_1321_wdarft","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":10},{"effectId":"enemyeffect_11_1","name":"战术特训·频次I","desc":"为自身下场战斗添加1只磨砻,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1195_sfyin","count":1,"adds":[{"enemyKey":"enemy_1195_sfyin","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":11},{"effectId":"enemyeffect_11_2","name":"战术特训·频次II","desc":"为自身下场战斗添加1只烹泉,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1203_sfhu","count":1,"adds":[{"enemyKey":"enemy_1203_sfhu","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":11},{"effectId":"enemyeffect_11_3","name":"战术特训·频次III","desc":"为自身下场战斗添加1只新硎,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1207_sfji_2","count":1,"adds":[{"enemyKey":"enemy_1207_sfji_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":11},{"effectId":"enemyeffect_11_4","name":"悬赏·频次I","desc":"为自身接下来两场作战添加1只磨砻,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1195_sfyin","count":1,"adds":[{"enemyKey":"enemy_1195_sfyin","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":11},{"effectId":"enemyeffect_11_5","name":"悬赏·频次II","desc":"为自身接下来两场作战添加1只烹泉,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1203_sfhu","count":1,"adds":[{"enemyKey":"enemy_1203_sfhu","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":11},{"effectId":"enemyeffect_11_6","name":"悬赏·频次III","desc":"为自身接下来两场作战添加1只清明,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1209_sfden","count":1,"adds":[{"enemyKey":"enemy_1209_sfden","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":11},{"effectId":"enemyeffect_11_7","name":"悬赏·频次I","desc":"为自身下场战斗添加1只沏虹,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1203_sfhu_2","count":1,"adds":[{"enemyKey":"enemy_1203_sfhu_2","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":11},{"effectId":"enemyeffect_11_8","name":"悬赏·频次II","desc":"为自身下场战斗添加1只新硎,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1207_sfji_2","count":1,"adds":[{"enemyKey":"enemy_1207_sfji_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":11},{"effectId":"enemyeffect_12_1","name":"战术特训·损伤I","desc":"为自身下场战斗添加1只底海滑动者,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1148_dssbr","count":1,"adds":[{"enemyKey":"enemy_1148_dssbr","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":12},{"effectId":"enemyeffect_12_2","name":"战术特训·损伤II","desc":"为自身下场战斗添加1只炽焰源石虫,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1305_mhslim_2","count":1,"adds":[{"enemyKey":"enemy_1305_mhslim_2","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":12},{"effectId":"enemyeffect_12_3","name":"战术特训·损伤III","desc":"为自身下场战斗添加1只灼藤,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_10067_ftsjc","count":1,"adds":[{"enemyKey":"enemy_10067_ftsjc","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":12},{"effectId":"enemyeffect_12_4","name":"悬赏·损伤I","desc":"为自身接下来两场作战添加1只底海滑动者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1148_dssbr","count":1,"adds":[{"enemyKey":"enemy_1148_dssbr","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":12},{"effectId":"enemyeffect_12_5","name":"悬赏·损伤II","desc":"为自身接下来两场作战添加1只控潮术师,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1161_tidmag","count":1,"adds":[{"enemyKey":"enemy_1161_tidmag","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":12},{"effectId":"enemyeffect_12_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只术师快艇,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1162_magmot","count":1,"adds":[{"enemyKey":"enemy_1162_magmot","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":12},{"effectId":"enemyeffect_12_7","name":"悬赏·损伤II","desc":"为自身下场战斗添加1只灼藤,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10067_ftsjc","count":1,"adds":[{"enemyKey":"enemy_10067_ftsjc","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":12},{"effectId":"enemyeffect_12_8","name":"悬赏·损伤II","desc":"为自身下场战斗添加1只异光体孽生者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1439_dslntf_2","count":1,"adds":[{"enemyKey":"enemy_1439_dslntf_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":12},{"effectId":"enemyeffect_13_1","name":"战术特训·持续I","desc":"为自身下场战斗添加1只逐腐兽,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1270_nhstlk","count":1,"adds":[{"enemyKey":"enemy_1270_nhstlk","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":13},{"effectId":"enemyeffect_13_2","name":"战术特训·持续II","desc":"为自身下场战斗添加1只萨卡兹枯朽战士组长,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1267_nhpbr_2","count":1,"adds":[{"enemyKey":"enemy_1267_nhpbr_2","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":13},{"effectId":"enemyeffect_13_3","name":"战术特训·持续III","desc":"为自身下场战斗添加1只尖端萨卡兹枯朽战车,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1272_nhtank_2","count":1,"adds":[{"enemyKey":"enemy_1272_nhtank_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":13},{"effectId":"enemyeffect_13_4","name":"悬赏·持续I","desc":"为自身接下来两场作战添加1只萨卡兹枯朽战士组长,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1267_nhpbr_2","count":1,"adds":[{"enemyKey":"enemy_1267_nhpbr_2","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":13},{"effectId":"enemyeffect_13_5","name":"悬赏·持续II","desc":"为自身接下来两场作战添加1只逐腐兽,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1270_nhstlk","count":1,"adds":[{"enemyKey":"enemy_1270_nhstlk","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":13},{"effectId":"enemyeffect_13_6","name":"悬赏·持续III","desc":"为自身接下来两场作战添加1只萨卡兹枯朽战车,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1272_nhtank","count":1,"adds":[{"enemyKey":"enemy_1272_nhtank","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":13},{"effectId":"enemyeffect_13_7","name":"悬赏·持续I","desc":"为自身下场战斗添加1只假想敌:蚀裂,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_9006_actoxi","count":1,"adds":[{"enemyKey":"enemy_9006_actoxi","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":13},{"effectId":"enemyeffect_13_8","name":"悬赏·持续II","desc":"为自身下场战斗添加1只尖端萨卡兹枯朽战车,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1272_nhtank_2","count":1,"adds":[{"enemyKey":"enemy_1272_nhtank_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":13},{"effectId":"enemyeffect_14_1","name":"战术特训·隐匿I","desc":"为自身下场战斗添加1只隐形弩手,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1019_jshoot","count":1,"adds":[{"enemyKey":"enemy_1019_jshoot","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":14},{"effectId":"enemyeffect_14_2","name":"战术特训·隐匿II","desc":"为自身下场战斗添加1只节日爵士乐手,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_10034_cnvsax","count":1,"adds":[{"enemyKey":"enemy_10034_cnvsax","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":14},{"effectId":"enemyeffect_14_3","name":"战术特训·隐匿III","desc":"为自身下场战斗添加1只家族灭迹人,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1283_sgkill","count":1,"adds":[{"enemyKey":"enemy_1283_sgkill","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":14},{"effectId":"enemyeffect_14_4","name":"悬赏·隐匿I","desc":"为自身接下来两场作战添加1只隐形弩手,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1019_jshoot","count":1,"adds":[{"enemyKey":"enemy_1019_jshoot","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":14},{"effectId":"enemyeffect_14_5","name":"悬赏·隐匿II","desc":"为自身接下来两场作战添加1只隐形术师,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1023_jmage","count":1,"adds":[{"enemyKey":"enemy_1023_jmage","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":14},{"effectId":"enemyeffect_14_6","name":"悬赏·隐匿III","desc":"为自身接下来两场作战添加1只山海众头目,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1299_ymkilr","count":1,"adds":[{"enemyKey":"enemy_1299_ymkilr","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":14},{"effectId":"enemyeffect_14_7","name":"悬赏·隐匿I","desc":"为自身下场战斗添加1只重弩突袭者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1404_msnip","count":1,"adds":[{"enemyKey":"enemy_1404_msnip","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":14},{"effectId":"enemyeffect_14_8","name":"悬赏·隐匿II","desc":"为自身下场战斗添加1只家族暗影灭迹人,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1283_sgkill_2","count":1,"adds":[{"enemyKey":"enemy_1283_sgkill_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":14},{"effectId":"enemyeffect_15_1","name":"战术特训·折射I","desc":"为自身下场战斗添加1只深池方阵战士,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1169_duphlx","count":1,"adds":[{"enemyKey":"enemy_1169_duphlx","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":15},{"effectId":"enemyeffect_15_2","name":"战术特训·折射II","desc":"为自身下场战斗添加1只深池暗影术师队长,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1168_dumage_2","count":1,"adds":[{"enemyKey":"enemy_1168_dumage_2","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":15},{"effectId":"enemyeffect_15_3","name":"战术特训·折射III","desc":"为自身下场战斗添加1只深池伙友卫队精英,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1174_duholy_2","count":1,"adds":[{"enemyKey":"enemy_1174_duholy_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":15},{"effectId":"enemyeffect_15_4","name":"悬赏·折射I","desc":"为自身接下来两场作战添加1只深池方阵战士,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1169_duphlx","count":1,"adds":[{"enemyKey":"enemy_1169_duphlx","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":15},{"effectId":"enemyeffect_15_5","name":"悬赏·折射II","desc":"为自身接下来两场作战添加1只深池暗影术师,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1168_dumage","count":1,"adds":[{"enemyKey":"enemy_1168_dumage","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":15},{"effectId":"enemyeffect_15_6","name":"悬赏·折射III","desc":"为自身接下来两场作战添加1只深池伙友卫队,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1174_duholy","count":1,"adds":[{"enemyKey":"enemy_1174_duholy","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":15},{"effectId":"enemyeffect_15_7","name":"悬赏·折射II","desc":"为自身下场战斗添加1只深池重甲卫士队长,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1170_dushld_2","count":1,"adds":[{"enemyKey":"enemy_1170_dushld_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":15},{"effectId":"enemyeffect_15_8","name":"悬赏·折射II","desc":"为自身下场战斗添加1只愤怒的守墓石像,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1172_dugago_2","count":1,"adds":[{"enemyKey":"enemy_1172_dugago_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":15},{"effectId":"enemyeffect_16_1","name":"悬赏·特异III","desc":"为自身下场战斗添加1只泥岩巨像,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1092_mdgint","count":1,"adds":[{"enemyKey":"enemy_1092_mdgint","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_2","name":"悬赏·特异III","desc":"为自身下场战斗添加1只“越长尘”,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1302_ymtro_2","count":1,"adds":[{"enemyKey":"enemy_1302_ymtro_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_3","name":"悬赏·特异III","desc":"为自身下场战斗添加1只狂暴宿主组长,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1062_rager_2","count":1,"adds":[{"enemyKey":"enemy_1062_rager_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_4","name":"悬赏·特异III","desc":"为自身下场战斗添加1只温顺的武装大驮兽,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1415_mmkabi_2","count":1,"adds":[{"enemyKey":"enemy_1415_mmkabi_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_5","name":"悬赏·特异III","desc":"为自身下场战斗添加1只萨卡兹骸骨拷打者,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1364_spnaxe_2","count":1,"adds":[{"enemyKey":"enemy_1364_spnaxe_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_6","name":"悬赏·特异III","desc":"为自身下场战斗添加1只高准度伦蒂尼姆城防自行炮,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1273_stmgun_2","count":1,"adds":[{"enemyKey":"enemy_1273_stmgun_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_7","name":"悬赏·特异III","desc":"为自身下场战斗添加1只乌顶巨角卢鲁,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10144_xdelk_2","count":1,"adds":[{"enemyKey":"enemy_10144_xdelk_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_8","name":"悬赏·特异III","desc":"为自身下场战斗添加1只伊利昂的木驮兽,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10159_mntrjn","count":1,"adds":[{"enemyKey":"enemy_10159_mntrjn","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_9","name":"悬赏·特异II","desc":"为自身下场战斗添加1只拥霜羽兽,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10141_xdpeng_2","count":1,"adds":[{"enemyKey":"enemy_10141_xdpeng_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_10","name":"悬赏·特异II","desc":"为自身下场战斗添加1只异质裂兽·α,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10127_rkmbst_2","count":1,"adds":[{"enemyKey":"enemy_10127_rkmbst_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_11","name":"悬赏·损伤I","desc":"为自身下场战斗添加1只心虚设计师,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10097_crshd","count":1,"adds":[{"enemyKey":"enemy_10097_crshd","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_12","name":"悬赏·特异I","desc":"为自身下场战斗添加1只转译基底·α,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10081_mpplai","count":1,"adds":[{"enemyKey":"enemy_10081_mpplai","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_17_1","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只雪孩子,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10138_xdsnow","count":1,"adds":[{"enemyKey":"enemy_10138_xdsnow","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_2","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只新手祭司学徒,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10156_mncrer","count":1,"adds":[{"enemyKey":"enemy_10156_mncrer","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_3","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只冒失的小弟,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10112_ymgds","count":1,"adds":[{"enemyKey":"enemy_10112_ymgds","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_4","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只骇笑看客,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_2009_csaudc","count":1,"adds":[{"enemyKey":"enemy_2009_csaudc","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_5","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只水遁忍者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10116_ymgtop","count":1,"adds":[{"enemyKey":"enemy_10116_ymgtop","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_6","name":"悬赏·特异III","desc":"为自身接下来两场作战添加1只自制投石机,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10162_mnctpt","count":1,"adds":[{"enemyKey":"enemy_10162_mnctpt","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_18_1","name":"悬赏·损伤I","desc":"为自身接下来两场作战添加1只临时收音师,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10094_crstf","count":1,"adds":[{"enemyKey":"enemy_10094_crstf","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_2","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只迷茫的修理小助手,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10073_mpcar","count":1,"adds":[{"enemyKey":"enemy_10073_mpcar","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_3","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只高能源石虫,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1021_bslime","count":1,"adds":[{"enemyKey":"enemy_1021_bslime","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_4","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只圣堂剑士,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10087_hlchgr","count":1,"adds":[{"enemyKey":"enemy_10087_hlchgr","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_5","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只寻仇者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1025_reveng","count":1,"adds":[{"enemyKey":"enemy_1025_reveng","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只主角阵营角色,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10098_crhro","count":1,"adds":[{"enemyKey":"enemy_10098_crhro","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_19_1","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只节日气球,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10040_cnvbln","count":1,"adds":[{"enemyKey":"enemy_10040_cnvbln","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_2","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只简饲源石虫,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10001_trslim","count":1,"adds":[{"enemyKey":"enemy_10001_trslim","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_3","name":"悬赏·折射I","desc":"为自身接下来两场作战添加1只深池侦察犬pro,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1165_duhond_2","count":1,"adds":[{"enemyKey":"enemy_1165_duhond_2","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_4","name":"悬赏·飞行II","desc":"为自身接下来两场作战添加1只吉兆飞鳞,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10045_parrot","count":1,"adds":[{"enemyKey":"enemy_10045_parrot","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_5","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只咸鳞汁推荐者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10044_wintun","count":1,"adds":[{"enemyKey":"enemy_10044_wintun","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只反派阵营角色,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10099_crvln","count":1,"adds":[{"enemyKey":"enemy_10099_crvln","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_20_1","name":"悬赏·持续I","desc":"为自身接下来两场作战添加1只萨卡兹枯朽战士,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1267_nhpbr","count":1,"adds":[{"enemyKey":"enemy_1267_nhpbr","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_2","name":"悬赏·频次I","desc":"为自身接下来两场作战添加1只俗心,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1197_sfshu","count":1,"adds":[{"enemyKey":"enemy_1197_sfshu","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_3","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只潜伏者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1009_lurker","count":1,"adds":[{"enemyKey":"enemy_1009_lurker","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_4","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只“独轮车玩具”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10018_sgrobh","count":1,"adds":[{"enemyKey":"enemy_10018_sgrobh","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_5","name":"悬赏·损伤II","desc":"为自身接下来两场作战添加1只无胄盟清扫小队,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1183_mlasrt","count":1,"adds":[{"enemyKey":"enemy_1183_mlasrt","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只鼎沸,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10054_cjhot","count":1,"adds":[{"enemyKey":"enemy_10054_cjhot","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_b_1","name":"碎骨·悬赏","desc":"为自身下场作战添加1个碎骨,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1500_skulsr","count":1,"adds":[{"enemyKey":"enemy_1500_skulsr","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_2","name":"萨卡兹百夫长·悬赏","desc":"为自身下场作战添加1个萨卡兹百夫长,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1501_demonk","count":1,"adds":[{"enemyKey":"enemy_1501_demonk","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_3","name":"弑君者·悬赏","desc":"为自身下场作战添加1个弑君者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1502_crowns","count":1,"adds":[{"enemyKey":"enemy_1502_crowns","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_4","name":"泥岩·悬赏","desc":"为自身下场作战添加1个泥岩,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1511_mdrock","count":1,"adds":[{"enemyKey":"enemy_1511_mdrock","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_5","name":"腐败骑士·悬赏","desc":"为自身下场作战添加1个腐败骑士,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1513_dekght","count":1,"adds":[{"enemyKey":"enemy_1513_dekght","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_6","name":"凋零骑士·悬赏","desc":"为自身下场作战添加1个凋零骑士,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1513_dekght_2","count":1,"adds":[{"enemyKey":"enemy_1513_dekght_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_7","name":"“遗弃者”·悬赏","desc":"为自身下场作战添加1个“遗弃者”,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2005_axetro","count":1,"adds":[{"enemyKey":"enemy_2005_axetro","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_8","name":"喷气人·悬赏","desc":"为自身下场作战添加1个喷气人,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2004_balloon","count":1,"adds":[{"enemyKey":"enemy_2004_balloon","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_9","name":"杰斯顿·威廉姆斯·悬赏","desc":"为自身下场作战添加1个杰斯顿·威廉姆斯,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1516_jakill","count":1,"adds":[{"enemyKey":"enemy_1516_jakill","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_10","name":"W·悬赏","desc":"为自身下场作战添加1个W,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1504_cqbw","count":1,"adds":[{"enemyKey":"enemy_1504_cqbw","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_11","name":"“鼠王”·悬赏","desc":"为自身下场作战添加1个“鼠王”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1509_mousek","count":1,"adds":[{"enemyKey":"enemy_1509_mousek","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_12","name":"“庞贝”·悬赏","desc":"为自身下场作战添加1个“庞贝”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1050_lslime","count":1,"adds":[{"enemyKey":"enemy_1050_lslime","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_13","name":"大鲍勃·悬赏","desc":"为自身下场作战添加1个大鲍勃,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1001_bigbo","count":1,"adds":[{"enemyKey":"enemy_1001_bigbo","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_14","name":"“自在”·悬赏","desc":"为自身下场作战添加1个“自在”,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1517_xi","count":1,"adds":[{"enemyKey":"enemy_1517_xi","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_15","name":"锏·悬赏","desc":"为自身下场作战添加1个锏,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1525_blkswb","count":1,"adds":[{"enemyKey":"enemy_1525_blkswb","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_16","name":"扎罗,“狼之主”·悬赏","desc":"为自身下场作战添加1个扎罗,“狼之主”,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1535_wlfmster","count":1,"adds":[{"enemyKey":"enemy_1535_wlfmster","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_17","name":"“墓碑”·悬赏","desc":"为自身下场作战添加1个“墓碑”,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2008_flking","count":1,"adds":[{"enemyKey":"enemy_2008_flking","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_18","name":"迷路的巨像·悬赏","desc":"为自身下场作战添加1个迷路的巨像,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2003_rockman","count":1,"adds":[{"enemyKey":"enemy_2003_rockman","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_19","name":"澪·悬赏","desc":"为自身下场作战添加1个澪,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10118_ymgprc","count":1,"adds":[{"enemyKey":"enemy_10118_ymgprc","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_20","name":"“巨大的丑东西”·悬赏","desc":"为自身下场作战添加1个“巨大的丑东西”,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1512_mcmstr","count":1,"adds":[{"enemyKey":"enemy_1512_mcmstr","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_21","name":"“复仇者”·悬赏","desc":"为自身下场作战添加1个“复仇者”,将其击倒者获得6资金","tier":3,"coin":6,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1539_reid","count":1,"adds":[{"enemyKey":"enemy_1539_reid","count":1,"coin":6,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_22","name":"“邪魔的利刃”·悬赏","desc":"为自身下场作战添加1个“邪魔的利刃”,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2048_smgrd","count":1,"adds":[{"enemyKey":"enemy_2048_smgrd","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_23","name":"陷落雪祀·悬赏","desc":"为自身下场作战添加1个陷落雪祀,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2050_smsha","count":1,"adds":[{"enemyKey":"enemy_2050_smsha","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_24","name":"纠缠藤蔓·悬赏","desc":"为自身下场作战添加1个纠缠藤蔓,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2052_smgia","count":1,"adds":[{"enemyKey":"enemy_2052_smgia","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyInitial_1","name":"多轮悬赏 · 假想敌:蚀裂","desc":"后续每场作战添加1只假想敌:蚀裂(被击倒时造成持续伤害),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9006_actoxi","count":1,"adds":[{"enemyKey":"enemy_9006_actoxi","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_2","name":"多轮悬赏 · 假想敌:淤困","desc":"后续每场作战添加1只假想敌:淤困(可造成元素损伤),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9007_acelem","count":1,"adds":[{"enemyKey":"enemy_9007_acelem","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_3","name":"多轮悬赏 · 假想敌:骨刺","desc":"后续每场作战添加1只假想敌:骨刺(拥有隐匿),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9008_acbunn","count":1,"adds":[{"enemyKey":"enemy_9008_acbunn","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_4","name":"多轮悬赏 · 假想敌:黑云","desc":"后续每场作战添加1只假想敌:黑云(空中敌人),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9009_acfort","count":1,"adds":[{"enemyKey":"enemy_9009_acfort","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_5","name":"多轮悬赏 · 假想敌:再生","desc":"后续每场作战添加1只假想敌:再生(需要一定攻击次数击破),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9010_acpupp","count":1,"adds":[{"enemyKey":"enemy_9010_acpupp","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_6","name":"多轮悬赏 · 假想敌:镜膜","desc":"后续每场作战添加1只假想敌:镜膜(拥有折射),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9011_acrefr","count":1,"adds":[{"enemyKey":"enemy_9011_acrefr","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null}],"tactic":[{"effectId":"allybuff_select_1","name":"列装","desc":"你获得2件随机1阶装备,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_1","name":"斯卡蒂的盟誓","desc":"你的阿戈尔、突袭和坚守盟约层数+8,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_2","name":"诗怀雅的盟誓","desc":"你的炎和投资人盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_3","name":"风笛的盟誓","desc":"你的维多利亚、远见和不屈盟约层数+8,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_4","name":"银灰的盟誓","desc":"你的谢拉格、投资人、迅捷盟约层数+8,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_5","name":"莫斯提马的盟誓","desc":"你的拉特兰、奥术盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_6","name":"缇缇的盟誓","desc":"你的萨尔贡、精准盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_7","name":"玛恩纳的盟誓","desc":"你的卡西米尔盟约层数+12,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_8","name":"德克萨斯的盟誓","desc":"你的叙拉古、突袭盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_3","name":"财富","desc":"你获得1资金,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_4","name":"补给","desc":"你接下来的2次刷新变为免费(可叠加),若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_5","name":"整备","desc":"你接下来购买的1件装备变为进阶品质","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_6","name":"升华","desc":"你接下来购买的1名干员变为精锐状态","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_1","name":"炎盟约驰援","desc":"你获得1名炎盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_2","name":"谢拉格驰援","desc":"你获得1名谢拉格盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_3","name":"萨尔贡驰援","desc":"你获得1名萨尔贡盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_4","name":"叙拉古驰援","desc":"你获得1名叙拉古盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_5","name":"卡西米尔驰援","desc":"你获得1名卡西米尔盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_6","name":"拉特兰驰援","desc":"你获得1名拉特兰盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_7","name":"维多利亚驰援","desc":"你获得1名维多利亚盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_8","name":"阿戈尔驰援","desc":"你获得1名阿戈尔盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_11","name":"自愈","desc":"你获得:我方单位每次受到伤害时回复50点生命值;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_13","name":"火力","desc":"你获得:休整期结束时若手牌区至少有3个单位,我方所有干员无视敌人20法术抗性;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_14","name":"征召","desc":"你获得:开始作战时若场上至少有一行存在3名干员,所有干员的再部署时间-50%;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_18","name":"无瑕","desc":"你获得:干员在生命值为满时,攻击力、防御力+30%;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_19","name":"锐利","desc":"你获得:休整期结束时若手牌区为空,我方所有干员无视敌人30%的防御力;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"enemydebuff_select_1","name":"排斥:乏力","desc":"全部敌人获得减益效果:攻击力-5%","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_2","name":"排斥:脆弱","desc":"全部敌人获得减益效果:防御力-100","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_3","name":"排斥:致幻","desc":"全部敌人获得减益效果:法术抗性-3","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_4","name":"责罚:乏力","desc":"精英敌人获得减益效果:攻击力-6%","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_5","name":"责罚:脆弱","desc":"精英敌人获得减益效果:防御力-150","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_6","name":"责罚:致幻","desc":"精英敌人获得减益效果:法术抗性-5","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_7","name":"裁决:乏力","desc":"领袖敌人获得减益效果:攻击力-7%","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_8","name":"裁决:脆弱","desc":"领袖敌人获得减益效果:防御力-200","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_9","name":"裁决:致幻","desc":"领袖敌人获得减益效果:法术抗性-7","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"map_m01_1","name":"模拟战场演变·模式一","desc":"移除场地上全部阻隔工事","kind":"terrain","stageId":"act1autochess_m01","team":false},{"effectId":"map_m02_1","name":"模拟战场演变·模式二","desc":"场地上全部阻隔工事变为射击台","kind":"terrain","stageId":"act1autochess_m02","team":false},{"effectId":"map_m02_2","name":"模拟战场演变·模式三","desc":"移除场地上全部阻隔工事","kind":"terrain","stageId":"act1autochess_m02","team":false},{"effectId":"map_m03_1","name":"模拟战场演变·模式四","desc":"移除场地左侧的阻隔工事","kind":"terrain","stageId":"act1autochess_m03","team":false},{"effectId":"map_m03_2","name":"模拟战场演变·模式五","desc":"场地右侧的射击台变为可以部署高台干员和地面干员的地面","kind":"terrain","stageId":"act1autochess_m03","team":false},{"effectId":"map_m04_1","name":"模拟战场演变·模式六","desc":"移除场地上全部阻隔工事","kind":"terrain","stageId":"act1autochess_m04","team":false},{"effectId":"map_m06_1","name":"模拟战场演变·模式八","desc":"场地中的沙尘暴停止","kind":"terrain","stageId":"act1autochess_m06","team":false},{"effectId":"map_m07_1","name":"模拟战场演变·模式九","desc":"场上的树丛全部消失","kind":"terrain","stageId":"act1autochess_m07","team":false}]},"bountyDrafts":{"initial":{"events":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"slots":10,"sets":[{"cards":["enemyeffect_18_1","enemyeffect_18_2","enemyeffect_18_3","enemyeffect_18_4","enemyeffect_18_5","enemyeffect_18_6"],"seen":[1,3,5,9]},{"cards":["enemyeffect_19_1","enemyeffect_19_2","enemyeffect_19_3","enemyeffect_19_4","enemyeffect_19_5","enemyeffect_19_6"],"seen":[2]},{"cards":["enemyeffect_17_1","enemyeffect_17_2","enemyeffect_17_3","enemyeffect_17_4","enemyeffect_17_5","enemyeffect_17_6"],"seen":[7]},{"cards":["enemyeffect_10_5","enemyeffect_11_4","enemyeffect_12_5","enemyeffect_13_6","enemyeffect_15_4","enemyeffect_20_3"],"seen":[4,10]},{"cards":["enemyeffect_10_4","enemyeffect_11_5","enemyeffect_12_6","enemyeffect_14_4","enemyeffect_15_5","enemyeffect_20_2"],"seen":[6]},{"cards":["enemyeffect_10_4","enemyeffect_11_5","enemyeffect_12_4","enemyeffect_14_6","enemyeffect_15_4","enemyeffect_20_4"],"seen":[8]},{"cards":["enemyeffect_10_4","enemyeffect_11_6","enemyeffect_12_4","enemyeffect_13_4","enemyeffect_14_5","enemyeffect_15_5"],"seen":[11]}],"mixed":{"series":[10,11,12,13,14,15,20],"count":6,"tiers":[1,1,1,2,2,3]},"count":6,"assumed":["the unseen slots built by `mixed`","险境 R6 drafts like R3"]},"boss":{"events":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"templates":[{"featured":[],"fill":["enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_10","enemyeffect_b_12","enemyeffect_b_13","enemyeffect_5_1"],"seen":[4]},{"featured":["enemyeffect_b_8","enemyeffect_b_24"],"fill":["enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_10","enemyeffect_b_12","enemyeffect_b_13","enemyeffect_5_1"],"seen":[1,5]},{"featured":["enemyeffect_b_4","enemyeffect_b_19"],"fill":["enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_10","enemyeffect_b_12","enemyeffect_b_13","enemyeffect_5_1"],"seen":[2]},{"featured":["enemyeffect_b_5","enemyeffect_b_17","enemyeffect_b_20"],"fill":["enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_10","enemyeffect_b_12","enemyeffect_b_13","enemyeffect_5_1"],"seen":[3]},{"featured":["enemyeffect_b_22","enemyeffect_b_21","enemyeffect_b_2"],"fill":["enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_10","enemyeffect_b_12","enemyeffect_b_13","enemyeffect_5_1"],"seen":[6,"bahamut-12294"]},{"featured":["enemyeffect_b_9","enemyeffect_b_23"],"fill":["enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_10","enemyeffect_b_11","enemyeffect_b_13","enemyeffect_5_1"],"seen":[7,11]},{"featured":["enemyeffect_b_9","enemyeffect_b_14"],"fill":["enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_10","enemyeffect_b_11","enemyeffect_b_13","enemyeffect_5_1"],"seen":[8,9,10]}],"count":6,"assumed":["a uniform pick among the seen groups","boss bounties of no seen group are not offered"]},"hunter":{"events":["bounty_hunter_1","bounty_hunter_2","bounty_hunter_3","bounty_hunter_4","bounty_hunter_5","bounty_hunter_6","bounty_hunter_7","bounty_hunter_8","bounty_hunter_9","bounty_hunter_10","bounty_hunter_11","bounty_hunter_12","bounty_hunter_13","bounty_hunter_14","bounty_hunter_15"],"slots":15,"templates":[{"featured":["enemyeffect_16_4","enemyeffect_16_10","enemyeffect_15_7","enemyeffect_12_7","enemyeffect_13_8"],"fill":["enemyeffect_10_7","enemyeffect_11_7","enemyeffect_13_7","enemyeffect_14_7","enemyeffect_16_11"],"seen":[1,6]},{"featured":["enemyeffect_16_3","enemyeffect_15_7","enemyeffect_13_8"],"fill":["enemyeffect_10_7","enemyeffect_11_7","enemyeffect_13_7","enemyeffect_14_7","enemyeffect_16_11"],"seen":[3]},{"featured":["enemyeffect_16_5","enemyeffect_14_8","enemyeffect_12_7","enemyeffect_15_8"],"fill":["enemyeffect_10_7","enemyeffect_11_7","enemyeffect_13_7","enemyeffect_14_7","enemyeffect_16_11"],"seen":[10]},{"featured":["enemyeffect_16_7","enemyeffect_16_9"],"fill":["enemyeffect_10_7","enemyeffect_11_7","enemyeffect_13_7","enemyeffect_14_7","enemyeffect_16_11"],"seen":[11]}],"rule":{"giants":["enemyeffect_16_1","enemyeffect_16_2","enemyeffect_16_3","enemyeffect_16_4","enemyeffect_16_5","enemyeffect_16_6","enemyeffect_16_7","enemyeffect_16_8"],"groupCards":["enemyeffect_10_8","enemyeffect_11_8","enemyeffect_12_7","enemyeffect_12_8","enemyeffect_13_8","enemyeffect_14_8","enemyeffect_15_7","enemyeffect_15_8","enemyeffect_16_9","enemyeffect_16_10"],"groupSizes":[1,2,3,4],"fill":["enemyeffect_10_7","enemyeffect_11_7","enemyeffect_13_7","enemyeffect_14_7","enemyeffect_16_11","enemyeffect_16_12"]},"onePerSeries":[10,11,12,13,14,15],"count":6,"assumed":["a group (the giant + tier-II cards) + tier-I fill, like R9","the unseen slots built by `rule`","a uniform pick among the 15 events"]}},"schedule":{"mode_training_1":{"spRounds":[3],"rounds":{"3":{"families":[{"family":"supply","weight":100}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1_tr"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_single_funny":{"spRounds":[],"rounds":{}},"mode_single_normal":{"spRounds":[6,9],"rounds":{"6":{"families":[{"family":"supply","weight":100}],"cards":3,"supplyTiers":[2,5],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1_s","enemy_initial_2_s","enemy_initial_3_s","enemy_initial_4_s","enemy_initial_5_s","enemy_initial_6_s","enemy_initial_7_s","enemy_initial_8_s","enemy_initial_9_s","enemy_initial_10_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true},"9":{"families":[{"family":"tactic","weight":100}],"cards":3,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1_s","bossInitial_2_s","bossInitial_3_s","bossInitial_4_s","bossInitial_5_s","bossInitial_6_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true}}},"mode_single_hard":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1_s","enemy_initial_2_s","enemy_initial_3_s","enemy_initial_4_s","enemy_initial_5_s","enemy_initial_6_s","enemy_initial_7_s","enemy_initial_8_s","enemy_initial_9_s","enemy_initial_10_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1_s","bossInitial_2_s","bossInitial_3_s","bossInitial_4_s","bossInitial_5_s","bossInitial_6_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":45},{"family":"shop","weight":35},{"family":"tactic","weight":20}],"cards":3,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1_s","bounty_hunter_2_s","bounty_hunter_3_s","bounty_hunter_4_s","bounty_hunter_5_s","bounty_hunter_6_s","bounty_hunter_7_s","bounty_hunter_8_s","bounty_hunter_9_s","bounty_hunter_10_s","bounty_hunter_11_s","bounty_hunter_12_s","bounty_hunter_13_s","bounty_hunter_14_s","bounty_hunter_15_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true}}},"mode_single_abyss":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1_s","enemy_initial_2_s","enemy_initial_3_s","enemy_initial_4_s","enemy_initial_5_s","enemy_initial_6_s","enemy_initial_7_s","enemy_initial_8_s","enemy_initial_9_s","enemy_initial_10_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1_s","bossInitial_2_s","bossInitial_3_s","bossInitial_4_s","bossInitial_5_s","bossInitial_6_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":45},{"family":"shop","weight":35},{"family":"tactic","weight":20}],"cards":3,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1_s","bounty_hunter_2_s","bounty_hunter_3_s","bounty_hunter_4_s","bounty_hunter_5_s","bounty_hunter_6_s","bounty_hunter_7_s","bounty_hunter_8_s","bounty_hunter_9_s","bounty_hunter_10_s","bounty_hunter_11_s","bounty_hunter_12_s","bounty_hunter_13_s","bounty_hunter_14_s","bounty_hunter_15_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true}}},"mode_multi_funny":{"spRounds":[3,9],"rounds":{"3":{"families":[{"family":"supply","weight":45},{"family":"tactic","weight":35},{"family":"shop","weight":20}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true},"9":{"families":[{"family":"supply","weight":45},{"family":"tactic","weight":35},{"family":"shop","weight":20}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_multi_normal":{"spRounds":[3,6,9],"rounds":{"3":{"families":[{"family":"bounty","weight":50},{"family":"supply","weight":25},{"family":"shop","weight":10},{"family":"tactic","weight":15}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true},"6":{"families":[{"family":"bounty","weight":50},{"family":"supply","weight":25},{"family":"shop","weight":10},{"family":"tactic","weight":15}],"cards":6,"supplyTiers":[2,5],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true},"9":{"families":[{"family":"bounty","weight":50},{"family":"supply","weight":25},{"family":"shop","weight":10},{"family":"tactic","weight":15}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_multi_hard":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":45},{"family":"shop","weight":35},{"family":"tactic","weight":20}],"cards":6,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1","bounty_hunter_2","bounty_hunter_3","bounty_hunter_4","bounty_hunter_5","bounty_hunter_6","bounty_hunter_7","bounty_hunter_8","bounty_hunter_9","bounty_hunter_10","bounty_hunter_11","bounty_hunter_12","bounty_hunter_13","bounty_hunter_14","bounty_hunter_15"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_multi_abyss":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":45},{"family":"shop","weight":35},{"family":"tactic","weight":20}],"cards":6,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1","bounty_hunter_2","bounty_hunter_3","bounty_hunter_4","bounty_hunter_5","bounty_hunter_6","bounty_hunter_7","bounty_hunter_8","bounty_hunter_9","bounty_hunter_10","bounty_hunter_11","bounty_hunter_12","bounty_hunter_13","bounty_hunter_14","bounty_hunter_15"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}}},"pools":{"pool_equip_normal":{"kind":"equip","rule":"shopEligible","maxTier":"shopLevel","assumed":true},"pool_equip_shop_1":{"kind":"equip","rule":"shopEligible","tiers":[1],"assumed":true},"pool_equip_kathe":{"kind":"equip","rule":"shopEligible","maxTier":"shopLevel","assumed":true},"pool_equip_narant":{"kind":"equip","rule":"shopEligible","maxTier":"shopLevel","assumed":true},"pool_equip_vict":{"kind":"equip","items":["chess_item_4_09_e_a","chess_item_3_09_e_a","chess_item_3_10_e_a","chess_item_2_03_e_a"],"assumed":true},"pool_equip_pepe":{"kind":"equip","weighted":[["chess_item_1_03_e_a",45],["chess_item_2_04_e_a",45],["chess_item_6_07_e_a",10]],"goldenWeights":[40,40,20],"assumed":true},"pool_equip_rockr":{"kind":"equip","items":["chess_item_4_09_e_a","chess_item_3_09_e_a","chess_item_3_10_e_a","chess_item_2_03_e_a"],"assumed":true},"pool_chess_glady":{"kind":"chess","items":["chess_char_3_05_a","chess_char_2_07_a","chess_char_1_04_a"],"assumed":true},"pool_char_pinus":{"kind":"chess","weighted":[["chess_char_1_19_a",45],["chess_char_2_18_a",45],["chess_char_4_20_a",10]],"assumed":true},"pool_char_later":{"kind":"chess","bond":"lateranoShip","minTier":4,"golden":true,"rule":"shopEligible","assumed":true},"pool_chess_shop_1_reward":{"kind":"chess","tier":1,"rule":"shopEligible","assumed":true},"pool_chess_shop_2_reward":{"kind":"chess","tier":2,"rule":"shopEligible","assumed":true},"pool_chess_shop_3_reward":{"kind":"chess","tier":3,"rule":"shopEligible","assumed":true},"pool_chess_shop_4_reward":{"kind":"chess","tier":4,"rule":"shopEligible","assumed":true},"pool_chess_shop_5_reward":{"kind":"chess","tier":5,"rule":"shopEligible","assumed":true},"pool_chess_shop_6_reward":{"kind":"chess","tier":6,"rule":"shopEligible","assumed":true}}} \ No newline at end of file +{"events":{"artifact_paid_1":{"id":"artifact_paid_1","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_1_s":{"id":"artifact_paid_1_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_2":{"id":"artifact_paid_2","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_2_s":{"id":"artifact_paid_2_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_3":{"id":"artifact_paid_3","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_3_s":{"id":"artifact_paid_3_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_4":{"id":"artifact_paid_4","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_4_s":{"id":"artifact_paid_4_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"artifact_paid_5":{"id":"artifact_paid_5","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"shop","solo":false,"training":false},"artifact_paid_5_s":{"id":"artifact_paid_5_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"机密商店","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"shop","solo":true,"training":false},"bossInitial_1":{"id":"bossInitial_1","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_1_s":{"id":"bossInitial_1_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_2":{"id":"bossInitial_2","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_2_s":{"id":"bossInitial_2_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_3":{"id":"bossInitial_3","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_3_s":{"id":"bossInitial_3_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_4":{"id":"bossInitial_4","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_4_s":{"id":"bossInitial_4_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_5":{"id":"bossInitial_5","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_5_s":{"id":"bossInitial_5_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bossInitial_6":{"id":"bossInitial_6","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bossInitial_6_s":{"id":"bossInitial_6_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_1":{"id":"bounty_hunter_1","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_1_s":{"id":"bounty_hunter_1_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_2":{"id":"bounty_hunter_2","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_2_s":{"id":"bounty_hunter_2_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_3":{"id":"bounty_hunter_3","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_3_s":{"id":"bounty_hunter_3_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_4":{"id":"bounty_hunter_4","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_4_s":{"id":"bounty_hunter_4_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_5":{"id":"bounty_hunter_5","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_5_s":{"id":"bounty_hunter_5_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_6":{"id":"bounty_hunter_6","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_6_s":{"id":"bounty_hunter_6_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_7":{"id":"bounty_hunter_7","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_7_s":{"id":"bounty_hunter_7_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#f2bd3e","family":"bounty","solo":true,"training":false},"bounty_hunter_8":{"id":"bounty_hunter_8","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_8_s":{"id":"bounty_hunter_8_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_9":{"id":"bounty_hunter_9","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_9_s":{"id":"bounty_hunter_9_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_10":{"id":"bounty_hunter_10","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_10_s":{"id":"bounty_hunter_10_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_11":{"id":"bounty_hunter_11","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_11_s":{"id":"bounty_hunter_11_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_12":{"id":"bounty_hunter_12","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_12_s":{"id":"bounty_hunter_12_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_13":{"id":"bounty_hunter_13","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_13_s":{"id":"bounty_hunter_13_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_14":{"id":"bounty_hunter_14","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_14_s":{"id":"bounty_hunter_14_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"bounty_hunter_15":{"id":"bounty_hunter_15","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"bounty_hunter_15_s":{"id":"bounty_hunter_15_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"buff_select_1":{"id":"buff_select_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_1_s":{"id":"buff_select_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"buff_select_2":{"id":"buff_select_2","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_2_s":{"id":"buff_select_2_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"buff_select_3":{"id":"buff_select_3","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_3_s":{"id":"buff_select_3_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"buff_select_4":{"id":"buff_select_4","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"buff_select_4_s":{"id":"buff_select_4_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"enemy_initial_1":{"id":"enemy_initial_1","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_1_s":{"id":"enemy_initial_1_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_2":{"id":"enemy_initial_2","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_2_s":{"id":"enemy_initial_2_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_3":{"id":"enemy_initial_3","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_3_s":{"id":"enemy_initial_3_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_4":{"id":"enemy_initial_4","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_4_s":{"id":"enemy_initial_4_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_5":{"id":"enemy_initial_5","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_5_s":{"id":"enemy_initial_5_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_6":{"id":"enemy_initial_6","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_6_s":{"id":"enemy_initial_6_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_7":{"id":"enemy_initial_7","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_7_s":{"id":"enemy_initial_7_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_8":{"id":"enemy_initial_8","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_8_s":{"id":"enemy_initial_8_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_9":{"id":"enemy_initial_9","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_9_s":{"id":"enemy_initial_9_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"enemy_initial_10":{"id":"enemy_initial_10","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false},"enemy_initial_10_s":{"id":"enemy_initial_10_s","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":true,"training":false},"equip_free_1":{"id":"equip_free_1","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_1_tr":{"id":"equip_free_1_tr","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":true},"equip_free_2":{"id":"equip_free_2","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_2_s":{"id":"equip_free_2_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"supply","solo":true,"training":false},"equip_free_3":{"id":"equip_free_3","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_3_s":{"id":"equip_free_3_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"supply","solo":true,"training":false},"equip_free_4":{"id":"equip_free_4","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#35d8b4","family":"supply","solo":false,"training":false},"equip_free_4_s":{"id":"equip_free_4_s","choiceType":"EQUIP_FREE","effectType":"EQUIP","name":"道具补给","desc":"无需消耗资金,获得装备补给。","descRaw":"无需消耗资金,获得装备补给。","color":"#f2bd3e","family":"supply","solo":true,"training":false},"hardbuff_select_1":{"id":"hardbuff_select_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"hardbuff_select_1_s":{"id":"hardbuff_select_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":true,"training":false},"hardbuff_select_2":{"id":"hardbuff_select_2","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"hardbuff_select_2_s":{"id":"hardbuff_select_2_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":true,"training":false},"hardbuff_select_3":{"id":"hardbuff_select_3","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"hardbuff_select_3_s":{"id":"hardbuff_select_3_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":true,"training":false},"hunter_band_1":{"id":"hunter_band_1","choiceType":"PERSONAL_CHOOSE","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","descRaw":"选定悬赏目标,获取额外奖励。","color":"#35d8b4","family":"bounty","solo":false,"training":false,"usedBy":["chess_item_6_03_m","chess_item_6_01_m"]},"terrain_m01_1":{"id":"terrain_m01_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m01_1_s":{"id":"terrain_m01_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m02_1":{"id":"terrain_m02_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m02_1_s":{"id":"terrain_m02_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m02_2":{"id":"terrain_m02_2","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m02_2_s":{"id":"terrain_m02_2_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m03_1":{"id":"terrain_m03_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m03_1_s":{"id":"terrain_m03_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m04_1":{"id":"terrain_m04_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m04_1_s":{"id":"terrain_m04_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m06_1":{"id":"terrain_m06_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m06_1_s":{"id":"terrain_m06_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false},"terrain_m07_1":{"id":"terrain_m07_1","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#35d8b4","family":"tactic","solo":false,"training":false},"terrain_m07_1_s":{"id":"terrain_m07_1_s","choiceType":"BUFF_SELECT","effectType":"BUFF_GAIN","name":"战术决策","desc":"进行协同调整,做好迎战准备。","descRaw":"进行协同调整,做好迎战准备。","color":"#f2bd3e","family":"tactic","solo":true,"training":false}},"families":{"bounty":{"name":"悬赏决策","desc":"选定悬赏目标,获取额外奖励。","cards":"bountyDrafts[schedule[*].bountyDraft] — one official card list of the round (initial: an R3 set of 6; boss: an R9 group of up to 9; hunter: one of the 7 seen R11 lists of 7), six different cards of it drawn by weight, over cards.bounty entries with draft: true and that draftPool"},"supply":{"name":"道具补给","desc":"无需消耗资金,获得装备补给。","cards":"random normal EQUIP items in schedule[*].supplyTiers (duplicates allowed)"},"shop":{"name":"机密商店","desc":"无需消耗资金,获得装备补给。","cards":"at shopDraft.rounds (R11): six slots drawn with replacement (VI, VI, V, 盟约之币, 2 × V / IV / III / 盟约之币); other rounds: random normal EQUIP shop items of tiers I–VI (duplicates allowed) — the same item can come twice"},"tactic":{"name":"战术决策","desc":"进行协同调整,做好迎战准备。","cards":"cards.tactic, each card drawn on its own (with replacement) — the same card can come twice; at tacticDraft.rounds (R11) the ally cards by tacticDraft.weights, other rounds every card uniform (terrain cards only for the match stage)"}},"format":{"multi":{"cards":6,"pickOrder":"random","firstPickSec":30,"otherPickSec":16,"onTimeout":"autoPickRandom","eachPlayerPicks":1},"solo":{"cards":3,"timer":null},"opensAfterIncome":true},"cards":{"bounty":[{"effectId":"enemyeffect_1","name":"无人机护障·P·战术特训","desc":"为自身下场作战添加3只无人机护障·P,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1355_mrfly_2","count":3,"adds":[{"enemyKey":"enemy_1355_mrfly_2","count":4,"coin":2,"rounds":1,"payout":"perfect","buffKey":"next_battle_add_enemy_win_gain_coin"},{"enemyKey":"enemy_1355_mrfly_2","count":3,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":null},{"effectId":"enemyeffect_2","name":"法术大师A2·多轮战术特训","desc":"之后的每场作战添加2只法术大师A2,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":99,"multiRound":true,"enemyKey":"enemy_1041_lazerd_2","count":2,"adds":[{"enemyKey":"enemy_1041_lazerd_2","count":2,"coin":2,"rounds":99,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":null},{"effectId":"enemyeffect_3_2","name":"法术大师A2·悬赏","desc":"为自身下场作战添加1只法术大师A2,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1041_lazerd_2","count":1,"adds":[{"enemyKey":"enemy_1041_lazerd_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":3},{"effectId":"enemyeffect_3_2_e","name":"“萨科塔之眼”·悬赏","desc":"为自身下场作战添加1只“萨科塔之眼”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10084_hlegle","count":1,"adds":[{"enemyKey":"enemy_10084_hlegle","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_3_3","name":"元核孽生者·悬赏","desc":"为自身下场作战添加1只元核孽生者,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1439_dslntf","count":1,"adds":[{"enemyKey":"enemy_1439_dslntf","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":3},{"effectId":"enemyeffect_3_3_e","name":"幽灵组长·悬赏","desc":"为自身下场作战添加1只幽灵组长,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1026_aghost","count":1,"adds":[{"enemyKey":"enemy_1026_aghost","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_3_4","name":"山海众头目·悬赏","desc":"为自身下场作战添加1只山海众头目,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1299_ymkilr","count":1,"adds":[{"enemyKey":"enemy_1299_ymkilr","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":3},{"effectId":"enemyeffect_3_4_e","name":"重装防御者·悬赏","desc":"为自身下场作战添加1只重装防御者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1006_shield","count":1,"adds":[{"enemyKey":"enemy_1006_shield","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_3_5_e","name":"重弩突袭者·悬赏","desc":"为自身下场作战添加1只重弩突袭者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1404_msnip","count":1,"adds":[{"enemyKey":"enemy_1404_msnip","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_4","name":"山海众头目·多轮悬赏","desc":"之后的每场作战添加1只山海众头目,将其击倒者获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_1299_ymkilr","count":1,"adds":[{"enemyKey":"enemy_1299_ymkilr","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_5","name":"鸭爵·悬赏","desc":"为自身下场作战添加1只鸭爵,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2001_duckmi","count":1,"adds":[{"enemyKey":"enemy_2001_duckmi","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_5_1","name":"源石虫·特训","desc":"为自身下场作战添加1只源石虫,但不获得资金","tier":1,"coin":0,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1007_slime","count":1,"adds":[{"enemyKey":"enemy_1007_slime","count":1,"coin":0,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":5},{"effectId":"enemyeffect_6","name":"高普尼克·悬赏","desc":"为自身下场作战添加1只高普尼克,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2002_bearmi","count":1,"adds":[{"enemyKey":"enemy_2002_bearmi","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_7","name":"流泪小子·悬赏","desc":"为自身下场作战添加1只流泪小子,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2034_sythef","count":1,"adds":[{"enemyKey":"enemy_2034_sythef","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_8","name":"圆仔·悬赏","desc":"为自身下场作战添加1只圆仔,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2085_skzjxd","count":1,"adds":[{"enemyKey":"enemy_2085_skzjxd","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"hidden","draftPool":null,"series":null},{"effectId":"enemyeffect_10_1","name":"战术特训·飞行I","desc":"为自身下场战斗添加1只妖怪,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1005_yokai","count":1,"adds":[{"enemyKey":"enemy_1005_yokai","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":10},{"effectId":"enemyeffect_10_2","name":"战术特训·飞行II","desc":"为自身下场战斗添加1只暴鸰,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1040_bombd","count":1,"adds":[{"enemyKey":"enemy_1040_bombd","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":10},{"effectId":"enemyeffect_10_3","name":"战术特训·飞行III","desc":"为自身下场战斗添加1只帝国炮火中枢先兆者,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1112_emppnt_2","count":1,"adds":[{"enemyKey":"enemy_1112_emppnt_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":10},{"effectId":"enemyeffect_10_4","name":"悬赏·飞行I","desc":"为自身接下来两场作战添加1只妖怪,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1005_yokai","count":1,"adds":[{"enemyKey":"enemy_1005_yokai","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10},{"effectId":"enemyeffect_10_5","name":"悬赏·飞行II","desc":"为自身接下来两场作战添加1只暴鸰,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1040_bombd","count":1,"adds":[{"enemyKey":"enemy_1040_bombd","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10},{"effectId":"enemyeffect_10_6","name":"悬赏·飞行III","desc":"为自身接下来两场作战添加1只法术大师A1,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1041_lazerd","count":1,"adds":[{"enemyKey":"enemy_1041_lazerd","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10},{"effectId":"enemyeffect_10_7","name":"悬赏·飞行I","desc":"为自身下场战斗添加1只法术大师A2,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1041_lazerd_2","count":1,"adds":[{"enemyKey":"enemy_1041_lazerd_2","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":10},{"effectId":"enemyeffect_10_8","name":"悬赏·飞行II","desc":"为自身下场战斗添加1只枯朽萃聚使徒,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1321_wdarft","count":1,"adds":[{"enemyKey":"enemy_1321_wdarft","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":10},{"effectId":"enemyeffect_11_1","name":"战术特训·频次I","desc":"为自身下场战斗添加1只磨砻,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1195_sfyin","count":1,"adds":[{"enemyKey":"enemy_1195_sfyin","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":11},{"effectId":"enemyeffect_11_2","name":"战术特训·频次II","desc":"为自身下场战斗添加1只烹泉,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1203_sfhu","count":1,"adds":[{"enemyKey":"enemy_1203_sfhu","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":11},{"effectId":"enemyeffect_11_3","name":"战术特训·频次III","desc":"为自身下场战斗添加1只新硎,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1207_sfji_2","count":1,"adds":[{"enemyKey":"enemy_1207_sfji_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":11},{"effectId":"enemyeffect_11_4","name":"悬赏·频次I","desc":"为自身接下来两场作战添加1只磨砻,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1195_sfyin","count":1,"adds":[{"enemyKey":"enemy_1195_sfyin","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":11},{"effectId":"enemyeffect_11_5","name":"悬赏·频次II","desc":"为自身接下来两场作战添加1只烹泉,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1203_sfhu","count":1,"adds":[{"enemyKey":"enemy_1203_sfhu","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":11},{"effectId":"enemyeffect_11_6","name":"悬赏·频次III","desc":"为自身接下来两场作战添加1只清明,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1209_sfden","count":1,"adds":[{"enemyKey":"enemy_1209_sfden","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":11},{"effectId":"enemyeffect_11_7","name":"悬赏·频次I","desc":"为自身下场战斗添加1只沏虹,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1203_sfhu_2","count":1,"adds":[{"enemyKey":"enemy_1203_sfhu_2","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":11},{"effectId":"enemyeffect_11_8","name":"悬赏·频次II","desc":"为自身下场战斗添加1只新硎,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1207_sfji_2","count":1,"adds":[{"enemyKey":"enemy_1207_sfji_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":11},{"effectId":"enemyeffect_12_1","name":"战术特训·损伤I","desc":"为自身下场战斗添加1只底海滑动者,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1148_dssbr","count":1,"adds":[{"enemyKey":"enemy_1148_dssbr","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":12},{"effectId":"enemyeffect_12_2","name":"战术特训·损伤II","desc":"为自身下场战斗添加1只炽焰源石虫,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1305_mhslim_2","count":1,"adds":[{"enemyKey":"enemy_1305_mhslim_2","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":12},{"effectId":"enemyeffect_12_3","name":"战术特训·损伤III","desc":"为自身下场战斗添加1只灼藤,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_10067_ftsjc","count":1,"adds":[{"enemyKey":"enemy_10067_ftsjc","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":12},{"effectId":"enemyeffect_12_4","name":"悬赏·损伤I","desc":"为自身接下来两场作战添加1只底海滑动者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1148_dssbr","count":1,"adds":[{"enemyKey":"enemy_1148_dssbr","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":12},{"effectId":"enemyeffect_12_5","name":"悬赏·损伤II","desc":"为自身接下来两场作战添加1只控潮术师,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1161_tidmag","count":1,"adds":[{"enemyKey":"enemy_1161_tidmag","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":12},{"effectId":"enemyeffect_12_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只术师快艇,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1162_magmot","count":1,"adds":[{"enemyKey":"enemy_1162_magmot","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":12},{"effectId":"enemyeffect_12_7","name":"悬赏·损伤II","desc":"为自身下场战斗添加1只灼藤,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10067_ftsjc","count":1,"adds":[{"enemyKey":"enemy_10067_ftsjc","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":12},{"effectId":"enemyeffect_12_8","name":"悬赏·损伤II","desc":"为自身下场战斗添加1只异光体孽生者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1439_dslntf_2","count":1,"adds":[{"enemyKey":"enemy_1439_dslntf_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":12},{"effectId":"enemyeffect_13_1","name":"战术特训·持续I","desc":"为自身下场战斗添加1只逐腐兽,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1270_nhstlk","count":1,"adds":[{"enemyKey":"enemy_1270_nhstlk","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":13},{"effectId":"enemyeffect_13_2","name":"战术特训·持续II","desc":"为自身下场战斗添加1只萨卡兹枯朽战士组长,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1267_nhpbr_2","count":1,"adds":[{"enemyKey":"enemy_1267_nhpbr_2","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":13},{"effectId":"enemyeffect_13_3","name":"战术特训·持续III","desc":"为自身下场战斗添加1只尖端萨卡兹枯朽战车,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1272_nhtank_2","count":1,"adds":[{"enemyKey":"enemy_1272_nhtank_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":13},{"effectId":"enemyeffect_13_4","name":"悬赏·持续I","desc":"为自身接下来两场作战添加1只萨卡兹枯朽战士组长,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1267_nhpbr_2","count":1,"adds":[{"enemyKey":"enemy_1267_nhpbr_2","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":13},{"effectId":"enemyeffect_13_5","name":"悬赏·持续II","desc":"为自身接下来两场作战添加1只逐腐兽,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1270_nhstlk","count":1,"adds":[{"enemyKey":"enemy_1270_nhstlk","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":13},{"effectId":"enemyeffect_13_6","name":"悬赏·持续III","desc":"为自身接下来两场作战添加1只萨卡兹枯朽战车,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1272_nhtank","count":1,"adds":[{"enemyKey":"enemy_1272_nhtank","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":13},{"effectId":"enemyeffect_13_7","name":"悬赏·持续I","desc":"为自身下场战斗添加1只假想敌:蚀裂,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_9006_actoxi","count":1,"adds":[{"enemyKey":"enemy_9006_actoxi","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":13},{"effectId":"enemyeffect_13_8","name":"悬赏·持续II","desc":"为自身下场战斗添加1只尖端萨卡兹枯朽战车,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1272_nhtank_2","count":1,"adds":[{"enemyKey":"enemy_1272_nhtank_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":13},{"effectId":"enemyeffect_14_1","name":"战术特训·隐匿I","desc":"为自身下场战斗添加1只隐形弩手,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1019_jshoot","count":1,"adds":[{"enemyKey":"enemy_1019_jshoot","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":14},{"effectId":"enemyeffect_14_2","name":"战术特训·隐匿II","desc":"为自身下场战斗添加1只节日爵士乐手,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_10034_cnvsax","count":1,"adds":[{"enemyKey":"enemy_10034_cnvsax","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":14},{"effectId":"enemyeffect_14_3","name":"战术特训·隐匿III","desc":"为自身下场战斗添加1只家族灭迹人,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1283_sgkill","count":1,"adds":[{"enemyKey":"enemy_1283_sgkill","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":14},{"effectId":"enemyeffect_14_4","name":"悬赏·隐匿I","desc":"为自身接下来两场作战添加1只隐形弩手,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1019_jshoot","count":1,"adds":[{"enemyKey":"enemy_1019_jshoot","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":14},{"effectId":"enemyeffect_14_5","name":"悬赏·隐匿II","desc":"为自身接下来两场作战添加1只隐形术师,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1023_jmage","count":1,"adds":[{"enemyKey":"enemy_1023_jmage","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":14},{"effectId":"enemyeffect_14_6","name":"悬赏·隐匿III","desc":"为自身接下来两场作战添加1只山海众头目,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1299_ymkilr","count":1,"adds":[{"enemyKey":"enemy_1299_ymkilr","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":14},{"effectId":"enemyeffect_14_7","name":"悬赏·隐匿I","desc":"为自身下场战斗添加1只重弩突袭者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1404_msnip","count":1,"adds":[{"enemyKey":"enemy_1404_msnip","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":14},{"effectId":"enemyeffect_14_8","name":"悬赏·隐匿II","desc":"为自身下场战斗添加1只家族暗影灭迹人,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1283_sgkill_2","count":1,"adds":[{"enemyKey":"enemy_1283_sgkill_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":14},{"effectId":"enemyeffect_15_1","name":"战术特训·折射I","desc":"为自身下场战斗添加1只深池方阵战士,若各自行动阶段就达成完美作战,获得1资金","tier":1,"coin":1,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1169_duphlx","count":1,"adds":[{"enemyKey":"enemy_1169_duphlx","count":1,"coin":1,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":15},{"effectId":"enemyeffect_15_2","name":"战术特训·折射II","desc":"为自身下场战斗添加1只深池暗影术师队长,若各自行动阶段就达成完美作战,获得2资金","tier":2,"coin":2,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1168_dumage_2","count":1,"adds":[{"enemyKey":"enemy_1168_dumage_2","count":1,"coin":2,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":15},{"effectId":"enemyeffect_15_3","name":"战术特训·折射III","desc":"为自身下场战斗添加1只深池伙友卫队精英,若各自行动阶段就达成完美作战,获得3资金","tier":3,"coin":3,"payout":"perfect","rounds":1,"multiRound":false,"enemyKey":"enemy_1174_duholy_2","count":1,"adds":[{"enemyKey":"enemy_1174_duholy_2","count":1,"coin":3,"rounds":1,"payout":"perfect","buffKey":"add_enemy_selfbattle_win_gain_coin"}],"draft":false,"draftExcluded":"perfect","draftPool":null,"series":15},{"effectId":"enemyeffect_15_4","name":"悬赏·折射I","desc":"为自身接下来两场作战添加1只深池方阵战士,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1169_duphlx","count":1,"adds":[{"enemyKey":"enemy_1169_duphlx","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":15},{"effectId":"enemyeffect_15_5","name":"悬赏·折射II","desc":"为自身接下来两场作战添加1只深池暗影术师,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1168_dumage","count":1,"adds":[{"enemyKey":"enemy_1168_dumage","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":15},{"effectId":"enemyeffect_15_6","name":"悬赏·折射III","desc":"为自身接下来两场作战添加1只深池伙友卫队,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1174_duholy","count":1,"adds":[{"enemyKey":"enemy_1174_duholy","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":15},{"effectId":"enemyeffect_15_7","name":"悬赏·折射II","desc":"为自身下场战斗添加1只深池重甲卫士队长,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1170_dushld_2","count":1,"adds":[{"enemyKey":"enemy_1170_dushld_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":15},{"effectId":"enemyeffect_15_8","name":"悬赏·折射II","desc":"为自身下场战斗添加1只愤怒的守墓石像,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1172_dugago_2","count":1,"adds":[{"enemyKey":"enemy_1172_dugago_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":15},{"effectId":"enemyeffect_16_1","name":"悬赏·特异III","desc":"为自身下场战斗添加1只泥岩巨像,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1092_mdgint","count":1,"adds":[{"enemyKey":"enemy_1092_mdgint","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_2","name":"悬赏·特异III","desc":"为自身下场战斗添加1只“越长尘”,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1302_ymtro_2","count":1,"adds":[{"enemyKey":"enemy_1302_ymtro_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_3","name":"悬赏·特异III","desc":"为自身下场战斗添加1只狂暴宿主组长,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1062_rager_2","count":1,"adds":[{"enemyKey":"enemy_1062_rager_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_4","name":"悬赏·特异III","desc":"为自身下场战斗添加1只温顺的武装大驮兽,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1415_mmkabi_2","count":1,"adds":[{"enemyKey":"enemy_1415_mmkabi_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_5","name":"悬赏·特异III","desc":"为自身下场战斗添加1只萨卡兹骸骨拷打者,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1364_spnaxe_2","count":1,"adds":[{"enemyKey":"enemy_1364_spnaxe_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_6","name":"悬赏·特异III","desc":"为自身下场战斗添加1只高准度伦蒂尼姆城防自行炮,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1273_stmgun_2","count":1,"adds":[{"enemyKey":"enemy_1273_stmgun_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_7","name":"悬赏·特异III","desc":"为自身下场战斗添加1只乌顶巨角卢鲁,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10144_xdelk_2","count":1,"adds":[{"enemyKey":"enemy_10144_xdelk_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_8","name":"悬赏·特异III","desc":"为自身下场战斗添加1只伊利昂的木驮兽,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10159_mntrjn","count":1,"adds":[{"enemyKey":"enemy_10159_mntrjn","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_9","name":"悬赏·特异II","desc":"为自身下场战斗添加1只拥霜羽兽,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10141_xdpeng_2","count":1,"adds":[{"enemyKey":"enemy_10141_xdpeng_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_10","name":"悬赏·特异II","desc":"为自身下场战斗添加1只异质裂兽·α,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10127_rkmbst_2","count":1,"adds":[{"enemyKey":"enemy_10127_rkmbst_2","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_11","name":"悬赏·损伤I","desc":"为自身下场战斗添加1只心虚设计师,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10097_crshd","count":1,"adds":[{"enemyKey":"enemy_10097_crshd","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_16_12","name":"悬赏·特异I","desc":"为自身下场战斗添加1只转译基底·α,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10081_mpplai","count":1,"adds":[{"enemyKey":"enemy_10081_mpplai","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"hunter","series":16},{"effectId":"enemyeffect_17_1","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只雪孩子,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10138_xdsnow","count":1,"adds":[{"enemyKey":"enemy_10138_xdsnow","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_2","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只新手祭司学徒,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10156_mncrer","count":1,"adds":[{"enemyKey":"enemy_10156_mncrer","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_3","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只冒失的小弟,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10112_ymgds","count":1,"adds":[{"enemyKey":"enemy_10112_ymgds","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_4","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只骇笑看客,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_2009_csaudc","count":1,"adds":[{"enemyKey":"enemy_2009_csaudc","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_5","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只水遁忍者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10116_ymgtop","count":1,"adds":[{"enemyKey":"enemy_10116_ymgtop","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_17_6","name":"悬赏·特异III","desc":"为自身接下来两场作战添加1只自制投石机,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10162_mnctpt","count":1,"adds":[{"enemyKey":"enemy_10162_mnctpt","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":17},{"effectId":"enemyeffect_18_1","name":"悬赏·损伤I","desc":"为自身接下来两场作战添加1只临时收音师,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10094_crstf","count":1,"adds":[{"enemyKey":"enemy_10094_crstf","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_2","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只迷茫的修理小助手,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10073_mpcar","count":1,"adds":[{"enemyKey":"enemy_10073_mpcar","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_3","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只高能源石虫,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1021_bslime","count":1,"adds":[{"enemyKey":"enemy_1021_bslime","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_4","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只圣堂剑士,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10087_hlchgr","count":1,"adds":[{"enemyKey":"enemy_10087_hlchgr","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_5","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只寻仇者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1025_reveng","count":1,"adds":[{"enemyKey":"enemy_1025_reveng","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_18_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只主角阵营角色,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10098_crhro","count":1,"adds":[{"enemyKey":"enemy_10098_crhro","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":18},{"effectId":"enemyeffect_19_1","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只节日气球,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10040_cnvbln","count":1,"adds":[{"enemyKey":"enemy_10040_cnvbln","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_2","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只简饲源石虫,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10001_trslim","count":1,"adds":[{"enemyKey":"enemy_10001_trslim","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_3","name":"悬赏·折射I","desc":"为自身接下来两场作战添加1只深池侦察犬pro,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1165_duhond_2","count":1,"adds":[{"enemyKey":"enemy_1165_duhond_2","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_4","name":"悬赏·飞行II","desc":"为自身接下来两场作战添加1只吉兆飞鳞,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10045_parrot","count":1,"adds":[{"enemyKey":"enemy_10045_parrot","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_5","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只咸鳞汁推荐者,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10044_wintun","count":1,"adds":[{"enemyKey":"enemy_10044_wintun","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_19_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只反派阵营角色,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10099_crvln","count":1,"adds":[{"enemyKey":"enemy_10099_crvln","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":19},{"effectId":"enemyeffect_20_1","name":"悬赏·持续I","desc":"为自身接下来两场作战添加1只萨卡兹枯朽战士,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1267_nhpbr","count":1,"adds":[{"enemyKey":"enemy_1267_nhpbr","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_2","name":"悬赏·频次I","desc":"为自身接下来两场作战添加1只俗心,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1197_sfshu","count":1,"adds":[{"enemyKey":"enemy_1197_sfshu","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_3","name":"悬赏·特异I","desc":"为自身接下来两场作战添加1只潜伏者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1009_lurker","count":1,"adds":[{"enemyKey":"enemy_1009_lurker","count":1,"coin":1,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_4","name":"悬赏·特异II","desc":"为自身接下来两场作战添加1只“独轮车玩具”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10018_sgrobh","count":1,"adds":[{"enemyKey":"enemy_10018_sgrobh","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_5","name":"悬赏·损伤II","desc":"为自身接下来两场作战添加1只无胄盟清扫小队,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1183_mlasrt","count":1,"adds":[{"enemyKey":"enemy_1183_mlasrt","count":1,"coin":2,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_20_6","name":"悬赏·损伤III","desc":"为自身接下来两场作战添加1只鼎沸,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_10054_cjhot","count":1,"adds":[{"enemyKey":"enemy_10054_cjhot","count":1,"coin":3,"rounds":2,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"initial","series":20},{"effectId":"enemyeffect_b_1","name":"碎骨·悬赏","desc":"为自身下场作战添加1个碎骨,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1500_skulsr","count":1,"adds":[{"enemyKey":"enemy_1500_skulsr","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_2","name":"萨卡兹百夫长·悬赏","desc":"为自身下场作战添加1个萨卡兹百夫长,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1501_demonk","count":1,"adds":[{"enemyKey":"enemy_1501_demonk","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_3","name":"弑君者·悬赏","desc":"为自身下场作战添加1个弑君者,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1502_crowns","count":1,"adds":[{"enemyKey":"enemy_1502_crowns","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_4","name":"泥岩·悬赏","desc":"为自身下场作战添加1个泥岩,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1511_mdrock","count":1,"adds":[{"enemyKey":"enemy_1511_mdrock","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_5","name":"腐败骑士·悬赏","desc":"为自身下场作战添加1个腐败骑士,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1513_dekght","count":1,"adds":[{"enemyKey":"enemy_1513_dekght","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_6","name":"凋零骑士·悬赏","desc":"为自身下场作战添加1个凋零骑士,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1513_dekght_2","count":1,"adds":[{"enemyKey":"enemy_1513_dekght_2","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_7","name":"“遗弃者”·悬赏","desc":"为自身下场作战添加1个“遗弃者”,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2005_axetro","count":1,"adds":[{"enemyKey":"enemy_2005_axetro","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_8","name":"喷气人·悬赏","desc":"为自身下场作战添加1个喷气人,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2004_balloon","count":1,"adds":[{"enemyKey":"enemy_2004_balloon","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_9","name":"杰斯顿·威廉姆斯·悬赏","desc":"为自身下场作战添加1个杰斯顿·威廉姆斯,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1516_jakill","count":1,"adds":[{"enemyKey":"enemy_1516_jakill","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_10","name":"W·悬赏","desc":"为自身下场作战添加1个W,将其击倒者获得1资金","tier":1,"coin":1,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1504_cqbw","count":1,"adds":[{"enemyKey":"enemy_1504_cqbw","count":1,"coin":1,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_11","name":"“鼠王”·悬赏","desc":"为自身下场作战添加1个“鼠王”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1509_mousek","count":1,"adds":[{"enemyKey":"enemy_1509_mousek","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_12","name":"“庞贝”·悬赏","desc":"为自身下场作战添加1个“庞贝”,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1050_lslime","count":1,"adds":[{"enemyKey":"enemy_1050_lslime","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_13","name":"大鲍勃·悬赏","desc":"为自身下场作战添加1个大鲍勃,将其击倒者获得2资金","tier":2,"coin":2,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1001_bigbo","count":1,"adds":[{"enemyKey":"enemy_1001_bigbo","count":1,"coin":2,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_14","name":"“自在”·悬赏","desc":"为自身下场作战添加1个“自在”,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1517_xi","count":1,"adds":[{"enemyKey":"enemy_1517_xi","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_15","name":"锏·悬赏","desc":"为自身下场作战添加1个锏,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1525_blkswb","count":1,"adds":[{"enemyKey":"enemy_1525_blkswb","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_16","name":"扎罗,“狼之主”·悬赏","desc":"为自身下场作战添加1个扎罗,“狼之主”,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1535_wlfmster","count":1,"adds":[{"enemyKey":"enemy_1535_wlfmster","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_17","name":"“墓碑”·悬赏","desc":"为自身下场作战添加1个“墓碑”,将其击倒者获得4资金","tier":3,"coin":4,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2008_flking","count":1,"adds":[{"enemyKey":"enemy_2008_flking","count":1,"coin":4,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_18","name":"迷路的巨像·悬赏","desc":"为自身下场作战添加1个迷路的巨像,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2003_rockman","count":1,"adds":[{"enemyKey":"enemy_2003_rockman","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyeffect_b_19","name":"澪·悬赏","desc":"为自身下场作战添加1个澪,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_10118_ymgprc","count":1,"adds":[{"enemyKey":"enemy_10118_ymgprc","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_20","name":"“巨大的丑东西”·悬赏","desc":"为自身下场作战添加1个“巨大的丑东西”,将其击倒者获得5资金","tier":3,"coin":5,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1512_mcmstr","count":1,"adds":[{"enemyKey":"enemy_1512_mcmstr","count":1,"coin":5,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_21","name":"“复仇者”·悬赏","desc":"为自身下场作战添加1个“复仇者”,将其击倒者获得6资金","tier":3,"coin":6,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_1539_reid","count":1,"adds":[{"enemyKey":"enemy_1539_reid","count":1,"coin":6,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_22","name":"“邪魔的利刃”·悬赏","desc":"为自身下场作战添加1个“邪魔的利刃”,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2048_smgrd","count":1,"adds":[{"enemyKey":"enemy_2048_smgrd","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_23","name":"陷落雪祀·悬赏","desc":"为自身下场作战添加1个陷落雪祀,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2050_smsha","count":1,"adds":[{"enemyKey":"enemy_2050_smsha","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyeffect_b_24","name":"纠缠藤蔓·悬赏","desc":"为自身下场作战添加1个纠缠藤蔓,将其击倒者获得3资金","tier":3,"coin":3,"payout":"kill","rounds":1,"multiRound":false,"enemyKey":"enemy_2052_smgia","count":1,"adds":[{"enemyKey":"enemy_2052_smgia","count":1,"coin":3,"rounds":1,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":true,"draftExcluded":null,"draftPool":"boss","series":null},{"effectId":"enemyInitial_1","name":"多轮悬赏 · 假想敌:蚀裂","desc":"后续每场作战添加1只假想敌:蚀裂(被击倒时造成持续伤害),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9006_actoxi","count":1,"adds":[{"enemyKey":"enemy_9006_actoxi","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_2","name":"多轮悬赏 · 假想敌:淤困","desc":"后续每场作战添加1只假想敌:淤困(可造成元素损伤),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9007_acelem","count":1,"adds":[{"enemyKey":"enemy_9007_acelem","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_3","name":"多轮悬赏 · 假想敌:骨刺","desc":"后续每场作战添加1只假想敌:骨刺(拥有隐匿),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9008_acbunn","count":1,"adds":[{"enemyKey":"enemy_9008_acbunn","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_4","name":"多轮悬赏 · 假想敌:黑云","desc":"后续每场作战添加1只假想敌:黑云(空中敌人),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9009_acfort","count":1,"adds":[{"enemyKey":"enemy_9009_acfort","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_5","name":"多轮悬赏 · 假想敌:再生","desc":"后续每场作战添加1只假想敌:再生(需要一定攻击次数击破),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9010_acpupp","count":1,"adds":[{"enemyKey":"enemy_9010_acpupp","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null},{"effectId":"enemyInitial_6","name":"多轮悬赏 · 假想敌:镜膜","desc":"后续每场作战添加1只假想敌:镜膜(拥有折射),击倒它的你或队友获得1资金","tier":2,"coin":1,"payout":"kill","rounds":99,"multiRound":true,"enemyKey":"enemy_9011_acrefr","count":1,"adds":[{"enemyKey":"enemy_9011_acrefr","count":1,"coin":1,"rounds":99,"payout":"kill","buffKey":"add_enemy_kill_gain_coin"}],"draft":false,"draftExcluded":"unseen","draftPool":null,"series":null}],"tactic":[{"effectId":"allybuff_select_1","name":"列装","desc":"你获得2件随机1阶装备,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_1","name":"斯卡蒂的盟誓","desc":"你的阿戈尔、突袭和坚守盟约层数+8,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_2","name":"诗怀雅的盟誓","desc":"你的炎和投资人盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_3","name":"风笛的盟誓","desc":"你的维多利亚、远见和不屈盟约层数+8,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_4","name":"银灰的盟誓","desc":"你的谢拉格、投资人、迅捷盟约层数+8,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_5","name":"莫斯提马的盟誓","desc":"你的拉特兰、奥术盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_6","name":"缇缇的盟誓","desc":"你的萨尔贡、精准盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_7","name":"玛恩纳的盟誓","desc":"你的卡西米尔盟约层数+12,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_2_8","name":"德克萨斯的盟誓","desc":"你的叙拉古、突袭盟约层数+10,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_3","name":"财富","desc":"你获得1资金,若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_4","name":"补给","desc":"你接下来的2次刷新变为免费(可叠加),若存在其他队友则他们也获得","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_5","name":"整备","desc":"你接下来购买的1件装备变为进阶品质","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_6","name":"升华","desc":"你接下来购买的1名干员变为精锐状态","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_1","name":"炎盟约驰援","desc":"你获得1名炎盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_2","name":"谢拉格驰援","desc":"你获得1名谢拉格盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_3","name":"萨尔贡驰援","desc":"你获得1名萨尔贡盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_4","name":"叙拉古驰援","desc":"你获得1名叙拉古盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_5","name":"卡西米尔驰援","desc":"你获得1名卡西米尔盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_6","name":"拉特兰驰援","desc":"你获得1名拉特兰盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_7","name":"维多利亚驰援","desc":"你获得1名维多利亚盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_7_8","name":"阿戈尔驰援","desc":"你获得1名阿戈尔盟约的随机干员棋子","kind":"ally","stageId":null,"team":false},{"effectId":"allybuff_select_11","name":"自愈","desc":"你获得:我方单位每次受到伤害时回复50点生命值;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_13","name":"火力","desc":"你获得:休整期结束时若手牌区至少有3个单位,我方所有干员无视敌人20法术抗性;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_14","name":"征召","desc":"你获得:开始作战时若场上至少有一行存在3名干员,所有干员的再部署时间-50%;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_18","name":"无瑕","desc":"你获得:干员在生命值为满时,攻击力、防御力+30%;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"allybuff_select_19","name":"锐利","desc":"你获得:休整期结束时若手牌区为空,我方所有干员无视敌人30%的防御力;若存在其他队友则他们也获得此效果","kind":"ally","stageId":null,"team":true},{"effectId":"enemydebuff_select_1","name":"排斥:乏力","desc":"全部敌人获得减益效果:攻击力-5%","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_2","name":"排斥:脆弱","desc":"全部敌人获得减益效果:防御力-100","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_3","name":"排斥:致幻","desc":"全部敌人获得减益效果:法术抗性-3","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_4","name":"责罚:乏力","desc":"精英敌人获得减益效果:攻击力-6%","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_5","name":"责罚:脆弱","desc":"精英敌人获得减益效果:防御力-150","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_6","name":"责罚:致幻","desc":"精英敌人获得减益效果:法术抗性-5","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_7","name":"裁决:乏力","desc":"领袖敌人获得减益效果:攻击力-7%","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_8","name":"裁决:脆弱","desc":"领袖敌人获得减益效果:防御力-200","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"enemydebuff_select_9","name":"裁决:致幻","desc":"领袖敌人获得减益效果:法术抗性-7","kind":"enemyDebuff","stageId":null,"team":false},{"effectId":"map_m01_1","name":"模拟战场演变·模式一","desc":"移除场地上全部阻隔工事","kind":"terrain","stageId":"act1autochess_m01","team":false},{"effectId":"map_m02_1","name":"模拟战场演变·模式二","desc":"场地上全部阻隔工事变为射击台","kind":"terrain","stageId":"act1autochess_m02","team":false},{"effectId":"map_m02_2","name":"模拟战场演变·模式三","desc":"移除场地上全部阻隔工事","kind":"terrain","stageId":"act1autochess_m02","team":false},{"effectId":"map_m03_1","name":"模拟战场演变·模式四","desc":"移除场地左侧的阻隔工事","kind":"terrain","stageId":"act1autochess_m03","team":false},{"effectId":"map_m03_2","name":"模拟战场演变·模式五","desc":"场地右侧的射击台变为可以部署高台干员和地面干员的地面","kind":"terrain","stageId":"act1autochess_m03","team":false},{"effectId":"map_m04_1","name":"模拟战场演变·模式六","desc":"移除场地上全部阻隔工事","kind":"terrain","stageId":"act1autochess_m04","team":false},{"effectId":"map_m06_1","name":"模拟战场演变·模式八","desc":"场地中的沙尘暴停止","kind":"terrain","stageId":"act1autochess_m06","team":false},{"effectId":"map_m07_1","name":"模拟战场演变·模式九","desc":"场上的树丛全部消失","kind":"terrain","stageId":"act1autochess_m07","team":false}]},"bountyDrafts":{"initial":{"events":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"slots":10,"pick":"slot","groups":[{"cards":["enemyeffect_18_1","enemyeffect_18_2","enemyeffect_18_3","enemyeffect_18_4","enemyeffect_18_5","enemyeffect_18_6"],"seen":[1,3,5,9,17]},{"cards":["enemyeffect_19_1","enemyeffect_19_2","enemyeffect_19_3","enemyeffect_19_4","enemyeffect_19_5","enemyeffect_19_6"],"seen":[2,15,22]},{"cards":["enemyeffect_17_1","enemyeffect_17_2","enemyeffect_17_3","enemyeffect_17_4","enemyeffect_17_5","enemyeffect_17_6"],"seen":[7,14]},{"cards":["enemyeffect_10_5","enemyeffect_11_4","enemyeffect_12_5","enemyeffect_13_6","enemyeffect_15_4","enemyeffect_20_3"],"seen":[4,10,16]},{"cards":["enemyeffect_10_4","enemyeffect_11_5","enemyeffect_12_6","enemyeffect_14_4","enemyeffect_15_5","enemyeffect_20_2"],"seen":[6,18]},{"cards":["enemyeffect_10_4","enemyeffect_11_5","enemyeffect_12_4","enemyeffect_14_6","enemyeffect_15_4","enemyeffect_20_4"],"seen":[8]},{"cards":["enemyeffect_10_4","enemyeffect_11_6","enemyeffect_12_4","enemyeffect_13_4","enemyeffect_14_5","enemyeffect_15_5"],"seen":[11,20]},{"cards":["enemyeffect_10_4","enemyeffect_11_4","enemyeffect_12_5","enemyeffect_15_6","enemyeffect_20_1","enemyeffect_20_5"],"seen":[12]},{"cards":["enemyeffect_11_4","enemyeffect_12_4","enemyeffect_13_5","enemyeffect_14_4","enemyeffect_15_5","enemyeffect_17_6"],"seen":[13,19,21]}],"rule":{"series":[10,11,12,13,14,15,20],"tiers":[1,1,1,2,2,3],"perSeries":2,"prefer":["enemyeffect_10_6","enemyeffect_20_6"]},"count":6,"assumed":["a uniform pick among the 10 events","the unseen 10th set built by `rule`","险境 R6 drafts like R3"]},"boss":{"events":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"slots":6,"pick":"seen","groups":[{"cards":["enemyeffect_b_10","enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_13","enemyeffect_5_1","enemyeffect_b_11","enemyeffect_b_9","enemyeffect_b_14","enemyeffect_b_23"],"seen":[7,8,9,10,11,12,13,14,15,16,17,18,19,21],"weights":[12,13,12,12,11,5,13,8,7]},{"cards":["enemyeffect_b_10","enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_13","enemyeffect_b_12","enemyeffect_5_1","enemyeffect_b_8","enemyeffect_b_24","enemyeffect_b_19"],"seen":[1,5,22],"weights":[4,2,2,4,2,3,4,4,2]},{"cards":["enemyeffect_b_10","enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_12","enemyeffect_5_1","enemyeffect_b_19","enemyeffect_b_22","enemyeffect_b_21","enemyeffect_b_2"],"seen":[6,20,"bahamut-12294"],"weights":[4,3,2,3,2,2,3,4,4]},{"cards":["enemyeffect_b_10","enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_13","enemyeffect_b_12","enemyeffect_5_1","enemyeffect_b_5","enemyeffect_b_17","enemyeffect_b_20"],"seen":[3],"weights":[2,2,1,1,1,2,2,2,2]},{"cards":["enemyeffect_b_10","enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_13","enemyeffect_b_12","enemyeffect_5_1","enemyeffect_b_4","enemyeffect_b_19"],"seen":[2],"weights":[1,1,2,2,2,2,2,2]},{"cards":["enemyeffect_b_10","enemyeffect_b_1","enemyeffect_b_3","enemyeffect_b_13","enemyeffect_b_12","enemyeffect_5_1"],"seen":[4],"weights":[2,2,2,2,2,2]}],"count":6,"assumed":["a group picked by the matches it came in (the per-match cause is open)","card weights 1 + hits","the single-draft groups completed with their base cards","boss bounties of no seen group are not offered"]},"hunter":{"events":["bounty_hunter_1","bounty_hunter_2","bounty_hunter_3","bounty_hunter_4","bounty_hunter_5","bounty_hunter_6","bounty_hunter_7","bounty_hunter_8","bounty_hunter_9","bounty_hunter_10","bounty_hunter_11","bounty_hunter_12","bounty_hunter_13","bounty_hunter_14","bounty_hunter_15"],"slots":7,"pick":"slot","groups":[{"cards":["enemyeffect_16_4","enemyeffect_16_10","enemyeffect_15_7","enemyeffect_12_7","enemyeffect_13_8","enemyeffect_10_7","enemyeffect_11_7"],"seen":[1,6,21,22],"weights":[5,5,4,4,5,4,4]},{"cards":["enemyeffect_16_3","enemyeffect_15_7","enemyeffect_13_8","enemyeffect_16_9","enemyeffect_14_7","enemyeffect_11_7","enemyeffect_10_7"],"seen":[3,13],"weights":[3,3,3,2,3,3,2]},{"cards":["enemyeffect_16_5","enemyeffect_15_8","enemyeffect_12_7","enemyeffect_14_8","enemyeffect_10_7","enemyeffect_16_11","enemyeffect_11_7"],"seen":[10,12,16],"weights":[4,4,4,3,4,4,2]},{"cards":["enemyeffect_16_7","enemyeffect_16_9","enemyeffect_14_7","enemyeffect_16_11","enemyeffect_11_7","enemyeffect_13_7"],"seen":[11],"open":1,"weights":[2,2,2,2,2,2]},{"cards":["enemyeffect_16_8","enemyeffect_16_10","enemyeffect_14_8","enemyeffect_10_7","enemyeffect_16_12","enemyeffect_13_7"],"seen":[14,19],"open":1,"weights":[3,3,3,3,3,3]},{"cards":["enemyeffect_16_1","enemyeffect_10_8","enemyeffect_11_8","enemyeffect_15_7","enemyeffect_13_7","enemyeffect_14_7"],"seen":[17],"open":1,"weights":[2,2,2,2,2,2]},{"cards":["enemyeffect_10_8","enemyeffect_12_7","enemyeffect_13_7","enemyeffect_14_7","enemyeffect_11_7","enemyeffect_16_12"],"seen":[15],"open":1,"weights":[2,2,2,2,2,2]}],"rule":{"size":7,"onePerSeries":[10,11,12,13,14,15],"maxSeries16":2,"giants":["enemyeffect_16_1","enemyeffect_16_2","enemyeffect_16_3","enemyeffect_16_4","enemyeffect_16_5","enemyeffect_16_6","enemyeffect_16_7","enemyeffect_16_8"],"cards":["enemyeffect_10_8","enemyeffect_11_8","enemyeffect_12_7","enemyeffect_12_8","enemyeffect_13_8","enemyeffect_14_8","enemyeffect_15_7","enemyeffect_15_8","enemyeffect_16_9","enemyeffect_16_10","enemyeffect_10_7","enemyeffect_11_7","enemyeffect_13_7","enemyeffect_14_7","enemyeffect_16_11","enemyeffect_16_12"]},"count":6,"assumed":["one of the 7 seen lists, picked uniformly (which of the 15 events R11 fires is open)","card weights 1 + hits","the `open` cards built by `rule`"]}},"shopDraft":{"rounds":[11],"slots":[{"6":1},{"6":1},{"5":1},{"coin":1},{"3":1,"4":2,"5":3,"coin":2},{"3":1,"4":2,"5":3,"coin":2}],"coin":"chess_item_1_03_e_a","itemWeights":{"chess_item_3_12_e_a":2,"chess_item_4_01_e_a":2,"chess_item_4_11_e_a":2,"chess_item_5_03_e_a":3,"chess_item_5_06_e_a":2,"chess_item_5_07_e_a":3,"chess_item_5_09_e_a":3,"chess_item_6_02_e_a":2,"chess_item_6_03_e_a":2,"chess_item_6_08_e_a":2,"chess_item_6_09_e_a":5,"chess_item_6_11_e_a":2},"seen":[2,4,5,8],"count":6,"assumed":["the slot split","item weights 1 + seen","solo shows 3 of the 6","other rounds (标准 / 险境) keep the previous draw: tiers I–VI with replacement"]},"tacticDraft":{"rounds":[11],"kinds":["ally"],"weights":{"allybuff_select_1":4,"allybuff_select_2_1":2,"allybuff_select_2_4":3,"allybuff_select_2_5":3,"allybuff_select_2_7":2,"allybuff_select_3":3,"allybuff_select_4":4,"allybuff_select_5":2,"allybuff_select_6":4,"allybuff_select_7_2":2,"allybuff_select_7_3":2,"allybuff_select_7_4":2,"allybuff_select_7_8":3,"allybuff_select_19":2},"seen":[7,9,18,20],"count":6,"assumed":["card weights 1 + seen","independent draws (no slot structure)","no terrain card at R11","solo shows 3","other rounds (标准 / 险境) keep every card, uniform, with replacement"]},"schedule":{"mode_training_1":{"spRounds":[3],"rounds":{"3":{"families":[{"family":"supply","weight":100}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1_tr"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_single_funny":{"spRounds":[],"rounds":{}},"mode_single_normal":{"spRounds":[6,9],"rounds":{"6":{"families":[{"family":"supply","weight":100}],"cards":3,"supplyTiers":[2,5],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1_s","enemy_initial_2_s","enemy_initial_3_s","enemy_initial_4_s","enemy_initial_5_s","enemy_initial_6_s","enemy_initial_7_s","enemy_initial_8_s","enemy_initial_9_s","enemy_initial_10_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true},"9":{"families":[{"family":"tactic","weight":100}],"cards":3,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1_s","bossInitial_2_s","bossInitial_3_s","bossInitial_4_s","bossInitial_5_s","bossInitial_6_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true}}},"mode_single_hard":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1_s","enemy_initial_2_s","enemy_initial_3_s","enemy_initial_4_s","enemy_initial_5_s","enemy_initial_6_s","enemy_initial_7_s","enemy_initial_8_s","enemy_initial_9_s","enemy_initial_10_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1_s","bossInitial_2_s","bossInitial_3_s","bossInitial_4_s","bossInitial_5_s","bossInitial_6_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":14},{"family":"shop","weight":4},{"family":"tactic","weight":4}],"cards":3,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1_s","bounty_hunter_2_s","bounty_hunter_3_s","bounty_hunter_4_s","bounty_hunter_5_s","bounty_hunter_6_s","bounty_hunter_7_s","bounty_hunter_8_s","bounty_hunter_9_s","bounty_hunter_10_s","bounty_hunter_11_s","bounty_hunter_12_s","bounty_hunter_13_s","bounty_hunter_14_s","bounty_hunter_15_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true}}},"mode_single_abyss":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1_s","enemy_initial_2_s","enemy_initial_3_s","enemy_initial_4_s","enemy_initial_5_s","enemy_initial_6_s","enemy_initial_7_s","enemy_initial_8_s","enemy_initial_9_s","enemy_initial_10_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":3,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1_s","bossInitial_2_s","bossInitial_3_s","bossInitial_4_s","bossInitial_5_s","bossInitial_6_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":14},{"family":"shop","weight":4},{"family":"tactic","weight":4}],"cards":3,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1_s","bounty_hunter_2_s","bounty_hunter_3_s","bounty_hunter_4_s","bounty_hunter_5_s","bounty_hunter_6_s","bounty_hunter_7_s","bounty_hunter_8_s","bounty_hunter_9_s","bounty_hunter_10_s","bounty_hunter_11_s","bounty_hunter_12_s","bounty_hunter_13_s","bounty_hunter_14_s","bounty_hunter_15_s"],"supply":["equip_free_2_s","equip_free_3_s","equip_free_4_s"],"shop":["artifact_paid_1_s","artifact_paid_2_s","artifact_paid_3_s","artifact_paid_4_s","artifact_paid_5_s"],"tactic":["buff_select_1_s","buff_select_2_s","buff_select_3_s","buff_select_4_s","hardbuff_select_1_s","hardbuff_select_2_s","hardbuff_select_3_s","terrain_m01_1_s","terrain_m02_1_s","terrain_m02_2_s","terrain_m03_1_s","terrain_m04_1_s","terrain_m06_1_s","terrain_m07_1_s"]},"assumed":true}}},"mode_multi_funny":{"spRounds":[3,9],"rounds":{"3":{"families":[{"family":"supply","weight":45},{"family":"tactic","weight":35},{"family":"shop","weight":20}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true},"9":{"families":[{"family":"supply","weight":45},{"family":"tactic","weight":35},{"family":"shop","weight":20}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_multi_normal":{"spRounds":[3,6,9],"rounds":{"3":{"families":[{"family":"bounty","weight":50},{"family":"supply","weight":25},{"family":"shop","weight":10},{"family":"tactic","weight":15}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true},"6":{"families":[{"family":"bounty","weight":50},{"family":"supply","weight":25},{"family":"shop","weight":10},{"family":"tactic","weight":15}],"cards":6,"supplyTiers":[2,5],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true},"9":{"families":[{"family":"bounty","weight":50},{"family":"supply","weight":25},{"family":"shop","weight":10},{"family":"tactic","weight":15}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_multi_hard":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":14},{"family":"shop","weight":4},{"family":"tactic","weight":4}],"cards":6,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1","bounty_hunter_2","bounty_hunter_3","bounty_hunter_4","bounty_hunter_5","bounty_hunter_6","bounty_hunter_7","bounty_hunter_8","bounty_hunter_9","bounty_hunter_10","bounty_hunter_11","bounty_hunter_12","bounty_hunter_13","bounty_hunter_14","bounty_hunter_15"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}},"mode_multi_abyss":{"spRounds":[3,9,11],"rounds":{"3":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":["enemy_initial_1","enemy_initial_2","enemy_initial_3","enemy_initial_4","enemy_initial_5","enemy_initial_6","enemy_initial_7","enemy_initial_8","enemy_initial_9","enemy_initial_10"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"9":{"families":[{"family":"bounty","weight":100}],"cards":6,"supplyTiers":[3,6],"bountyDraft":"boss","events":{"bounty":["bossInitial_1","bossInitial_2","bossInitial_3","bossInitial_4","bossInitial_5","bossInitial_6"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":false},"11":{"families":[{"family":"bounty","weight":14},{"family":"shop","weight":4},{"family":"tactic","weight":4}],"cards":6,"supplyTiers":[4,6],"bountyDraft":"hunter","events":{"bounty":["bounty_hunter_1","bounty_hunter_2","bounty_hunter_3","bounty_hunter_4","bounty_hunter_5","bounty_hunter_6","bounty_hunter_7","bounty_hunter_8","bounty_hunter_9","bounty_hunter_10","bounty_hunter_11","bounty_hunter_12","bounty_hunter_13","bounty_hunter_14","bounty_hunter_15"],"supply":["equip_free_1","equip_free_2","equip_free_3","equip_free_4"],"shop":["artifact_paid_1","artifact_paid_2","artifact_paid_3","artifact_paid_4","artifact_paid_5"],"tactic":["buff_select_1","buff_select_2","buff_select_3","buff_select_4","hardbuff_select_1","hardbuff_select_2","hardbuff_select_3","terrain_m01_1","terrain_m02_1","terrain_m02_2","terrain_m03_1","terrain_m04_1","terrain_m06_1","terrain_m07_1"]},"assumed":true}}}},"pools":{"pool_equip_normal":{"kind":"equip","rule":"shopEligible","maxTier":"shopLevel","assumed":true},"pool_equip_shop_1":{"kind":"equip","rule":"shopEligible","tiers":[1],"assumed":true},"pool_equip_kathe":{"kind":"equip","rule":"shopEligible","maxTier":"shopLevel","assumed":true},"pool_equip_narant":{"kind":"equip","rule":"shopEligible","maxTier":"shopLevel","assumed":true},"pool_equip_vict":{"kind":"equip","items":["chess_item_4_09_e_a","chess_item_3_09_e_a","chess_item_3_10_e_a","chess_item_2_03_e_a"],"assumed":true},"pool_equip_pepe":{"kind":"equip","weighted":[["chess_item_1_03_e_a",45],["chess_item_2_04_e_a",45],["chess_item_6_07_e_a",10]],"goldenWeights":[40,40,20],"assumed":true},"pool_equip_rockr":{"kind":"equip","items":["chess_item_4_09_e_a","chess_item_3_09_e_a","chess_item_3_10_e_a","chess_item_2_03_e_a"],"assumed":true},"pool_chess_glady":{"kind":"chess","items":["chess_char_3_05_a","chess_char_2_07_a","chess_char_1_04_a"],"assumed":true},"pool_char_pinus":{"kind":"chess","weighted":[["chess_char_1_19_a",45],["chess_char_2_18_a",45],["chess_char_4_20_a",10]],"assumed":true},"pool_char_later":{"kind":"chess","bond":"lateranoShip","minTier":4,"golden":true,"rule":"shopEligible","assumed":true},"pool_chess_shop_1_reward":{"kind":"chess","tier":1,"rule":"shopEligible","assumed":true},"pool_chess_shop_2_reward":{"kind":"chess","tier":2,"rule":"shopEligible","assumed":true},"pool_chess_shop_3_reward":{"kind":"chess","tier":3,"rule":"shopEligible","assumed":true},"pool_chess_shop_4_reward":{"kind":"chess","tier":4,"rule":"shopEligible","assumed":true},"pool_chess_shop_5_reward":{"kind":"chess","tier":5,"rule":"shopEligible","assumed":true},"pool_chess_shop_6_reward":{"kind":"chess","tier":6,"rule":"shopEligible","assumed":true}}} \ No newline at end of file diff --git a/docs/DATA.md b/docs/DATA.md index 77e4fd0f..e4032bd2 100644 --- a/docs/DATA.md +++ b/docs/DATA.md @@ -318,12 +318,14 @@ Types: `BAND_INITIAL` 41, `BOND` 23, `EQUIP` 115, `ENEMY_GAIN` 129 (悬赏), `BU | Key | Example | Meaning | |---|---|---| | `events[id]` | `{"id":"enemy_initial_1","choiceType":"BOUNTY_HUNT","effectType":"ENEMY_GAIN","name":"悬赏决策","desc":"…","color":"#35d8b4","family":"bounty","solo":false,"training":false}` | 109 official choice events; `_s` = solo copies; `usedBy` on events opened by items (`hunter_band_1` ← 教鞭 / “神秘顾客”) | -| `families` | `{"bounty":{"name":"悬赏决策",…},"supply":{…},"shop":{…},"tactic":{…}}` | 悬赏决策 / 道具补给 / 机密商店 / 战术决策 | +| `families` | `{"bounty":{"name":"悬赏决策",…},"supply":{…},"shop":{…},"tactic":{…}}` | 悬赏决策 / 道具补给 / 机密商店 / 战术决策; `desc` = the overlay header after the name, the official event text (战术决策 "进行协同调整,做好迎战准备。", as on the official screens and in effectChoiceInfoDict `buff_select_*`) | | `format` | `{"multi":{"cards":6,"pickOrder":"random","firstPickSec":30,"otherPickSec":16,"onTimeout":"autoPickRandom","eachPlayerPicks":1},"solo":{"cards":3,"timer":null},"opensAfterIncome":true}` | | -| `cards.bounty[]` | `{"effectId":"enemyeffect_10_4","name":"悬赏·飞行I","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1005_yokai","count":1,"adds":[…],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10}` | `payout` `kill` (killer gets coins, 联防 helpers too) / `perfect` (chooser's own phase perfect); `rounds` = battles affected (99 = all remaining); `tier` from the I/II/III suffix (else coin value); `enemyKey` = the effect's `enemy_id` (fixed per card; the title only names category and tier); `draft` = offered by a 悬赏决策 draft (86 cards); else `draftExcluded` `perfect` (战术特训: "仅由法术教鞭生成" — the 教鞭 Art's cards; 20) / `hidden` (鸭爵 / 高普尼克 / 流泪小子 / 圆仔; 4) / `unseen` (in none of the 27 official bounty drafts of the user's 33 screenshots: the 7 multi-round cards, enemyeffect_3_*, the boss bounties of no seen R9 group; 19, [ASSUMED] not offered) — build-data `bountyDraftExclusion`, `server/match/choices.js draftBounty`, user playtest #6 item 4, player feedback after 0.1.0 report #2; `draftPool` = the kind of draft that offers it: `initial` (R3: the 42 "接下来两场作战" cards), `boss` (R9: 19 boss bounties + 源石虫·特训), `hunter` (R11: the faction _7 / _8 and 特异 series 16 "下场战斗" cards, 24), null when not drafted; `series` = N of `enemyeffect_N_M` (null otherwise) | -| `cards.tactic[]` | `{"effectId":"map_m01_1","name":"模拟战场演变·模式一","kind":"terrain","stageId":"act1autochess_m01","team":false}` | `kind` `ally` / `enemyDebuff` / `terrain` (only for the match stage); `team` = also given to teammates | -| `bountyDrafts[kind]` | `{"initial":{"events":[…],"slots":10,"sets":[{"cards":[…6],"seen":[1,3,5,9]},…],"mixed":{"series":[10,11,12,13,14,15,20],"count":6,"tiers":[1,1,1,2,2,3]},"count":6},"boss":{"events":[…],"templates":[{"featured":[…],"fill":[…],"seen":[1,5]},…],"count":6},"hunter":{"events":[…],"slots":15,"templates":[{"featured":[…],"fill":[…],"seen":[1,6]},…],"rule":{"giants":[…],"groupCards":[…],"groupSizes":[1,2,3,4],"fill":[…]},"onePerSeries":[10,…,15],"count":6}}` | the official 悬赏决策 structures, read from 33 screenshots of 11 official co-op 绝境 / 终极 matches (player feedback after 0.1.0 report #2; build-data `BOUNTY_INITIAL_SETS`, readings in `test/fixtures/official-bounty-drafts.json`, `seen` = its match numbers): `initial` = one of `slots` fixed sets, the seen `sets` or for an unseen slot `mixed` (one card from each of `count` of `series`, with `tiers`) [ASSUMED]; `boss` = a `templates` entry: its `featured` bosses + `fill` drawn to 6 (uniform among the seen groups [ASSUMED]); `hunter` = one of `slots` events: a seen `templates` group — its `featured` 特异III giant + tier-II cards, always together (matches 1 and 6 share the whole group, only the tier-I card differs) — or for an unseen slot a `rule` group (one of `giants` + `groupSizes` of `groupCards`), then tier-I `fill` to 6, at most one card per `onePerSeries` series (the group / fill split by tier, the unseen slots and the uniform pick among the events [ASSUMED]) | -| `schedule[modeId]` | `{"spRounds":[3,6,9],"rounds":{"3":{"families":[{"family":"bounty","weight":50},…],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":[…],"supply":[…],"shop":[…],"tactic":[…]},"assumed":true}}}` | research 01 A4 defaults: pick a family by weight; `supplyTiers` = item tier window for 道具补给; 机密商店 draws any tier; `bountyDraft` = the `bountyDrafts` kind of the round's 悬赏决策 (R3 / 险境 R6 `initial`, R9 `boss`, R11 `hunter`); 绝境 / 终极 R11 = 悬赏决策 45 / 机密商店 35 / 战术决策 20 (the official co-op R11s: 5 / 4 / 2 of 11, no 道具补给; weights [ASSUMED]; solo takes the same weights [ASSUMED: no solo screenshot — extrapolated from co-op, the data has solo R11 悬赏决策 events `bounty_hunter_*_s`]); `events` = the official event ids of that kind (`enemy_initial_*`, `bossInitial_*`, `bounty_hunter_*`), usable as the phase header | +| `cards.bounty[]` | `{"effectId":"enemyeffect_10_4","name":"悬赏·飞行I","tier":1,"coin":1,"payout":"kill","rounds":2,"multiRound":false,"enemyKey":"enemy_1005_yokai","count":1,"adds":[…],"draft":true,"draftExcluded":null,"draftPool":"initial","series":10}` | `payout` `kill` (killer gets coins, 联防 helpers too) / `perfect` (chooser's own phase perfect); `rounds` = battles affected (99 = all remaining); `tier` from the I/II/III suffix (else coin value); `enemyKey` = the effect's `enemy_id` (fixed per card; the title only names category and tier); `draft` = offered by a 悬赏决策 draft (86 cards); else `draftExcluded` `perfect` (战术特训: "仅由法术教鞭生成" — the 教鞭 Art's cards; 20) / `hidden` (鸭爵 / 高普尼克 / 流泪小子 / 圆仔; 4) / `unseen` (in none of the 59 official bounty drafts of the user's 66 screenshots: the 7 multi-round cards, enemyeffect_3_*, the boss bounties of no seen R9 group; 19, [ASSUMED] not offered) — build-data `bountyDraftExclusion`, `server/match/choices.js draftBounty`, user playtest #6 item 4, player feedback after 0.1.0 report #2; `draftPool` = the kind of draft that offers it: `initial` (R3: the 42 "接下来两场作战" cards), `boss` (R9: 19 boss bounties + 源石虫·特训), `hunter` (R11: the faction _7 / _8 and 特异 series 16 "下场战斗" cards, 24), null when not drafted; `series` = N of `enemyeffect_N_M` (null otherwise) | +| `cards.tactic[]` | `{"effectId":"map_m01_1","name":"模拟战场演变·模式一","kind":"terrain","stageId":"act1autochess_m01","team":false}` | `kind` `ally` / `enemyDebuff` / `terrain` (only for the match stage); `team` = also given to teammates. A 战术决策 draws each card on its own, with replacement, so the same card can be offered twice (official match 7 R11: 补给 ×2; `tacticDraft`) | +| `bountyDrafts[kind]` | `{"initial":{"events":[…],"slots":10,"pick":"slot","groups":[{"cards":[…6],"seen":[1,3,5,9,17]},…],"rule":{"series":[10,…,15,20],"tiers":[1,1,1,2,2,3],"perSeries":2,"prefer":["enemyeffect_10_6","enemyeffect_20_6"]},"count":6},"boss":{"events":[…],"slots":6,"pick":"seen","groups":[{"cards":[…9],"seen":[7,…,21],"weights":[12,13,…]},…],"count":6},"hunter":{"events":[…],"slots":7,"pick":"slot","groups":[{"cards":[…7],"seen":[1,6,21,22],"weights":[…]},{"cards":[…6],"open":1,…},…],"rule":{"size":7,"onePerSeries":[10,…,15],"maxSeries16":2,"giants":[…],"cards":[…]},"count":6}}` | the official 悬赏决策 card lists, read from 66 screenshots of 22 official co-op 绝境 / 终极 matches (player feedback after 0.1.0 report #2; build-data `BOUNTY_INITIAL_SETS` / `BOUNTY_BOSS_GROUPS` / `BOUNTY_HUNTER_GROUPS`, readings in `test/fixtures/official-bounty-drafts.json`, `seen` = its match numbers). A draft = one group (`pick` `slot`: one of `slots` events, uniform — a seen group or, for an unseen event, a list built by `rule`; `seen`: a group by the matches it came in), then `count` different cards of its `cards` drawn one by one by `weights` (1 + the drafts of the group the card showed in; a rule-built card 1). `initial`: 9 seen sets of 6 (all six shown), the 10th by `rule` — tiers I I I II II III, ≤ `perSeries` a series, the III one of `prefer` (the two-battle cards no draft showed) [ASSUMED]; `boss`: the 6 groups of 9, 9, 9, 9, 8 and 6 cards (one per bossInitial event; 9 where three named bosses came; the three single-draft groups completed only with the base cards they lack [ASSUMED] — match 4's base-only group may instead be a draft of the 泥岩 group), the 鼠王 group in 14 of 22 matches — every one on the dark grey board — so picked by `seen` [ASSUMED: the per-match cause is open]; `hunter`: the 7 seen lists of 7, `slots` 7 so one of them uniform, so no list is built from nothing [ASSUMED] (which of the 15 events R11 fires is open: by the blocks of effectChoiceInfoDict it would be bounty_hunter_8..15, beside artifact_paid_4 / 5 and hardbuff_select; with 8 events an unseen list would come in about 1 R11 bounty draft in 8); `open` = cards still unseen, drawn by `rule`: a giant for a list without one, else tier I / II cards, one per `onePerSeries` series, ≤ `maxSeries16` of 16_9..12 [ASSUMED] — the only way 12_8 / 16_2 / 16_6 (in no draft) come, about 1 R11 bounty draft in 15 | +| `schedule[modeId]` | `{"spRounds":[3,6,9],"rounds":{"3":{"families":[{"family":"bounty","weight":50},…],"cards":6,"supplyTiers":[1,4],"bountyDraft":"initial","events":{"bounty":[…],"supply":[…],"shop":[…],"tactic":[…]},"assumed":true}}}` | research 01 A4 defaults: pick a family by weight; `supplyTiers` = item tier window for 道具补给; 机密商店 draws `shopDraft` at its `rounds` (R11), else any normal shop item of tiers I–VI per card (duplicates allowed); `bountyDraft` = the `bountyDrafts` kind of the round's 悬赏决策 (R3 / 险境 R6 `initial`, R9 `boss`, R11 `hunter`); 绝境 / 终极 R11 = 悬赏决策 14 / 机密商店 4 / 战术决策 4 (the official co-op R11s of 22 matches, no 道具补给; weights = those counts [ASSUMED]; solo takes the same weights [ASSUMED: no solo screenshot — extrapolated from co-op, the data has solo R11 悬赏决策 events `bounty_hunter_*_s`]); `events` = the official event ids of that kind (`enemy_initial_*`, `bossInitial_*`, `bounty_hunter_*`), usable as the phase header | +| `shopDraft` | `{"rounds":[11],"slots":[{"6":1},{"6":1},{"5":1},{"coin":1},{"3":1,"4":2,"5":3,"coin":2},{"3":1,"4":2,"5":3,"coin":2}],"coin":"chess_item_1_03_e_a","itemWeights":{"chess_item_6_09_e_a":5,…},"seen":[2,4,5,8],"count":6}` | the official 机密商店 (R11 of matches 2, 4, 5, 8; build-data `SHOP_DRAFT`; the user: "机密商店按官方改成可以重复吧"): six slots, each drawn on its own — with replacement, so an item can come twice (official: 盟约之币 ×2, 变形同构体 ×2) — a tier (or `coin` = 盟约之币) by the slot's weights, then an item of that tier by `itemWeights` (1 + the official cards it showed on; unlisted 1). Every official shop: exactly two tier VI, ≥ 1 V, ≥ 1 盟约之币, no other tier I / II; the slot split and the weights [ASSUMED]; solo 3 of the 6 [ASSUMED]; only at `rounds` (R11 = 绝境 / 终极, the rounds of the screenshots) — the earlier 机密商店 of 标准 R3 / R9 and 险境 R3 / R6 / R9 (no screenshot; the data's shop events sit in three blocks) keep the previous draw, any normal shop item of tiers I–VI per card, with replacement [ASSUMED]; free (price 0) | +| `tacticDraft` | `{"rounds":[11],"kinds":["ally"],"weights":{"allybuff_select_4":4,…},"seen":[7,9,18,20],"count":6}` | the official 战术决策 (R11 of matches 7, 9, 18, 20; build-data `TACTIC_DRAFT`; the user: "战术决策也按官方改成可以重复吧"): six cards, each drawn on its own — with replacement, so a card can come twice (official: 补给 ×2 in match 7; the other three drafts show six different cards). All 24 official cards are `ally` cards (no 排斥 / 责罚 / 裁决, no 模拟战场演变; four drafts without a debuff: about 0.04 % for the previous draw, 6 different cards of the 26 ally + 9 debuff cards), and 列装 / 财富 / 补给 / 整备 / 升华 made 12 of them (uniform: about 4.6), so at `rounds` (R11 = 绝境 / 终极, the round of the screenshots) only the cards of `kinds`, each by `weights` (1 + the official cards it showed on; unlisted 1) [ASSUMED: the weights; no terrain card at R11 — the maps of the 4 matches are unknown]; each card independent, no slots like `shopDraft` [ASSUMED, open: all 4 drafts hold a 驰援, a 盟誓 and two of 列装 / 财富 / 补给 / 整备 / 升华 — about 3 % under independent draws, a pattern spotted after the fact]; solo 3 [ASSUMED]; other rounds (标准 R3 / R9, 险境 R3 / R6 / R9, 险境 solo R9; no screenshot) every card uniform, terrain cards only for the match stage, with replacement too [ASSUMED]. A card acting only on dead bonds is never offered (`Match.bondLive`). `assumed` lists the assumed parts | | `pools[poolId]` | `{"kind":"equip","items":[…]}` / `{"kind":"chess","tier":2,"rule":"shopEligible"}` | server-side reward pools referenced by effects (`pool_equip_*`, `pool_chess_shop_N_reward`, `pool_char_later`, …), all [ASSUMED]; `rule:"shopEligible"` = visible/non-hidden entries, `maxTier:"shopLevel"` = ≤ current shop level, `weighted` = `[[id, weight]]`. `pool_equip_vict` (维多利亚, every 25 layers: "获得一件带有随机特殊效果的维式重锤") and `pool_equip_rockr` (洛洛's 定制品; user playtest #4 — the research 04 §8 guess 有限加速器 / 激光发射器 / 护盾无人机 / 双模机械臂 / 蜂鸣器 is superseded) = the 4 special 维式重锤, uniform | ## 9. `enemies.json` — `{ [enemyKey]: Enemy }` (249 keys that can appear) diff --git a/docs/DESIGN.md b/docs/DESIGN.md index e3a23384..0fdd5cc1 100644 --- a/docs/DESIGN.md +++ b/docs/DESIGN.md @@ -397,7 +397,7 @@ Each domain file `server/sim/content/{tokens,bonds,garrisons,items,bands,enemies - items: 56 equipment (+golden) + 3 Arts; 变形同构体 bond grant; VI-tier set/combos. - bands: 40 strategies (meta + battle). 鸭爵 “神秘顾客” swaps 0–2 ground enemies (not the leader, its parts or bounties; on a pair boss field only the player's half — the boss / hidden `onBattleStart` event carries `routes` and `side`) in every teammate's normal / Final Assault / Hidden Core battle from R5 into the act2 鸭爵 / 高普尼克 / 流泪小子 / 圆仔 (lpr 1, 1 fund to the killer, 联防 included) (§21.5). - enemies: special-type behaviours (FLY, TIMES, ELEMENT, DOT, INVISIBLE, REFLECTION, SPECIAL) and notable individual abilities from `data/enemies.json`; bosses 1–10 scripted — the huge leaders (假想敌:胄 ×2, 假想敌:管 ×2, 盐风主教昆图斯, 阿利斯泰尔, “萨米的意志”) are 自缚 + 无法被阻挡 (PRTS 天赋; `content/bosses.js SELF_BOUND`: a persistent noMove + unblockable buff from spawn) with their hit area (§19.4); 圆仔 and 鸭爵 are 无法被阻挡 (PRTS 天赋, §21.5); the knock-out forms follow PRTS — 深池逐火 余烬 (5 / 10 hits, 隐匿, blockable, back after 10 s), 转译基底·α (damage cancelled until its 2 s change into 寻仇者 / 特战术师 / 幽灵), the leaders' 重生, 守墓石像's statue and flight — and every 重生 clears what operators put on the enemy and restarts its skills from their initial cooldown (§21.4, §21.19); the mode's air units are 静态刚体, never moved (§21.9); leader parts (斩胄之剑 / 破胄之锤 / 碎铳之簧) pass every damage they take to their leader 1:1 as 无来源 HP loss (`PART_TRANSFER` 1, PRTS "等量"), a 假想敌:胄 drone that dies costs it 2 % of the pool (`DRONE_LINK_BASE 'pool'`) (§20.10, §20.13); devices/terrain. -- choices: 机变 families (悬赏决策 bounties, 道具补给, 机密商店, 战术决策 team/personal buffs). 悬赏决策 = the official structure of its round (choices.json `bountyDrafts`, 86 drafted cards: R3 a fixed set of six 两场 cards, R9 a boss group + cheap fill, R11 a 特异III giant group + tier-I fill; §21.2); bounty cards carry `descRaw`; no draft offers a multi-round card, and 教鞭's lasts two battles (`choices.js MULTI_ROUND_BOUNTY_BATTLES`, §20.6). 教鞭 = a random 战术特训 card (3 drawn, 1 taken). +- choices: 机变 families (悬赏决策 bounties, 道具补给, 机密商店, 战术决策 team/personal buffs). 悬赏决策 = the official structure of its round (choices.json `bountyDrafts`, 86 drafted cards: R3 a fixed set of six 两场 cards, R9 6 of a boss group's list, R11 6 of a seen 7-card list; §21.2); 机密商店 (R11 the official composition) and 战术决策 can offer the same card twice (`shopDraft` / `tacticDraft`); bounty cards carry `descRaw`; no draft offers a multi-round card, and 教鞭's lasts two battles (`choices.js MULTI_ROUND_BOUNTY_BATTLES`, §20.6). 教鞭 = a random 战术特训 card (3 drawn, 1 taken). --- @@ -1116,7 +1116,7 @@ In SETTLE it is the field the last battle left on screen. In prep without watchi Twenty-seven reports after the public 0.1.0 release (2026-10-02), relayed by the user in five batches; most were not tested by the user. Verdicts: **real** (fixed), **partly** (the rule was right, what a player sees was wrong or a related part was wrong — fixed), **not real** (not reproduced; tests lock the rule). Where each is handled: batch 1 — #1 拉普兰德's "获得该干员后该回合的首次刷新" should stack 叙拉古 → §21.1 (real); #2 late bounty enemies offered in early bounty drafts → §21.2 (real); #3 the water pool map: operators deployable in the water, 突袭 operators land in it → §21.3 (real); #4 昆图斯's 突变细胞 gone after one use → §21.1 (real: not consumed); #5 转译基底 does not transform → §21.4 (real); #6 凯瑟琳's three upgrade items shown wrong → §21.2 (real); #7 鸭爵's 圆仔 blockable, audit the other 鸭爵 enemies → §21.5 (real); #8 深池逐火战士's 怨恨的余烬 cannot be killed → §21.4 (real); #9 tacticians (伺夜) can place the tactical point outside their attack range → §21.3 (real); #10 bots too dumb, smarter without more CPU → §21.6 (real). Batch 2 — B1 奥术 not working → §21.7 (partly: the bond works, 标准 switches it off); B2 源石溶剂 white + white → gold, then an extra white → §21.7 (not real); B3 维娜·维多利亚 S3 summons one 黄金盟誓 → §21.8 (real); B4 玛恩纳's skill deals no damage → §21.8 (real, on flying waves); B5 薄绿 can pull flying enemies → §21.9 (real). Batch 3 — C1 the hidden leader's "造成50%伤害" broadcast before the fight → §21.10 (real); C2 变形同构体 + class item: the bond member count excludes the wearer → §21.11 (partly: display only). Batch 4 — D1 信仰搅拌机: 源石溶剂's HP drain should trigger S3 → §21.12 (real); D2 野鬃's skill sometimes pushes the wrong way → §21.13 (real); D3 special 源石虫 all drawn as the plain one → §21.14 (partly); D4 暴鸰's bombs do not drop properly → §21.14 (partly); D5 the originium-floor map's lower route should cut diagonally from row 4 to row 3 → §21.15 (real). Batch 5 — E1 烛煌 S3's attack range does not change → §21.16 (partly: the card); E2 medics that block a roaming leader stop healing and attack it → §21.17 (not real); E3 卡涅利安's attack is not a true AoE → §21.18 (real). -Eighteen workstreams (WA–WR, each on its own branch from master 7f13473) were merged into `feedback1` in the order WB, WA, WE, WD, WC, WI, WM, WN, WO, WL, WG, WH, WJ, WK, WP, WR, WQ, WF; data/*.json was rebuilt by `tools/build-data.mjs --offline` after every builder merge, never hand-merged. The integration fixed a bug already in 0.1.0 (a 联防 battle timed out during 隐德来希 S3 reported its 心烛 as leaks, so the server refused an honest client result — candles carry `mem.noLeak`), the last review of the transform workstream (form fx were still dropped by the render engine), every cross-workstream note worth doing with a primary source, and reconciled the bot with the merged rules — §21.19. §21.20 lists the settled decisions and what stays [ASSUMED]. Normative lines rewritten with it: §2 (`grid.js`), §3 (the effective `buildable`, the 深水区, range-bound summons, 攻击距离 vs skill ranges), §5.2 (`liveRangeGrid`, `form`), §5.3 (stealth vs area damage, the 奥术 refresh), §5.4 (`kill` / `death`, `foesInRadius`, `loseHp` vs damage, 静态刚体), §5.5 (healers that block, `rangeAoe`, armed enemies, results), §5.6 (TAKE_DAMAGE, `noRangeExtend` / `showOwnRange`, the profession splash radii), §6.2 (rewardOffer, piece `meta.round`, summons in range, returned equipment), §6.3 (变形同构体), §6.6 (the bot), §7 (bounty drafts, 鸭爵, knock-out forms), §8.2 / §8.3 (fx `form`, `m.ticker`, `range`, UnitInfo `items` / `form`, the stealth bit, rewardOffer), §9 (forms, alias tint), §10 (offers, ticker, 本局禁用), §13 (`spine/enemy`), §14 (ground pathing, boss tickers, the runner's form fx), §16, §17.3, §18.5, §18.6 #10, §19.1, §19.7, §20.1, §20.3, §20.6, §20.9. +Eighteen workstreams (WA–WR, each on its own branch from master 7f13473) were merged into `feedback1` in the order WB, WA, WE, WD, WC, WI, WM, WN, WO, WL, WG, WH, WJ, WK, WP, WR, WQ, WF, then WB's follow-up from 66 screenshots of 22 matches (bounty lists, the 机密商店 and 战术决策 with repeats) after QA; data/*.json was rebuilt by `tools/build-data.mjs --offline` after every builder merge, never hand-merged. The integration fixed a bug already in 0.1.0 (a 联防 battle timed out during 隐德来希 S3 reported its 心烛 as leaks, so the server refused an honest client result — candles carry `mem.noLeak`), the last review of the transform workstream (form fx were still dropped by the render engine), every cross-workstream note worth doing with a primary source, and reconciled the bot with the merged rules — §21.19. §21.20 lists the settled decisions and what stays [ASSUMED]. Normative lines rewritten with it: §2 (`grid.js`), §3 (the effective `buildable`, the 深水区, range-bound summons, 攻击距离 vs skill ranges), §5.2 (`liveRangeGrid`, `form`), §5.3 (stealth vs area damage, the 奥术 refresh), §5.4 (`kill` / `death`, `foesInRadius`, `loseHp` vs damage, 静态刚体), §5.5 (healers that block, `rangeAoe`, armed enemies, results), §5.6 (TAKE_DAMAGE, `noRangeExtend` / `showOwnRange`, the profession splash radii), §6.2 (rewardOffer, piece `meta.round`, summons in range, returned equipment), §6.3 (变形同构体), §6.6 (the bot), §7 (bounty drafts, 鸭爵, knock-out forms), §8.2 / §8.3 (fx `form`, `m.ticker`, `range`, UnitInfo `items` / `form`, the stealth bit, rewardOffer), §9 (forms, alias tint), §10 (offers, ticker, 本局禁用), §13 (`spine/enemy`), §14 (ground pathing, boss tickers, the runner's form fx), §16, §17.3, §18.5, §18.6 #10, §19.1, §19.7, §20.1, §20.3, §20.6, §20.9. ### 21.1 拉普兰德's first refresh; 突变细胞 is not consumed (#1, #4) — `sim/content/garrisons/meta.js SERVER_GAIN_BOND_LAYER_BY_REFRESH_CNT`, `match/PlayerState.js pieceRoundCount / bumpPieceRoundCount / _mergeChess / transformChess`, `match/effectsMeta.js ctx.pieceCounter / incPieceCounter / transform`, `match/builtinMeta.js char_chess_transformation_equip`, `match/bot.js cellTarget / makeHandRoom`, `tools/build-data.mjs ITEM_RULES`, `ui/detailPanel.js ItemDetail` @@ -1129,18 +1129,19 @@ Eighteen workstreams (WA–WR, each on its own branch from master 7f13473) were - [ASSUMED]: an elite merged this round keeps its copies' highest count (no second firing that round); a copy re-bought after a sale fires on its own first refresh ("获得该干员后"; each extra +4 costs 3 + 1 − 1 = 3 funds); the carrier transforms wherever it stands; a 6阶 carrier becomes another 6阶. - Tests: `test/match/feedback1-meta.test.js`, `test/ui/feedback1-cell.test.js`; `items.test.js`, `merge.test.js` updated. -### 21.2 Bounty drafts by the official round structures; special offers shown as what they hold (#2, #6) — `tools/build-data.mjs BOUNTY_INITIAL_SETS / BOUNTY_BOSS_TEMPLATES / BOUNTY_HUNTER_TEMPLATES / BOUNTY_HUNTER`, `match/choices.js bountyDraftCards`, choices.json `bountyDrafts` / `draftPool` / schedule `bountyDraft`, `test/fixtures/official-bounty-drafts.json`; `match/PlayerState.js pushRewardOffer / pushItemOffer`, `match/effectsMeta.js offerLabel`, `ui/gameLogic.js offerHeader`, `ui/shopBar.js RewardCards`, `ui/rewardOverlay.js` +### 21.2 Bounty drafts by the official round structures; special offers shown as what they hold (#2, #6) — `tools/build-data.mjs BOUNTY_INITIAL_SETS / BOUNTY_BOSS_GROUPS / BOUNTY_HUNTER_GROUPS / SHOP_DRAFT / TACTIC_DRAFT`, `match/choices.js bountyDraftCards / shopDraftCards / tacticDraftCards`, choices.json `bountyDrafts` / `shopDraft` / `tacticDraft` / `draftPool` / schedule `bountyDraft`, `test/fixtures/official-bounty-drafts.json`; `match/PlayerState.js pushRewardOffer / pushItemOffer`, `match/effectsMeta.js offerLabel`, `ui/gameLogic.js offerHeader`, `ui/shopBar.js RewardCards`, `ui/rewardOverlay.js` - **#2 seen**: "本来应该后期出的悬赏的怪物在前期的悬赏就出现了,导致选了打不过". **Cause**: every draft drew uniformly from 105 cards (§20.6), so R3 could offer the R9 bosses and the R11 giants. -- **#2 official** (33 screenshots of 11 co-op 绝境 / 终极 matches at R3 / R9 / R11 collected by the user 2026-10-03; readings in the fixture, no player names): every card is an act2autochess (下半) effect whose enemy is the effect's `enemy_id` (the title only names category and tier: 悬赏·损伤I = 底海滑动者 e12_4 / 临时收音师 e18_1 / 心虚设计师 e16_11); a draft holds 6 different cards in varying positions. - - **R3 (11 / 11)**: six 接下来两场作战 cards, I I I II II III (10 coins), one of 10 fixed sets (enemy_initial_1..10); seen: series 18 ×4, 19, 17 and 4 mixed sets of one card from each of 6 of the series 10–15 / 20. - - **R9 (12 / 12)**: boss bounties X·悬赏 + 源石虫·特训, 下场作战 — a group of 0–3 named bosses that always come together, plus cheap fill (W / 碎骨 / 弑君者, 大鲍勃, 庞贝 or 鼠王, 源石虫·特训); 7 groups seen for 6 events (two game versions, or a group set per match — open). - - **R11**: 悬赏决策 5, 机密商店 4, 战术决策 2, 道具补给 0 of 11; a bounty draft = a group (one 特异III giant + 1–4 tier-II cards, always together; matches 1 and 6 share the whole group) filled with tier-I cards, at most one per faction series 10–15; 4 groups seen for 15 events. +- **#2 official** (66 screenshots of 22 co-op 绝境 / 终极 matches of this season at R3 / R9 / R11, collected by the user 2026-10-03; readings in the fixture, no player names): every card is an act2autochess (下半) effect whose enemy is the effect's `enemy_id` (the title only names category and tier: 悬赏·损伤I = 底海滑动者 e12_4 / 临时收音师 e18_1 / 心虚设计师 e16_11); each 悬赏决策 event is a fixed card list and a draft shows 6 different cards of it in varying positions. + - **R3 (22 / 22)**: six 接下来两场作战 cards, I I I II II III (10 coins), one of 10 fixed sets (enemy_initial_1..10), all six shown; 9 sets seen — series 17 / 18 / 19 whole, and hand-made mixed sets (one holds two series-20 cards, one holds 自制投石机 e17_6), so no simple rule describes them. + - **R9 (22 / 22)**: boss bounties X·悬赏 + 源石虫·特训, 下场作战 — one of 6 groups (one per bossInitial event) of 9, 9, 9, 9, 8 and 6 cards; 庞贝 and 鼠王 never share a draft; named bosses do not always come together (match 19 = 自在 + 杰斯顿 + 陷落雪祀, match 12 = 杰斯顿 alone). The 鼠王 group came in 14 of 22 matches, every dark-grey-board match among them. + - **R11**: 悬赏决策 14, 机密商店 4, 战术决策 4, 道具补给 0 of 22. A bounty draft is a list of 7 下场战斗 cards — one 特异III giant, one card per faction series — of which the draft leaves out one (match 15 leaves out the giant; matches 1 / 6 / 21 / 22 leave out four different cards of one list); 7 lists seen. + - **机密商店** (matches 2, 4, 5, 8): six free items with repeats (盟约之币 ×2, 变形同构体 ×2); each shop exactly two tier VI, at least one V and one 盟约之币, no tier I / II. **战术决策** (matches 7, 9, 18, 20): six ally cards each (no 排斥 / 责罚 / 裁决, no 模拟战场演变), 补给 twice in match 7. - Never in a draft: the 7 multi-round cards (the 假想敌 question is answered), enemyeffect_3_*, 战术特训, the 鸭爵 set. -- **#2 now**: cards.bounty `draftPool` initial 42, boss 20, hunter 24 (86 drafted); `draftExcluded` 'unseen' (19: multi-round, e3_*, 凋零骑士 / 遗弃者 / 锏 / 扎罗 / 迷路的巨像). R3 = a seen set, or the mixed rule for the 3 unseen slots; R9 = a seen group + its fill; R11 = a seen group (4 of 15 slots) or a rule group of the same shape, then tier-I fill; 绝境 / 终极 R11 families: bounty 45 / shop 35 / tactic 20 (was supply 50 / shop 50). `MULTI_ROUND_BOUNTY_BATTLES = 2` stays (it now only affects 教鞭's 法术大师A2·多轮战术特训). The mode's inactive enemy list no longer removes bounty cards (PRTS 11/18 note "不影响悬赏决策出场"). Flip: add a newly seen set or group to the build-data constants and rebuild. +- **#2 now**: cards.bounty `draftPool` initial 42, boss 20, hunter 24 (86 drafted); `draftExcluded` 'unseen' (19: multi-round, e3_*, 凋零骑士 / 遗弃者 / 锏 / 扎罗 / 迷路的巨像). A draft = one group, then 6 different cards of it, each drawn with weight 1 + the official drafts of its group it showed in. R3 = one of 10 slots: a seen set, or for the unseen 10th a rule set (tiers I I I II II III, ≤ 2 per series, the III 法术大师A1 e10_6 or 鼎沸 e20_6 — the two-battle cards no draft showed); R9 = a seen group, picked by the matches it came in; R11 = one of the 7 seen lists, uniform (the 4 lists seen with 6 cards completed by the list shape, so 12_8 / 16_2 / 16_6 come in about 1 R11 bounty draft in 15); 绝境 / 终极 R11 families: bounty 14 / shop 4 / tactic 4 (the official counts; was supply 50 / shop 50). The R11 机密商店 (`shopDraft`): six slots drawn with replacement — VI, VI, V, 盟约之币 and twice V / IV / III / 盟约之币 — items weighted by the official cards they showed on; the earlier 标准 / 险境 shops keep any tier I–VI per card, also with replacement. The 战术决策 (`tacticDraft`): every card drawn on its own with replacement; at R11 only the ally cards, weighted 1 + the official cards each showed on; other rounds every card, uniform. Identical cards are separate cards (picks go by index; two picks of a team card stack). `MULTI_ROUND_BOUNTY_BATTLES = 2` stays (it now only affects 教鞭's 法术大师A2·多轮战术特训). The mode's inactive enemy list no longer removes bounty cards (PRTS 11/18 note "不影响悬赏决策出场"). Flip: add a newly seen set, group or list to the build-data constants and rebuild. On the 22 official bounty drafts the generator reaches every one (60 000 seeds per round, `mode_multi_hard` and `mode_multi_abyss`). - **#6 seen**: 凯瑟琳's three items appeared as blank operator cards with raw ids under 晋升奖励. **Now**: a special-refresh offer is drawn as what it holds — free item cards (icon, name, tier, description, FREE) or chess cards under its source's label (凯瑟琳 定向投放, 娜仁图亚 见者有份, 寻呼模块, 信标, 松果) + SPECIAL + 免费选择 1 件 / 名; m.private `shop.rewardOffer = { tier, source: 'merge'|'special', label, queued, slots }`; offers waiting behind the shown one show as "之后还有 N 项" and a +N on the reminder pill; a special offer plays the refresh sound. -- [ASSUMED]: the 3 unseen R3 sets (mixed rule) and 险境 R6 drafting like R3; uniform among the seen R9 groups, unseen bosses not offered; the R11 group / fill split by tier, the 11 unseen R11 slots, uniform among the events; the R11 weights; solo 绝境 / 终极 R11 = the co-op weights (no solo screenshot; the data has 15 solo `bounty_hunter_*_s` events); solo shows 3 of 6. Not changed: 机密商店 and 战术决策 can repeat a card officially; the remake's never do. -- Tests: `test/match/feedback1-bounty.test.js`, `test/ui/feedback1-offers.test.js`, `test/match/playtest6-matchflow.test.js`, `test/ui/playtest6-bounty.test.js`, `test/content/choices.test.js`; opt-in `test/ui/feedback1-offers.e2e.test.js` (`SP_E2E=1`). +- [ASSUMED]: the card weights inside a group; the unseen 10th R3 set (rule) and 险境 R6 drafting like R3; R9 groups picked by the matches they came in (what of the match decides — map, leader or difficulty — is open) and the three single-draft groups completed only with the base cards they lack; R11 = one of the 7 seen lists (which of the 15 events R11 fires is open: by the blocks of effectChoiceInfoDict it would be bounty_hunter_8..15, and with 8 events an unseen list would come in about 1 R11 bounty draft in 8); the R11 family weights = the official counts; the 机密商店 slot split and item weights, and the earlier 标准 / 险境 shops; the 战术决策 weights, R11 without terrain cards, independent draws (open: all 4 official drafts hold a 驰援, a 盟誓 and two of 列装 / 财富 / 补给 / 整备 / 升华), twin battle passives stacking; solo 绝境 / 终极 R11 = the co-op weights (no solo screenshot; the data has 15 solo `bounty_hunter_*_s` events); solo shows 3 of 6. +- Tests: `test/match/feedback1-bounty.test.js`, `test/match/feedback1-secret-shop.test.js`, `test/match/feedback1-tactic.test.js`, `test/ui/feedback1-offers.test.js`, `test/ui/feedback1-secret-shop.test.js`, `test/ui/feedback1-tactic.test.js`, `test/match/playtest6-matchflow.test.js`, `test/ui/playtest6-bounty.test.js`, `test/content/choices.test.js`; opt-in `test/ui/feedback1-offers.e2e.test.js`, `feedback1-secret-shop.e2e.test.js`, `feedback1-tactic.e2e.test.js` (`SP_E2E=1`). ### 21.3 No deployment in the water; tactical points inside the tactician's range (#3, #9) — `sim/grid.js DEPLOY_REFUSED_TILES / canStand`, `tools/build-data.mjs effectiveBuildable / ownerRange`, `match/board.js ownerRangeKeys`, `match/PlayerState.js _legal / summonRange / _liftOutOfRange / _reorient`, `ui/gameLogic.js summonRange`, `match/bot.js`, `match/invariants.js`, `content/kits/tier3.js tacticalPoint` @@ -1323,7 +1324,8 @@ Settled by the user: | Decision | Settled rule | One-line flip | |---|---|---| | A tactician re-oriented in place (§21.3) | a range-bound summon still inside the new range stays; one outside goes back to its stack (user-confirmed 2026-10-03; PRTS only says a MOVED owner resets every summon) | `PlayerState._liftOutOfRange` lifting every range-bound summon of a re-oriented owner | -| Bounty drafts (§21.2) | the official structure of each round from the user's 33 screenshots of 11 matches (R3 fixed sets, R9 boss groups + fill, R11 giant groups + tier-I fill; no multi-round card in a draft) | add a newly seen set / group to `tools/build-data.mjs BOUNTY_INITIAL_SETS / BOUNTY_BOSS_TEMPLATES / BOUNTY_HUNTER_TEMPLATES` and rebuild | +| Bounty drafts (§21.2) | the official structure of each round from the user's 66 screenshots of 22 matches (R3 fixed sets, R9 boss groups, R11 seen 7-card lists; no multi-round card in a draft) | add a newly seen set / group / list to `tools/build-data.mjs BOUNTY_INITIAL_SETS / BOUNTY_BOSS_GROUPS / BOUNTY_HUNTER_GROUPS` and rebuild | +| 机密商店 / 战术决策 repeats (§21.2) | the same card can be offered twice, as officially (the user: "机密商店按官方改成可以重复吧", "战术决策也按官方改成可以重复吧"); R11 机密商店 = two VI, ≥ 1 V, ≥ 1 盟约之币 | `choices.json shopDraft` / `tacticDraft` removed (choices.js falls back to the previous draws, still with replacement) | | Multi-round bounties (§20.6, unchanged) | last two battles — now only 教鞭's card | `server/match/choices.js MULTI_ROUND_BOUNTY_BATTLES = null` | | §20.9's decisions | unchanged (start-deploy summons, 凯瑟琳's hand card, every blocker hits, the collider reach, the elite to the board, the fixed leader pool, the watched bond strip) | as §20.9 | @@ -1331,7 +1333,7 @@ Official since this release (each with its source in its section): 突变细胞 Still [ASSUMED] (each in its section): - §21.1: an elite merged this round keeps its copies' refresh count; a 拉普兰德 re-bought after a sale fires again; a 6阶 突变细胞 carrier becomes another 6阶. -- §21.2: the 3 unseen R3 sets and 险境 R6 drafting like R3; uniform among the seen R9 groups; the R11 group / fill split, the 11 unseen R11 slots and the R11 weights (solo = co-op); solo shows 3 of 6. Open for the user: all six cards of an R11 悬赏决策, an R9 screenshot with the match's 确认本局信息 page and date, solo 绝境 / 终极 R3 / R9 / R11. +- §21.2: the weights inside a group; the unseen 10th R3 set and 险境 R6 drafting like R3; R9 groups by the matches they came in; R11 one of the 7 seen lists and the family weights (solo = co-op); the 机密商店 slots / weights and the earlier shops; the 战术决策 weights, independent draws and twin passives stacking; solo shows 3 of 6. Open for the user: each match's 确认本局信息 page (what decides the R9 group), more R11 悬赏决策 / 机密商店 / 战术决策, solo 绝境 / 终极 R3 / R9 / R11. - §21.3: the range is the loadout grid (items and bonds do not widen it); the canoe in the deploy map only. - §21.4: the translator immobile and damage-cancelled through its change; the 特战术师 form hits flyers (open for the user); the ember's 10 s after the 重生; 隐匿 back at once after a block; the 重生 whitelist; “余音” unmapped. - §21.5: the 鸭爵 swap's 0–2 uniform count and pick, the 60–99 % window, ground only, elites eligible, per-half on pair fields, decided at battle start. @@ -1348,4 +1350,4 @@ Still [ASSUMED] (each in its section): - §21.18: no target cap; damage at the attack instant; the beam look. - §21.19: the 奥术法阵 rider ending with its carriers; the 自行炮's immunity window = its bombardment. -Not done (noted, no primary source or out of scope): whether 华法琳 S2's 流失 can kill an ally (§21.17); 伊利昂的木驮兽's `Full` skin (§21.14); the render-demo recording `public/dev/recordings/normal-a1m04.json` still shows 战场#04's old L-shaped lower route (display only); 机密商店 / 战术决策 repeating a card as officially (§21.2). +Not done (noted, no primary source or out of scope): whether 华法琳 S2's 流失 can kill an ally (§21.17); 伊利昂的木驮兽's `Full` skin (§21.14); the render-demo recording `public/dev/recordings/normal-a1m04.json` still shows 战场#04's old L-shaped lower route (display only). diff --git a/docs/META.md b/docs/META.md index 331ba86b..3483d2c0 100644 --- a/docs/META.md +++ b/docs/META.md @@ -107,24 +107,51 @@ untimed. The UI picks a card with two taps (select → 确认选择, DESIGN §18 the mode's static `inactiveBondIds` — 标准 has no 拉特兰 / 阿戈尔 / 卡西米尔 / 奥术 … — and with chess in the pool), so 玛恩纳的盟誓 / 莫斯提马的盟誓 / 卡西米尔驰援 never show up in 标准. Card generation and the family defaults are documented in `choices.js` (bounty / supply / shop / tactic). 机密商店 cards are **free** (official -text "无需消耗资金"). 悬赏决策 offers only choices.json cards with `draft: true` (`choices.js draftBounty`): never 战术特训 (PRTS +text "无需消耗资金") and follow the 4 official 机密商店 (choices.json `shopDraft`, build-data `SHOP_DRAFT`; the user: +"机密商店按官方改成可以重复吧"): six slots drawn with replacement — VI, VI, V, 盟约之币 and twice V / IV / III / 盟约之币, +an item within its tier weighted by the official cards it showed on — so the same item can be offered twice (official: +盟约之币 ×2, 变形同构体 ×2; the slot split and the weights [ASSUMED]) — at R11 (绝境 / 终极), the round of the +screenshots; the earlier 机密商店 of 标准 / 险境 (no screenshot) keep the previous draw, any tier I–VI per card with +replacement [ASSUMED]; two identical cards are two cards (picks go by index). 战术决策 follows the 4 official 战术决策 +(choices.json `tacticDraft`, build-data `TACTIC_DRAFT`, `choices.js tacticDraftCards`; the user: "战术决策也按官方改成可以 +重复吧"): each card drawn on its own, with replacement, so the same card can be offered twice (official match 7 R11: +补给 ×2) — at R11 (绝境 / 终极) only the ally cards (the 24 official cards hold no 排斥 / 责罚 / 裁决 and no terrain card), +each weighted 1 + the official cards it showed on (列装 / 财富 / 补给 / 整备 / 升华 made half of them) [ASSUMED: the +weights]; the earlier 战术决策 of 标准 / 险境 (no screenshot) keep every card, uniform, terrain cards only for the match +stage, with replacement too [ASSUMED]. At R11 the cards are drawn independently rather than in slots like the 机密商店 +[ASSUMED, open: all 4 drafts hold a 驰援, a 盟誓 and two of 列装 / 财富 / 补给 / 整备 / 升华 — about 3 % under +independent draws, but a pattern spotted after the fact]. Identical tactic cards are separate cards as well: each pick +applies its own card once, and two picks of one team card (two players taking the twins) both reach every teammate and +add up — settled for the prep cards (补给 "可叠加"; 列装 / 财富 / 盟誓 grant their own items, coin and layers each time), +[ASSUMED] for the battle passives 自愈 / 火力 / 征召 / 无瑕 / 锐利: one buff per pick, so 锐利 ×2 ignores 60 % of the DEF +(open: whether the official keeps one instance of a 同名 env buff; twin passives come in about 4–5 % of R11 drafts). +The header reads the official "进行协同调整,做好迎战准备。". 悬赏决策 offers only choices.json cards with `draft: true` (`choices.js draftBounty`): never 战术特训 (PRTS "※以下悬赏任务仅由法术教鞭生成") nor the 鸭爵 / 高普尼克 / 流泪小子 / 圆仔 cards (user playtest #6 item 4). **Each draft is built like the official one of its round** (`choices.js bountyDraftCards`, choices.json `bountyDrafts` / schedule -`bountyDraft`; player feedback after 0.1.0, report #2 — late bounty enemies in the early drafts — settled by 33 -screenshots of 11 official co-op 绝境 / 终极 matches, readings in `test/fixtures/official-bounty-drafts.json`): **R3** -one of the 10 official sets of six "接下来两场作战" cards, 3 × I + 2 × II + 1 × III — 7 seen (a whole series 17 / 18 / 19, -or one card from each of 6 of the series 10–15 / 20), the 3 unseen slots built by that rule [ASSUMED]; **R9** boss -bounties + 源石虫·特训: a seen group of 0–3 named bosses that always come together, filled to 6 with the cheap ones (W / -碎骨 / 弑君者, 大鲍勃, 庞贝 or 鼠王, 源石虫·特训) — 7 groups for 6 events: two game versions or a group set per match -(leader, map), open; **R11** (绝境 / 终极 co-op: 悬赏决策, 机密商店 or 战术决策, never 道具补给; solo the same weights -[ASSUMED]) six "下场战斗" cards like R9: a group — one 特异III giant + 1–4 tier-II cards, always together (matches 1 and 6 -share the whole group, only the tier-I card differs) — filled to 6 with tier-I cards, at most one per faction series; -4 groups seen for the 15 events, the unseen slots draw a group of that shape [ASSUMED]. 险境 R6 drafts like R3 +`bountyDraft`; player feedback after 0.1.0, report #2 — late bounty enemies in the early drafts — settled by 66 +screenshots of 22 official co-op 绝境 / 终极 matches of this season, readings in +`test/fixtures/official-bounty-drafts.json`): the event is a fixed card list and the draft shows 6 different cards of +it, each drawn with weight 1 + the official drafts of its group it showed in [ASSUMED]. **R3** one of the 10 official +sets of six "接下来两场作战" cards (all six), 3 × I + 2 × II + 1 × III in 22 of 22 — 9 seen, hand-made (one holds two +series-20 cards), the 10th built by a rule whose III is 法术大师A1 or 鼎沸 (the two-battle cards no draft showed) +[ASSUMED]; **R9** boss bounties + 源石虫·特训: one of 6 groups (one per bossInitial event; 庞贝 and 鼠王 never +together) of 9, 9, 9, 9, 8 and 6 cards — 9 where three named bosses came, the single-draft groups completed only with +the base cards they lack [ASSUMED; match 4's base-only group may instead be a draft of the 泥岩 group]; the 鼠王 group (杰斯顿 / “自在” / 陷落雪祀) came in 14 of 22 matches, every match on the dark grey board +among them, so a group is picked by the matches it came in [ASSUMED: something of the match — map, leader or +difficulty — decides, open]; **R11** (绝境 / 终极 co-op: 悬赏决策 14, 机密商店 4, 战术决策 4, never 道具补给, weights = +those counts; solo the same [ASSUMED]) a list of 7 "下场战斗" cards — one 特异III giant, one card per faction series — +of which the draft leaves out one (matches 1 / 6 / 21 / 22 leave out four different cards of one list); one of the 7 +lists seen, uniform, so no list is invented [ASSUMED] (the data does not say which of the 15 events bounty_hunter_* +R11 fires: by its blocks it would be the 8 events 8..15, beside the 绝境 / 终极-only hardbuff_select; 7, 8 or 9 events +fit 14 drafts showing 7 lists about equally, 15 do not — with 8, an unseen list would come in about 1 R11 bounty draft +in 8, open), the 4 lists seen with 6 cards completed by that shape — so the R11 cards no draft showed (12_8 / 16_2 / +16_6) come in about 1 draft in 15 [ASSUMED]. 险境 R6 drafts like R3 [ASSUMED]. A card's enemy is fixed by its effect (`enemy_id`): the title only names category and tier (悬赏·损伤I = -底海滑动者 or 临时收音师). +底海滑动者 or 临时收音师). The players pick in turn from one shared draft (a taken card stays greyed with the taker's +avatar, as in the official matches 17 and 21). No official draft showed a multi-round card, a pre-series card (enemyeffect_3_*) or the boss bounties 凋零骑士 / “遗弃者” / 锏 / 扎罗 / 迷路的巨像: `draftExcluded: 'unseen'` [ASSUMED], flipped by adding them to build-data -`BOUNTY_INITIAL_SETS` / `BOUNTY_BOSS_TEMPLATES` / `BOUNTY_HUNTER_TEMPLATES` once a screenshot shows one. The card positions are shuffled; solo +`BOUNTY_INITIAL_SETS` / `BOUNTY_BOSS_GROUPS` / `BOUNTY_HUNTER_GROUPS` once a screenshot shows one. The card positions are shuffled; solo shows 3 of the 6 [ASSUMED]. The mode's inactive enemy list does not thin the draft (PRTS 11/18 note "不影响悬赏决策出场"). Every bounty card carries the effect's official rich text `descRaw` (the battles in blue "下场作战" / "两场作战"; the overlay and the effects column render it; the effects column also says "还剩 N 场作战"). diff --git a/docs/PLAYING.md b/docs/PLAYING.md index d2d01852..621a0855 100644 --- a/docs/PLAYING.md +++ b/docs/PLAYING.md @@ -16,7 +16,7 @@ |---|---| | 确认本局信息 | 本局地图(标准模拟固定为「战场#01」;险境从 8 张地图中随机,绝境 / 终极从不含战场#01 的 7 张中随机)、敌方派系、**被禁用的盟约及其干员**、领袖预告。所有人确认后继续;同盟模拟最多 25 秒;只有你一名玩家时(独立模拟,或同盟模拟只带 AI 队友)不限时。 | | 选择策略 | 40 名策略(分队长)决定**初始目标生命值(20–45)**和一条永久规则。同盟:随机顺序轮流选,**每人 30 秒**,右上角和「决策中」显示同一个倒计时;AI 队友立即选完;队友已选的不能重复,每人可**跳过一次**(排到最后);超时自动选你**当前选中**的策略(已被队友选走则选华法琳)。独立:自由选择、不限时;同盟模拟只有你一名玩家时也不限时。 | -| 机变 | 部分回合开始前出现:同盟共 6 张卡轮流各取 1 张(首位 30 秒,其余 16 秒;只有你一名玩家时不限时),独立 3 选 1。卡片包括装备、资金、干员、盟约层数、悬赏等;**悬赏决策**为你的作战添加悬赏敌人,卡上用蓝字标出持续多久:「下场作战」/「接下来两场作战」的只出现一场或两场,之后不再出现;官方的「多轮悬赏」(原文写「之后的每场作战」)在这里也按「接下来两场作战」处理,只出现两场(如教鞭的法术大师A2·多轮战术特训)。各回合的悬赏决策按官方对局截图来出:第 3 回合是 6 张「接下来两场作战」的悬赏(3 张 1 资金、2 张 2 资金、1 张 3 资金);第 9 回合是各首领的「下场作战」悬赏和「源石虫·特训」;绝境 / 终极的第 11 回合是悬赏决策、机密商店或战术决策之一,其中的悬赏是 1 只特异巨兽加 5 张「下场战斗」悬赏。击倒它的人(联防中的队友也算)获得资金;右侧效果栏会写「还剩 N 场作战」。每张卡左上是图标和名称,下面写着完整效果(与详情卡相同的官方描述,手机上也显示);已被选走的卡变暗,右上角显示选走它的玩家头像(悬停可看名字)。选卡要**点两次**:第一次只选中(金框 +「确认选择 · 再次点击」),再点同一张或点右上的「确认选择」才生效;点别的卡换选,按 Esc 或点空白处取消。 | +| 机变 | 部分回合开始前出现:同盟共 6 张卡轮流各取 1 张(首位 30 秒,其余 16 秒;只有你一名玩家时不限时),独立 3 选 1。卡片包括装备、资金、干员、盟约层数、悬赏等;**悬赏决策**为你的作战添加悬赏敌人,卡上用蓝字标出持续多久:「下场作战」/「接下来两场作战」的只出现一场或两场,之后不再出现;官方的「多轮悬赏」(原文写「之后的每场作战」)在这里也按「接下来两场作战」处理,只出现两场(如教鞭的法术大师A2·多轮战术特训)。各回合的悬赏决策按官方对局截图来出:第 3 回合是 6 张「接下来两场作战」的悬赏(3 张 1 资金、2 张 2 资金、1 张 3 资金);第 9 回合是各首领的「下场作战」悬赏和「源石虫·特训」;绝境 / 终极的第 11 回合多半是悬赏决策(也可能是机密商店或战术决策),其中的悬赏通常有 1 只特异巨兽,其余是各阵营的「下场战斗」悬赏。击倒悬赏敌人的人(联防中的队友也算)获得资金;右侧效果栏会写「还剩 N 场作战」。**机密商店**的 6 件装备都免费,和官方一样可能出现两件相同的装备(各算一张卡,可以分别被选走);第 11 回合(绝境 / 终极)的机密商店按官方:2 件 VI 阶、至少 1 件 V 阶和 1 枚盟约之币,标准 / 险境较早回合的机密商店各阶装备都可能出现。**战术决策**也和官方一样可能出现两张相同的卡(官方截图里出现过两张「补给」;各算一张卡,可以分别被选走,每张只生效一次,两人各选一张全队卡则效果叠加);第 11 回合(绝境 / 终极)的战术决策按官方截图只出盟誓、驰援、列装 / 财富 / 补给 / 整备 / 升华等增益卡,不出削弱敌人的卡和战场演变卡。每张卡左上是图标和名称,下面写着完整效果(与详情卡相同的官方描述,手机上也显示);已被选走的卡变暗,右上角显示选走它的玩家头像(悬停可看名字)。选卡要**点两次**:第一次只选中(金框 +「确认选择 · 再次点击」),再点同一张或点右上的「确认选择」才生效;点别的卡换选,按 Esc 或点空白处取消。 | | 休整期 | 购买、摆阵、配装备、冻结 / 刷新、升级调度中心;同盟有倒计时(65–215 秒,随回合增加);独立模拟、以及只有你一名玩家(只带 AI 队友)的同盟模拟不限时。所有人「准备就绪」即提前开战,全员就绪前可取消。 | | 作战 | 每人在自己的战场各自作战(战斗在你的浏览器里模拟,2 倍速)。干员按**从上到下、从左到右**的顺序自动部署并消耗部署费用(初始 10,+1/秒)。时限 45–115 秒(实际秒数,即屏幕上的倒计时),时间到仍存活的敌人算漏怪。有敌人进入蓝门时,顶栏的目标生命值会**立即**显示扣除后的数值(红字 + 「−N」,每回合至多 10 点),结算时确定;联防阶段标注「联防中」,队友拦下的部分最后不扣。左侧队伍栏同样显示队友的待扣生命值。被击倒的干员**留在原地**(倒地姿势、略微变灰),头上的圆圈是再部署倒计时:绿色圆环 + 秒数;变成黄色「DP」表示部署费用不够,红色「!」表示原位被占。血条下方的一行是**元素损伤**(与原版一致:元素图标 + 白条):干员为带图标的彩色圆盘,敌人为小号纯色圆盘,右侧白条是剩余元素值,像血条一样从右往左减少,白条耗尽的那一下就是爆条(被大额元素损伤一次打掉一截时白条也会一次少一截,例如掠海漂移体每击约为 25%–50%);爆条后进入爆发冷却(灼燃 / 神经 / 侵蚀 10 秒,敌方侵蚀 8 秒,凋亡 15 秒),这时白条变成**元素颜色**(神经青绿、侵蚀蓝、灼燃橙红、凋亡灰紫)并在冷却期间慢慢回满、图标闪烁——彩色条表示已经爆条、正在承受爆发效果,不是还剩的元素值;期间所有元素都不会累积也无法被治疗,结束后清零。元素爆发造成的是**无来源伤害**,不吃干员的增伤、穿透和装备加成(例如深巡打海嗣时灼燃爆发固定 7000),击杀仍记在爆条的干员名下;元素脆弱只提高元素伤害,不加快元素条;脆弱不影响元素伤害。已被击杀的敌人不会再被附加元素损伤。 | | 联防 | 见第 5 节。 | diff --git a/public/dev/game-mock.html b/public/dev/game-mock.html index 4af18f5e..4fcdd077 100644 --- a/public/dev/game-mock.html +++ b/public/dev/game-mock.html @@ -4,7 +4,7 @@ fabricated m.public / m.private / m.field / b.snap / b.ev streams and a tiny mock server behind net.request, so every phase can be developed and screenshot without the game server. URL params: ?phase=PREP|INFO_CHECK|BAND_DRAFT|BATTLE_CHECK|SP_DRAFT|COMBAT|UNITE|SETTLE|FINAL_ASSAULT|HIDDEN_CORE|RESULT - &variant=reward|bounty|supply|tactic|temp|frozen|dead|defeat|solo|popup|detail|drawer|info|pen|emote|settings|collapsed|bond|drag + &variant=reward|bounty|supply|shop|tactic|temp|frozen|dead|defeat|solo|popup|detail|drawer|info|pen|emote|settings|collapsed|bond|drag |leaker (联防: you let enemies through — the ×N counter) |overtime|drain (boss rounds: level time over / overtime drain) |paused (solo battles) &shot=1 (hide the switcher) &render=engine|fallback (default: the Pixi engine, DOM fallback if it fails) diff --git a/public/dev/game-mock.js b/public/dev/game-mock.js index 8b9b492f..293ef97b 100644 --- a/public/dev/game-mock.js +++ b/public/dev/game-mock.js @@ -282,11 +282,14 @@ function setPhase(phase, variant) { break; case PHASE.SP_DRAFT: { pub.round = 9; pub.deadline = Date.now() + 14000; - const fam = VARIANTS.has('supply') ? 'supply' : VARIANTS.has('tactic') ? 'tactic' : 'bounty'; + const fam = VARIANTS.has('supply') ? 'supply' : VARIANTS.has('shop') ? 'shop' : VARIANTS.has('tactic') ? 'tactic' : 'bounty'; const ch = data.get('choices'); let cards; if (fam === 'supply') cards = shuffle(shopItems().filter((i) => i.tier >= 3)).slice(0, 6).map((i) => ({ itemId: i.id })); - else if (fam === 'tactic') cards = shuffle(ch.cards.tactic.filter((t) => t.kind !== 'terrain')).slice(0, 6).map((t) => ({ effectId: t.effectId })); + // the official 机密商店 of match 8 R11 (test/fixtures/official-bounty-drafts.json): the same item twice + else if (fam === 'shop') cards = ['变形同构体', '盟约之币', '商业包装方案', '变形同构体', '天马之盔', '双模机械臂'].map((n) => ({ itemId: shopItems().find((i) => i.name === n).id })); + // the official 战术决策 of match 7 R11 (test/fixtures/official-bounty-drafts.json): the same card twice + else if (fam === 'tactic') cards = ['补给', '补给', '谢拉格驰援', '列装', '莫斯提马的盟誓', '升华'].map((n) => ({ effectId: ch.cards.tactic.find((t) => t.name === n).effectId })); else cards = shuffle(ch.cards.bounty.filter((b) => b.draft !== false)).slice(0, 6).map((b) => ({ effectId: b.effectId })); if (solo) { cards = cards.slice(0, 3); pub.deadline = 0; } pub.sp = { family: fam, cards, order: solo ? ['p1'] : ['p4', 'p1', 'ai_2', 'p3'], turn: solo ? 'p1' : 'p1', picks: solo ? {} : { p4: 2 }, untimed: solo }; @@ -698,7 +701,7 @@ const SWITCH = [ ['BATTLE_CHECK', PHASE.BATTLE_CHECK, ''], ['PREP', PHASE.PREP, ''], ['PREP + reward', PHASE.PREP, 'reward'], ['PREP + temp', PHASE.PREP, 'temp'], ['PREP frozen', PHASE.PREP, 'frozen'], ['PREP dead', PHASE.PREP, 'dead'], ['PREP boss (L)', PHASE.PREP, 'boss'], ['PREP boss (R)', PHASE.PREP, 'bossR'], - ['SP bounty', PHASE.SP_DRAFT, 'bounty'], ['SP supply', PHASE.SP_DRAFT, 'supply'], ['SP tactic', PHASE.SP_DRAFT, 'tactic'], ['SP solo', PHASE.SP_DRAFT, 'solo'], + ['SP bounty', PHASE.SP_DRAFT, 'bounty'], ['SP supply', PHASE.SP_DRAFT, 'supply'], ['SP shop', PHASE.SP_DRAFT, 'shop'], ['SP tactic', PHASE.SP_DRAFT, 'tactic'], ['SP solo', PHASE.SP_DRAFT, 'solo'], ['COMBAT', PHASE.COMBAT, ''], ['COMBAT done', PHASE.COMBAT, 'done'], ['UNITE', PHASE.UNITE, ''], ['UNITE leaker', PHASE.UNITE, 'leaker'], ['SETTLE', PHASE.SETTLE, ''], ['FINAL_ASSAULT', PHASE.FINAL_ASSAULT, ''], ['FA overtime soon', PHASE.FINAL_ASSAULT, 'overtime'], ['FA draining', PHASE.FINAL_ASSAULT, 'drain'], ['HIDDEN_CORE', PHASE.HIDDEN_CORE, ''], ['COMBAT solo (pause)', PHASE.COMBAT, 'solo'], ['FA solo paused', PHASE.FINAL_ASSAULT, 'solo,paused'], diff --git a/server/match/choices.js b/server/match/choices.js index a4817c02..1491e22b 100644 --- a/server/match/choices.js +++ b/server/match/choices.js @@ -5,15 +5,18 @@ // count is `cards` (co-op 6, solo 3): // bounty 悬赏决策 six distinct cards.bounty entries (solo: 3 of them) built like the official draft of the round // (`bountyDraftCards`; player feedback after 0.1.0, report #2 — late bounty enemies in the early -// drafts; 33 official screenshots, tools/build-data.mjs BOUNTY_INITIAL_SETS): schedule `bountyDraft` -// names the kind and choices.json `bountyDrafts[kind]` its structure — -// initial (R3, 险境 R6 [ASSUMED]): one of the 10 official sets of "接下来两场作战" cards — a seen -// set, or for an unseen slot one card from each of 6 of the series 10–15 / 20 with the -// tiers I I I II II III; -// boss (R9): a seen group of named bosses + the group's cheap boss bounties / 源石虫·特训 to 6; -// hunter (R11): one of the 15 official events — a seen group (a 特异III giant + its tier-II -// "下场战斗" cards, always together) or for an unseen slot a group of that shape -// [ASSUMED] — filled to 6 with tier-I cards, at most one card per faction series; +// drafts; 66 official screenshots of 22 matches, tools/build-data.mjs BOUNTY_INITIAL_SETS): schedule +// `bountyDraft` names the kind and choices.json `bountyDrafts[kind]` its card lists — the event is a +// fixed list and the draft shows 6 different cards of it, each drawn with its weight (1 + the +// official drafts of the group it showed in): +// initial (R3, 险境 R6 [ASSUMED]): one of the 10 official sets of six "接下来两场作战" cards (all +// six) — 9 seen, the 10th built by `rule` (I I I II II III) [ASSUMED]; +// boss (R9): one of the 6 groups (9, 9, 9, 9, 8 and 6 cards) of boss bounties / 源石虫·特训, +// picked by the matches it came in [ASSUMED]; +// hunter (R11): one of the 7 seen lists of 7 "下场战斗" cards, uniform, so no list is invented +// [ASSUMED: which of the 15 bounty_hunter events R11 fires is open — by the data's blocks +// 8..15]; a list seen with 6 cards gets its 7th (`open`) by `rule` +// (one 特异III giant, else a tier I / II card of a free faction series) [ASSUMED]; // only `draft` cards of that `draftPool` (never 战术特训 — 法术教鞭 only —, the 鸭爵 set, the 7 // multi-round cards or the pre-series cards: no official draft shows them); positions shuffled; the // mode's inactive enemy list does not apply (PRTS 卫戍协议:盟约 11/18 note "以上调整仅针对战术特训敌人, @@ -22,13 +25,26 @@ // MULTI_ROUND_BOUNTY_BATTLES battles and says so (`bountyBattles` / `bountyText`: the user's call // after playtest #6 — "我不记得有过多轮悬赏") // supply 道具补给 random normal EQUIP shop items with tier in supplyTiers [lo, hi] (duplicates allowed) -// shop 机密商店 random normal EQUIP shop items of any tier I–VI (duplicates allowed); FREE — the official card -// text is "无需消耗资金,获得装备补给" (research 01 A4/04 addendum), so the price is 0 -// tactic 战术决策 distinct cards.tactic entries; terrain cards only for the match stage; a 驰援 card -// (single_special_choice_gain_bond_chess) or a 盟誓 card (global_special_choice_bond_addlayer) -// only while at least one of its bonds is live in this match (opts.bondAvailable = Match.bondLive: -// not in the mode's static inactive list — 标准 turns off 拉特兰 / 阿戈尔 / 卡西米尔 / 奥术 … — -// and still with chess in the pool); a card acting only on dead bonds would do nothing +// shop 机密商店 at the rounds of choices.json `shopDraft` (R11: the 4 official 机密商店; the user: "机密商店按官方改 +// 成可以重复吧"): six slots, each drawn on its own — with replacement, so the same item can be +// offered twice (official: 盟约之币 ×2, 变形同构体 ×2): VI, VI, V, 盟约之币 and twice V / IV / III / +// 盟约之币, an item within its tier by `itemWeights` (solo: 3 of the 6 slots [ASSUMED]); other rounds +// (标准 / 险境, no screenshot) and without `shopDraft`: random normal EQUIP shop items of any tier I–VI, +// each card on its own (duplicates allowed) [ASSUMED]. FREE — the official card text is "无需消耗资金,获得装备 +// 补给" (research 01 A4/04 addendum), so the price is 0. Two identical cards are two cards: picks, +// `taken` and the client go by the card's `idx` +// tactic 战术决策 cards.tactic entries, each card drawn on its own — with replacement, so the same card can be +// offered twice (the 4 official 战术决策, R11 of matches 7 / 9 / 18 / 20: 补给 ×2 in match 7; the +// user: "战术决策也按官方改成可以重复吧"; `tacticDraftCards`): at the rounds of choices.json +// `tacticDraft` (R11) only its `kinds` (the ally cards — the official 24 cards hold no debuff and +// no terrain card), a card by `weights` (1 + the official cards it showed on) [ASSUMED: the +// weights]; other rounds (标准 / 险境, no screenshot) every card uniform, terrain cards only for +// the match stage [ASSUMED]; a 驰援 card (single_special_choice_gain_bond_chess) or a 盟誓 card +// (global_special_choice_bond_addlayer) only while at least one of its bonds is live in this match +// (opts.bondAvailable = Match.bondLive: not in the mode's static inactive list — 标准 turns off +// 拉特兰 / 阿戈尔 / 卡西米尔 / 奥术 … — and still with chess in the pool); a card acting only on dead +// bonds would do nothing. Two identical cards are two cards: picks, `taken` and the client go by +// the card's `idx`, and each pick applies its own card once (two picks of one team card stack) // Application (applyCard): a registered `choice:` handler (content) wins; otherwise the family default: // bounty → the picker's bounty list (waves.js adds the enemies to the next `rounds` battles; kill payout to the // killer via the Battle, perfect payout at settlement when the picker's own battle was perfect) @@ -185,76 +201,108 @@ export function bountyCard(gd, c) { }; } -/** Up to `k` cards of `list` not in `taken`, at most one per series of `onePer` (a Set), in a shuffled order. */ -function drawDistinct(rng, list, k, taken, onePer = null) { +/** Up to `k` cards of `list` not in `taken`, in a shuffled order. */ +function drawDistinct(rng, list, k, taken) { const out = []; - const used = new Set([...taken].map((c) => c.series)); for (const c of rng.shuffle(list.slice())) { if (out.length >= k) break; if (taken.has(c)) continue; - if (onePer && onePer.has(c.series) && used.has(c.series)) continue; out.push(c); taken.add(c); - used.add(c.series); + } + return out; +} + +/** `k` different entries of `list` drawn one by one with weights `weights` (missing / bad weights count 1). */ +function drawWeighted(rng, list, weights, k) { + const pool = list.map((c, i) => [c, Math.max(0, Number(weights && weights[i]) || 1)]); + const out = []; + while (out.length < k && pool.length) { + const c = weightedPick(rng, pool); + out.push(c); + pool.splice(pool.findIndex(([x]) => x === c), 1); } return out; } /** - * The cards of a 悬赏决策 of kind `kind` after its official structure (choices.json `bountyDrafts[kind]`, see the module + * The cards of an unseen R3 set (`spec.rule`, [ASSUMED]): one card per tier of `tiers` from the two-battle cards of + * `series`, at most `perSeries` of one series; a tier the `prefer` cards have is filled first, by one of them. + */ +function initialRuleSet(rng, rule, all) { + const out = []; + const perSeries = Number.isInteger(rule.perSeries) ? rule.perSeries : 1; + const ofSeries = (s) => out.filter((c) => c.series === s).length; + const prefer = new Set(Array.isArray(rule.prefer) ? rule.prefer : []); + const series = new Set(Array.isArray(rule.series) ? rule.series : []); + // the tiers a preferred card has go first, so that it still fits its series + const prefTiers = new Set(all.filter((c) => prefer.has(c.effectId)).map((c) => c.tier)); + const tiers = rng.shuffle((Array.isArray(rule.tiers) ? rule.tiers : []).slice()); + for (const tier of [...tiers.filter((t) => prefTiers.has(t)), ...tiers.filter((t) => !prefTiers.has(t))]) { + const ok = (c) => !out.includes(c) && c.tier === tier && series.has(c.series) && ofSeries(c.series) < perSeries; + const pref = all.filter((c) => prefer.has(c.effectId) && ok(c)); + const c = rng.pick(pref.length ? pref : all.filter(ok)); + if (c) out.push(c); + } + return out; +} + +/** + * Fill an R11 list up to `rule.size` (an unseen event: from nothing; a seen group: its `open` cards) [ASSUMED]: a list + * without a 特异III giant gets one, the rest are tier I / II cards, at most one per `onePerSeries` series and + * `maxSeries16` of series 16. + */ +function hunterFill(rng, rule, list, byId) { + const out = list.slice(); + const size = Number.isInteger(rule.size) ? rule.size : 7; + const giants = (Array.isArray(rule.giants) ? rule.giants : []).map((id) => byId.get(id)).filter(Boolean); + const onePer = new Set(Array.isArray(rule.onePerSeries) ? rule.onePerSeries : []); + const max16 = Number.isInteger(rule.maxSeries16) ? rule.maxSeries16 : 2; + if (out.length < size && !out.some((c) => giants.includes(c))) { const g = rng.pick(giants.filter((c) => !out.includes(c))); if (g) out.push(g); } + const fits = (c) => !out.includes(c) && (onePer.has(c.series) ? !out.some((x) => x.series === c.series) : c.series !== 16 || out.filter((x) => x.series === 16 && !giants.includes(x)).length < max16); + for (const c of rng.shuffle((Array.isArray(rule.cards) ? rule.cards : []).map((id) => byId.get(id)).filter(Boolean))) { + if (out.length >= size) break; + if (fits(c)) out.push(c); + } + return out; +} + +/** + * The cards of a 悬赏决策 of kind `kind` after its official card lists (choices.json `bountyDrafts[kind]`, see the module * header), over the eligible cards `byId` (effectId → cards.bounty entry). Ids the eligible list lacks are skipped. + * pick 'slot': one of `slots` events, uniform — a seen group, or for an unseen event a list built by `rule` (R3's + * 10th set; R11 has `slots` = its 7 seen lists, so none is built); + * pick 'seen': a group by the number of official matches it came in. + * The draft is `count` different cards of the list drawn by the group's `weights` (a rule-built card weighs 1). */ function structuredBounty(rng, kind, spec, byId) { - const get = (ids) => (Array.isArray(ids) ? ids : []).map((id) => byId.get(id)).filter(Boolean); - const taken = new Set(); const count = Number.isInteger(spec.count) ? spec.count : 6; - if (kind === 'initial') { - const sets = Array.isArray(spec.sets) ? spec.sets : []; - const slot = rng.int(Math.max(sets.length, Number.isInteger(spec.slots) ? spec.slots : 0)); - if (slot < sets.length) return get(sets[slot].cards).slice(0, count); - // an unseen official set: one card from each of `count` series, with the seen sets' tier mix - const mx = spec.mixed || {}; - const series = rng.shuffle((mx.series || []).slice()).slice(0, mx.count || count); - const tiers = rng.shuffle((mx.tiers || []).slice()); - const all = [...byId.values()]; - const out = []; - series.forEach((s, i) => { - const ofSeries = all.filter((c) => c.series === s); - const want = ofSeries.filter((c) => c.tier === tiers[i]); - const c = rng.pick(want.length ? want : ofSeries); - if (c) out.push(c); - }); - return out; - } - if (kind === 'boss') { - const t = rng.pick(Array.isArray(spec.templates) ? spec.templates : []); - if (!t) return []; - const featured = get(t.featured); - featured.forEach((c) => taken.add(c)); - return [...featured, ...drawDistinct(rng, get(t.fill), count - featured.length, taken)].slice(0, count); - } - if (kind === 'hunter') { - // one of the official events: a seen group, or for an unseen slot a group of the same shape; then tier-I fill to 6 - const onePer = new Set(Array.isArray(spec.onePerSeries) ? spec.onePerSeries : []); - const templates = Array.isArray(spec.templates) ? spec.templates : []; - const slots = Math.max(templates.length, Number.isInteger(spec.slots) ? spec.slots : 0); + const groups = Array.isArray(spec.groups) ? spec.groups : []; + let group = null; + if (spec.pick === 'seen') { + group = weightedPick(rng, groups.map((g) => [g, (Array.isArray(g.seen) ? g.seen.filter((x) => Number.isInteger(x)).length : 0) || 1])); + } else { + const slots = Math.max(groups.length, Number.isInteger(spec.slots) ? spec.slots : 0); const slot = slots > 0 ? rng.int(slots) : 0; - let group; - let fill; - if (slot < templates.length) { - group = get(templates[slot].featured); - group.forEach((c) => taken.add(c)); - fill = get(templates[slot].fill); - } else { - const r = spec.rule || {}; - const sizes = Array.isArray(r.groupSizes) && r.groupSizes.length ? r.groupSizes : [1]; - const giant = drawDistinct(rng, get(r.giants), 1, taken); - group = [...giant, ...drawDistinct(rng, get(r.groupCards), rng.pick(sizes), taken, onePer)]; - fill = get(r.fill); - } - return [...group, ...drawDistinct(rng, fill, count - group.length, taken, onePer)]; + group = slot < groups.length ? groups[slot] : null; } - return []; + const rule = spec.rule || {}; + let list; + let weights; + if (group) { + const ids = Array.isArray(group.cards) ? group.cards : []; + list = []; + weights = []; + ids.forEach((id, i) => { const c = byId.get(id); if (c) { list.push(c); weights.push(Array.isArray(group.weights) ? group.weights[i] : 1); } }); + if (kind === 'hunter' && Number(group.open) > 0) list = hunterFill(rng, { ...rule, size: list.length + Number(group.open) }, list, byId); + } else if (kind === 'initial') { + list = initialRuleSet(rng, rule, [...byId.values()]); + } else if (kind === 'hunter') { + list = hunterFill(rng, rule, [], byId); + } else { + list = []; + } + return drawWeighted(rng, list, weights, count); } /** @@ -274,9 +322,72 @@ function bountyDraftCards(gd, rng, n, sch, round) { return rng.shuffle(out).slice(0, n).map((c) => bountyCard(gd, c)); } +/** + * The 机密商店 cards (choices.json `shopDraft`, module header): every slot drawn on its own — a tier (or `coin`, the + * 盟约之币) by the slot's weights, then an item of that tier by `itemWeights` (1 when unlisted; an empty tier falls back to + * the nearest lower one, then any) — so one item can fill two slots. Positions shuffled; `n` < the slots (solo) keeps + * `n` of them. Null without a usable `shopDraft` or at a round its `rounds` (when given) does not list. + */ +export function shopDraftCards(gd, rng, n, round = null) { + const spec = gd.choices.shopDraft; + const slots = spec && Array.isArray(spec.slots) ? spec.slots.filter((x) => x && typeof x === 'object') : []; + if (!slots.length) return null; + if (Array.isArray(spec.rounds) && !spec.rounds.includes(round)) return null; + const w = spec.itemWeights && typeof spec.itemWeights === 'object' ? spec.itemWeights : {}; + const coin = typeof spec.coin === 'string' && gd.item(spec.coin) ? spec.coin : null; + const ofTier = (t) => { + for (let k = t; k >= 1; k--) if ((gd.shopItemsByTier[k] || []).length) return gd.shopItemsByTier[k]; + return eligibleItems(gd, 1, 6); + }; + const out = []; + for (const slot of slots) { + const kinds = Object.entries(slot).filter(([k]) => k === 'coin' ? !!coin : Number.isInteger(Number(k))); + const kind = weightedPick(rng, kinds); + if (kind == null) continue; + const list = kind === 'coin' ? [coin] : ofTier(Number(kind)); + const id = weightedPick(rng, list.map((x) => [x, Object.hasOwn(w, x) ? w[x] : 1])); + if (id) out.push(itemCard(gd, id)); + } + return rng.shuffle(out).slice(0, Math.max(0, n)); +} + +/** The draft card of a cards.tactic entry. */ +export function tacticCard(c) { + return { kind: 'tactic', id: c.effectId, name: c.name, desc: c.desc || '', tier: null, team: !!c.team, tacticKind: c.kind }; +} + +/** + * The 战术决策 cards (module header): `n` cards, each drawn on its own — with replacement, so one card can fill two places + * (official R11 of match 7: 补给 ×2). At the rounds of choices.json `tacticDraft` (`rounds`; R11) only the cards of its + * `kinds` (ally), each by `weights` (1 when unlisted); elsewhere — or when those kinds leave nothing — every card, uniform. + * Terrain cards only for the match stage; a card whose every target bond is dead in this match (mode-inactive, or no + * chess left in the pool: `bondAvailable`) is never offered. + */ +export function tacticDraftCards(gd, rng, n, { stageId = null, bondAvailable = null, round = null } = {}) { + const bondOk = (c) => { + if (typeof bondAvailable !== 'function') return true; + const bonds = cardTargetBonds(gd, c.effectId); + return !bonds || bonds.some((b) => !!bondAvailable(b)); + }; + const list = Array.isArray(gd.choices.cards && gd.choices.cards.tactic) ? gd.choices.cards.tactic : []; + const pool = list.filter((c) => c && (c.kind !== 'terrain' || (stageId && c.stageId === stageId)) && gd.effect(c.effectId) && bondOk(c)); + const spec = gd.choices.tacticDraft && typeof gd.choices.tacticDraft === 'object' ? gd.choices.tacticDraft : null; + const official = !!spec && (!Array.isArray(spec.rounds) || spec.rounds.includes(round)); + const kinds = official && Array.isArray(spec.kinds) && spec.kinds.length ? spec.kinds : null; + const w = official && spec.weights && typeof spec.weights === 'object' ? spec.weights : {}; + const ofKinds = kinds ? pool.filter((c) => kinds.includes(c.kind)) : pool; + const pairs = (ofKinds.length ? ofKinds : pool).map((c) => [c, Object.hasOwn(w, c.effectId) ? w[c.effectId] : 1]); + const out = []; + for (let i = 0; i < n && pairs.length; i++) out.push(tacticCard(weightedPick(rng, pairs))); + return out; +} + function buildCards(gd, rng, family, n, sch, { stageId = null, bondAvailable = null, round = 1 } = {}) { - const cardsData = gd.choices.cards || {}; if (family === 'bounty') return bountyDraftCards(gd, rng, n, sch, round); + if (family === 'shop') { + const cards = shopDraftCards(gd, rng, n, round); + if (cards) return cards; + } if (family === 'supply' || family === 'shop') { let lo = 1; let hi = 6; @@ -287,18 +398,7 @@ function buildCards(gd, rng, family, n, sch, { stageId = null, bondAvailable = n for (let i = 0; i < n && list.length; i++) out.push(itemCard(gd, list[Math.floor(rng() * list.length)])); return out; } - if (family === 'tactic') { - // a card whose every target bond is dead in this match (mode-inactive, or no chess left in the pool) does nothing - const bondOk = (c) => { - if (typeof bondAvailable !== 'function') return true; - const bonds = cardTargetBonds(gd, c.effectId); - return !bonds || bonds.some((b) => !!bondAvailable(b)); - }; - const pool = (Array.isArray(cardsData.tactic) ? cardsData.tactic : []).filter((c) => c && (c.kind !== 'terrain' || (stageId && c.stageId === stageId)) && gd.effect(c.effectId) && bondOk(c)); - const pick = pool.slice(); - rng.shuffle(pick); - return pick.slice(0, n).map((c) => ({ kind: 'tactic', id: c.effectId, name: c.name, desc: c.desc || '', tier: null, team: !!c.team, tacticKind: c.kind })); - } + if (family === 'tactic') return tacticDraftCards(gd, rng, n, { stageId, bondAvailable, round }); return []; } diff --git a/test/content/choices.test.js b/test/content/choices.test.js index 3d7b6fd3..c082377d 100644 --- a/test/content/choices.test.js +++ b/test/content/choices.test.js @@ -8,7 +8,7 @@ import { makeMatch, give, giveItem, chessOfTier, legalTileFor, checkInvariants a import { FakeBattle } from '../match/fakeBattle.js'; import { makeBattle, chessRec, enemyRec, checkInvariants } from '../helpers/battleHarness.js'; import { createRegistry } from '../../server/match/effectsMeta.js'; -import { applyCard, generateDraft } from '../../server/match/choices.js'; +import { applyCard, generateDraft, tacticCard } from '../../server/match/choices.js'; import { withBounties } from '../../server/match/waves.js'; import { Battle } from '../../server/sim/Battle.js'; import { bountyOf, battlePlanOf, choiceCardIds, gateOf, hasBattlePart, mapAliases, BUILTIN_REFS } from '../../server/sim/content/choices.js'; @@ -41,6 +41,17 @@ function toDraft(h, r) { return m.sp; } +/** + * Lay out the open 战术决策 as exactly the tactic cards `ids` (each its own index). The draft draws every card on its own, + * with replacement (the official 补给 ×2), so a small test pool can repeat one card and miss another: the tests that + * drive a card's effect through g.choice offer their cards this way, after checking what the generator drew. + */ +function offerTactic(m, ids) { + m.sp.cards = ids.map((id, idx) => ({ ...tacticCard(DATA.choices.cards.tactic.find((c) => c.effectId === id)), idx, family: 'tactic' })); + m.markPublic(); + return m.sp; +} + /** Pick cards in the draft's (random) order: plan = { playerId: cardId }; bots pick by themselves. */ function draftPicks(h, plan) { const m = h.m; @@ -350,7 +361,7 @@ test('道具补给 E2E (co-op): 6 free normal items within the round window; the m.dispose(); }); -test('机密商店 E2E (solo HARD R11): 3 free normal items of any tier I–VI; a second copy merges into the 进阶 item', () => { +test('机密商店 E2E (solo HARD R11): 3 free normal items of the official composition; a second copy merges into the 进阶 item', () => { const data = dataWith('mode_single_hard', 11, 'shop'); const h = makeMatch({ mode: 'solo', difficulty: 'HARD', humans: 1, seed: 42, data, registry: REG, fake: true }); const m = h.m; @@ -372,22 +383,122 @@ test('机密商店 E2E (solo HARD R11): 3 free normal items of any tier I–VI; m.dispose(); }); -test('机密商店 draws every tier I–VI with duplicates allowed (generation, 30 drafts)', () => { +test('机密商店 draws the official composition with duplicates allowed (generation, 30 drafts; the evidence is test/match/feedback1-secret-shop.test.js)', () => { const h = makeMatch({ mode: 'coop', difficulty: 'HARD', humans: 1, seed: 5, data: dataWith('mode_multi_hard', 11, 'shop'), registry: REG, fake: true }); + const coin = DATA.choices.shopDraft.coin; const tiers = new Set(); let dupes = 0; for (let i = 0; i < 30; i++) { const d = generateDraft(h.m.gd, h.m.rngDraft, 11, { stageId: h.m.stageId }); assert.equal(d.family, 'shop'); assert.equal(d.cards.length, 6); + assert.equal(d.cards.filter((c) => DATA.items[c.id].tier === 6).length, 2, 'two tier-VI items'); + assert.ok(d.cards.some((c) => c.id === coin), 'a 盟约之币'); for (const c of d.cards) tiers.add(DATA.items[c.id].tier); if (new Set(d.cards.map((c) => c.id)).size < d.cards.length) dupes++; } h.m.dispose(); - assert.deepEqual([...tiers].sort(), [1, 2, 3, 4, 5, 6]); + assert.deepEqual([...tiers].sort(), [1, 3, 4, 5, 6], 'tiers III–VI and the tier-I 盟约之币'); assert.ok(dupes > 0, 'duplicates allowed'); }); +test('机密商店 E2E (co-op): two identical cards are two cards — both can be taken, by index, and each picker gets the item', () => { + // six 变形同构体: every slot draws the one item `coin` names + const one = Object.values(DATA.items).find((i) => i.name === '变形同构体' && !i.isGolden).id; + const data = dataWith('mode_multi_hard', 3, 'shop'); + data.choices = { ...data.choices, shopDraft: { ...data.choices.shopDraft, rounds: [3], slots: Array.from({ length: 6 }, () => ({ coin: 1 })), coin: one } }; + const h = makeMatch({ mode: 'coop', difficulty: 'HARD', humans: 2, bots: 2, seed: 43, data, registry: REG, fake: true }); + const m = h.m; + h.start(); + const sp = toDraft(h, 3); + assert.equal(sp.family, 'shop'); + const pub = m.publicView().sp; + assert.deepEqual(pub.cards.map((c) => c.id), Array(6).fill(one), 'six identical offers'); + assert.deepEqual(pub.cards.map((c) => c.idx), [0, 1, 2, 3, 4, 5], 'each its own index'); + const funds = { p_0: h.ps('p_0').funds, p_1: h.ps('p_1').funds }; + const picked = {}; + for (let guard = 0; guard < 1000 && m.phase === 'SP_DRAFT'; guard++) { + const pid = m.spTurn(); + if (pid !== 'p_0' && pid !== 'p_1') { h.sched.runNext(); continue; } + // a taken card is refused even though an identical one is still free + const taken = Object.keys(m.sp.taken).map(Number); + if (taken.length) assert.deepEqual(m.handle(pid, { t: 'g.choice', idx: taken[0] }), { error: 'SOLD_OUT' }, 'a taken index stays taken'); + const idx = m.sp.cards.find((c) => m.sp.taken[c.idx] == null).idx; + assert.deepEqual(m.handle(pid, { t: 'g.choice', idx }), { ok: true }); + picked[pid] = idx; + } + assert.equal(m.phase, 'PREP'); + assert.notEqual(picked.p_0, picked.p_1, 'two different cards of the same item'); + assert.equal(Object.keys(sp.taken).length, 4, 'every player took one of the identical cards'); + for (const pid of ['p_0', 'p_1']) { + const ps = h.ps(pid); + assert.ok([...ps.hand, ...ps.temp].some((p) => p && (p.id === one || p.id === DATA.items[one].goldenId)), `${pid} holds the item`); + assert.equal(ps.funds, funds[pid], 'free'); + } + matchInvariants(m); + m.dispose(); +}); + +test('战术决策 E2E (co-op): identical cards are separate cards — one pick applies its card exactly once, the twin stays pickable, picks stack', () => { + // a pool of one card: every place draws 补给 (with replacement; the official match 7 R11 offered 补给 twice) + const one = 'allybuff_select_4'; + const data = dataWith('mode_multi_normal', 3, 'tactic', { tactic: [one] }); + const h = makeMatch({ mode: 'coop', difficulty: 'NORMAL', humans: 2, bots: 2, seed: 44, data, registry: REG, fake: true }); + const m = h.m; + h.start(); + const sp = toDraft(h, 3); + assert.equal(sp.family, 'tactic'); + const pub = m.publicView().sp; + assert.deepEqual(pub.cards.map((c) => c.id), Array(6).fill(one), 'six 补给'); + assert.deepEqual(pub.cards.map((c) => c.idx), [0, 1, 2, 3, 4, 5], 'each its own index'); + assert.equal(new Set(sp.cards).size, 6, 'six card objects, not one shared'); + const all = [...m.players.values()]; + const free0 = new Map(all.map((ps) => [ps.playerId, ps.shop.freeRefreshes])); + const freeNow = () => all.map((ps) => ps.shop.freeRefreshes - free0.get(ps.playerId)); + const picked = {}; + for (let guard = 0; guard < 1000 && m.phase === 'SP_DRAFT'; guard++) { + const pid = m.spTurn(); + if (pid !== 'p_0' && pid !== 'p_1') { h.sched.runNext(); continue; } + const taken = Object.keys(m.sp.taken).map(Number); + if (taken.length) assert.deepEqual(m.handle(pid, { t: 'g.choice', idx: taken[0] }), { error: 'SOLD_OUT' }, 'a taken index stays taken while a twin is free'); + const before = freeNow(); + const idx = m.sp.cards.find((c) => m.sp.taken[c.idx] == null).idx; + assert.deepEqual(m.handle(pid, { t: 'g.choice', idx }), { ok: true }); + picked[pid] = idx; + assert.deepEqual(m.sp.taken[idx], pid, 'that index alone is taken'); + assert.equal(Object.values(m.sp.taken).filter((x) => x === pid).length, 1, 'one card per pick'); + // 补给 is a team card: +2 free refreshes for every alive player, once — not once per identical card + assert.deepEqual(freeNow().map((x, i) => x - before[i]), all.map(() => 2), `${pid}: one 补给 applied once`); + } + assert.equal(m.phase, 'PREP'); + assert.notEqual(picked.p_0, picked.p_1, 'two different cards of the same tactic'); + assert.equal(Object.keys(sp.taken).length, 4, 'every player took one of the identical cards'); + assert.deepEqual(freeNow(), all.map(() => 8), 'four picks of 补给 stack (+2 each)'); + matchInvariants(m); + m.dispose(); +}); + +test('战术决策 E2E (solo): of three identical personal cards the one picked applies once; the other two stay untaken', () => { + const one = 'allybuff_select_6'; // 升华: the next purchased operator becomes elite + const data = dataWith('mode_single_normal', 9, 'tactic', { tactic: [one] }); + const h = makeMatch({ mode: 'solo', difficulty: 'NORMAL', humans: 1, seed: 45, data, registry: REG, fake: true }); + const m = h.m; + h.start(); + const sp = toDraft(h, 9); + assert.deepEqual(sp.cards.map((c) => [c.idx, c.id]), [[0, one], [1, one], [2, one]]); + assert.deepEqual(m.handle('p_0', { t: 'g.choice', idx: 1 }), { ok: true }); + assert.deepEqual(sp.taken, { 1: 'p_0' }); + assert.deepEqual(sp.picks, { p_0: 1 }); + const refs = h.ps('p_0').effects.filter((e) => e.key === BUILTIN_REFS.eliteChess); + assert.equal(refs.length, 1, 'one 升华'); + assert.equal(refs[0].counter, 1); + for (let guard = 0; guard < 50 && m.phase === 'SP_DRAFT'; guard++) h.sched.runNext(); + assert.equal(m.phase, 'PREP'); + assert.equal(h.ps('p_0').effects.filter((e) => e.key === BUILTIN_REFS.eliteChess).length, 1, 'still one after the draft closed'); + matchInvariants(m); + m.dispose(); +}); + // ===================================================================================================================== // 战术决策 — prep-side cards @@ -401,7 +512,10 @@ test('战术决策 E2E (co-op 3): team cards reach every teammate (AI included), const sp = toDraft(h, 3); assert.equal(sp.family, 'tactic'); assert.equal(m.publicView().sp.name, '战术决策'); - assert.deepEqual(sp.cards.map((c) => c.id).sort(), [...TEAM_PREP].sort()); + assert.equal(m.publicView().sp.desc, '进行协同调整,做好迎战准备。', 'the official header'); + assert.equal(sp.cards.length, 6); + assert.ok(sp.cards.every((c) => TEAM_PREP.includes(c.id)), 'drawn from the pool (with replacement)'); + offerTactic(m, TEAM_PREP); const view = m.publicView().sp.cards; for (const c of view) assert.equal(c.team, DATA.choices.cards.tactic.find((x) => x.effectId === c.id).team, `${c.id} team flag`); const all = [...m.players.values()]; @@ -492,6 +606,7 @@ test('战术决策 升华 / 整备: the next purchased operator becomes elite, t const m = h.m; h.start(); toDraft(h, 9); + offerTactic(m, ['allybuff_select_5', 'allybuff_select_6', 'allybuff_select_3']); draftPicks(h, { p_0: 'allybuff_select_6' }); const ps = h.ps('p_0'); const ref = ps.effects.find((e) => e.key === BUILTIN_REFS.eliteChess); @@ -535,6 +650,7 @@ test('战术决策 E2E: 火力 / 锐利 evaluate the 手牌区 at every prep end const m = h.m; h.start(); const sp = toDraft(h, 3); + offerTactic(m, ['allybuff_select_13', 'allybuff_select_19']); const [a, b] = sp.order; draftPicks(h, { [a]: 'allybuff_select_13', [b]: 'allybuff_select_19' }); const A = h.ps(a); @@ -597,6 +713,7 @@ test('战术决策 E2E (real battles): 排斥 debuffs every enemy of the picker\ }; h.start(); const sp = toDraft(h, 3); + offerTactic(m, [id, 'allybuff_select_3']); const [a, b] = sp.order; draftPicks(h, { [a]: id, [b]: 'allybuff_select_3' }); assert.ok(h.ps(a).effects.some((e) => e.key === `choice:${id}` && e.iconId === 'icon_enemy_debuff')); @@ -747,6 +864,7 @@ test('模拟战场演变 E2E (act1 m01): the card clears the picker\'s crates fo h.setStage('act1autochess_m01'); const sp = toDraft(h, 3); assert.ok(!sp.cards.some((c) => c.id === 'map_m02_1'), 'terrain cards only for the match stage'); + offerTactic(m, ['map_m01_1', 'allybuff_select_3']); const [a, b] = sp.order; draftPicks(h, { [a]: 'map_m01_1', [b]: 'allybuff_select_3' }); const A = h.ps(a); diff --git a/test/docs-consistency.test.js b/test/docs-consistency.test.js index b804dadd..01eaaf90 100644 --- a/test/docs-consistency.test.js +++ b/test/docs-consistency.test.js @@ -625,7 +625,9 @@ test('player feedback after 0.1.0 (DESIGN §21, v0.1.1): every report mapped, th // settled: the tactician re-orientation (user-confirmed) and the screenshot-based bounty structures const s2120 = sub(20); assert.match(s2120, /A tactician re-oriented in place \(§21\.3\) \| a range-bound summon still inside the new range stays[^\n]*user-confirmed 2026-10-03/); - assert.match(s2120, /Bounty drafts \(§21\.2\) \| the official structure of each round from the user's 33 screenshots/); + assert.match(s2120, /Bounty drafts \(§21\.2\) \| the official structure of each round from the user's 66 screenshots of 22 matches/); + assert.match(s2120, /机密商店 \/ 战术决策 repeats \(§21\.2\) \| the same card can be offered twice/); + assert.ok(!/the remake's never do/.test(sub(2)), '§21.2: the 机密商店 and the 战术决策 repeat'); assert.match(s2120, /MULTI_ROUND_BOUNTY_BATTLES = null/); // §21.2 = §7 = §20.6 superseded = the data assert.match(sub(2), /initial 42, boss 20, hunter 24 \(86 drafted\)/); diff --git a/test/fixtures/official-bounty-drafts.json b/test/fixtures/official-bounty-drafts.json index 9147255a..436d26db 100644 --- a/test/fixtures/official-bounty-drafts.json +++ b/test/fixtures/official-bounty-drafts.json @@ -1,7 +1,8 @@ { - "_doc": "Official 机变 drafts at the start of rounds 3, 9 and 11, read from screenshots of 11 official co-op matches collected by the user (2026-10-03; player names left out). The cards are in screen order (left to right, top to bottom). A bounty card is [title, enemy as printed, coins, battles] (battles 2 = 接下来两场作战, 1 = 下场作战 / 下场战斗; 源石虫·特训 pays 0); a 机密商店 card is [item, tier]; a 战术决策 card is [name]. Names are converted to Simplified Chinese. Matches 1 and 2 come from the Traditional-Chinese client, 3-11 from Simplified-Chinese video captures. Every match is a 4-player co-op match of 绝境 or 终极 (the modes whose SP rounds are 3, 9 and 11; the HUD does not say which). Used by test/match/feedback1-bounty.test.js.", + "_doc": "Official 机变 drafts at the start of rounds 3, 9 and 11, read from screenshots of 22 official co-op matches collected by the user (33 on 2026-10-03, 33 more the same day; player names left out). The cards are in screen order (left to right, top to bottom). A bounty card is [title, enemy as printed, coins, battles] (battles 2 = 接下来两场作战, 1 = 下场作战 / 下场战斗; 源石虫·特训 pays 0); a 机密商店 card is [item, tier]; a 战术决策 card is [name]. Names are converted to Simplified Chinese. Matches 1 and 2 come from the Traditional-Chinese client, 3-22 from Simplified-Chinese video captures of one uploader; the user dates the videos to the end of March 2026, all of one season (卫戍协议:盟约 下半, act2autochess). Every match is a 4-player co-op match of 绝境 or 终极 (the modes whose SP rounds are 3, 9 and 11; the HUD does not say which). A card another player has taken stays in its slot, greyed with the taker's avatar (match 17 R3: 迷茫的修理小助手; match 21 R9: 大鲍勃 and 杰斯顿·威廉姆斯): one shared draft, one pick each in turn. `boards` = the colour of the battlefield behind the overlay (the same in all three rounds of a match). Used by test/match/feedback1-bounty.test.js.", "season": "act2autochess", "aliases": { "深池重甲卫队队长": "深池重甲卫士队长" }, + "boards": { "_doc": "grey = dark grey metal tiles with blue / red frames; tan = sandy / beige tiles (possibly more than one map)", "grey": [8, 9, 11, 13, 16, 18, 19], "tan": [1, 2, 3, 4, 5, 6, 7, 10, 12, 14, 15, 17, 20, 21, 22] }, "matches": { "1": { "3": { "family": "bounty", "cards": [["悬赏·损伤I", "临时收音师", 1, 2], ["悬赏·损伤III", "主角阵营角色", 3, 2], ["悬赏·特异I", "迷茫的修理小助手", 1, 2], ["悬赏·特异II", "寻仇者", 2, 2], ["悬赏·特异II", "圣堂剑士", 2, 2], ["悬赏·特异I", "高能源石虫", 1, 2]] }, @@ -57,6 +58,61 @@ "3": { "family": "bounty", "cards": [["悬赏·持续I", "萨卡兹枯朽战士组长", 1, 2], ["悬赏·损伤I", "底海滑动者", 1, 2], ["悬赏·频次III", "清明", 3, 2], ["悬赏·折射II", "深池暗影术师", 2, 2], ["悬赏·飞行I", "妖怪", 1, 2], ["悬赏·隐匿II", "隐形术师", 2, 2]] }, "9": { "family": "bounty", "cards": [["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["源石虫·特训", "源石虫", 0, 1], ["W·悬赏", "W", 1, 1], ["碎骨·悬赏", "碎骨", 1, 1], ["陷落雪祀·悬赏", "陷落雪祀", 3, 1]] }, "11": { "family": "bounty", "cards": [["悬赏·特异II", "拥霜羽兽", 2, 1], ["悬赏·隐匿I", "重弩突袭者", 1, 1], ["悬赏·损伤I", "心虚设计师", 1, 1], ["悬赏·特异III", "乌顶巨角卢鲁", 3, 1], ["悬赏·频次I", "沏虹", 1, 1], ["悬赏·持续I", "假想敌:蚀裂", 1, 1]] } + }, + "12": { + "3": { "family": "bounty", "cards": [["悬赏·损伤II", "控潮术师", 2, 2], ["悬赏·频次I", "磨砻", 1, 2], ["悬赏·损伤II", "无胄盟清扫小队", 2, 2], ["悬赏·持续I", "萨卡兹枯朽战士", 1, 2], ["悬赏·飞行I", "妖怪", 1, 2], ["悬赏·折射III", "深池伙友卫队", 3, 2]] }, + "9": { "family": "bounty", "cards": [["碎骨·悬赏", "碎骨", 1, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["W·悬赏", "W", 1, 1], ["源石虫·特训", "源石虫", 0, 1], ["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·折射II", "愤怒的守墓石像", 2, 1], ["悬赏·特异III", "萨卡兹骸骨拷打者", 3, 1], ["悬赏·飞行I", "法术大师A2", 1, 1], ["悬赏·损伤I", "心虚设计师", 1, 1], ["悬赏·损伤II", "灼藤", 2, 1], ["悬赏·频次I", "沏虹", 1, 1]] } + }, + "13": { + "3": { "family": "bounty", "cards": [["悬赏·损伤I", "底海滑动者", 1, 2], ["悬赏·频次I", "磨砻", 1, 2], ["悬赏·持续II", "逐腐兽", 2, 2], ["悬赏·折射II", "深池暗影术师", 2, 2], ["悬赏·特异III", "自制投石机", 3, 2], ["悬赏·隐匿I", "隐形弩手", 1, 2]] }, + "9": { "family": "bounty", "cards": [["陷落雪祀·悬赏", "陷落雪祀", 3, 1], ["源石虫·特训", "源石虫", 0, 1], ["碎骨·悬赏", "碎骨", 1, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["W·悬赏", "W", 1, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·频次I", "沏虹", 1, 1], ["悬赏·折射II", "深池重甲卫队队长", 2, 1], ["悬赏·特异III", "狂暴宿主组长", 3, 1], ["悬赏·特异II", "拥霜羽兽", 2, 1], ["悬赏·持续II", "尖端萨卡兹枯朽战车", 2, 1], ["悬赏·隐匿I", "重弩突袭者", 1, 1]] } + }, + "14": { + "3": { "family": "bounty", "cards": [["悬赏·特异I", "新手祭司学徒", 1, 2], ["悬赏·特异I", "冒失的小弟", 1, 2], ["悬赏·特异II", "骇笑看客", 2, 2], ["悬赏·特异I", "雪孩子", 1, 2], ["悬赏·特异II", "水遁忍者", 2, 2], ["悬赏·特异III", "自制投石机", 3, 2]] }, + "9": { "family": "bounty", "cards": [["大鲍勃·悬赏", "大鲍勃", 2, 1], ["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1], ["源石虫·特训", "源石虫", 0, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["碎骨·悬赏", "碎骨", 1, 1], ["“自在”·悬赏", "“自在”", 4, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·飞行I", "法术大师A2", 1, 1], ["悬赏·特异II", "异质裂兽·α", 2, 1], ["悬赏·特异III", "伊利昂的木驮兽", 3, 1], ["悬赏·隐匿II", "家族暗影灭迹人", 2, 1], ["悬赏·特异I", "转译基底·α", 1, 1], ["悬赏·持续I", "假想敌:蚀裂", 1, 1]] } + }, + "15": { + "3": { "family": "bounty", "cards": [["悬赏·特异II", "咸鳞汁推荐者", 2, 2], ["悬赏·折射I", "深池侦察犬pro", 1, 2], ["悬赏·损伤III", "反派阵营角色", 3, 2], ["悬赏·飞行II", "吉兆飞鳞", 2, 2], ["悬赏·特异I", "节日气球", 1, 2], ["悬赏·特异I", "简饲源石虫", 1, 2]] }, + "9": { "family": "bounty", "cards": [["W·悬赏", "W", 1, 1], ["碎骨·悬赏", "碎骨", 1, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["源石虫·特训", "源石虫", 0, 1], ["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·持续I", "假想敌:蚀裂", 1, 1], ["悬赏·隐匿I", "重弩突袭者", 1, 1], ["悬赏·频次I", "沏虹", 1, 1], ["悬赏·特异I", "转译基底·α", 1, 1], ["悬赏·飞行II", "枯朽萃聚使徒", 2, 1], ["悬赏·损伤II", "灼藤", 2, 1]] } + }, + "16": { + "3": { "family": "bounty", "cards": [["悬赏·持续III", "萨卡兹枯朽战车", 3, 2], ["悬赏·特异I", "潜伏者", 1, 2], ["悬赏·频次I", "磨砻", 1, 2], ["悬赏·折射I", "深池方阵战士", 1, 2], ["悬赏·飞行II", "暴鸰", 2, 2], ["悬赏·损伤II", "控潮术师", 2, 2]] }, + "9": { "family": "bounty", "cards": [["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1], ["陷落雪祀·悬赏", "陷落雪祀", 3, 1], ["源石虫·特训", "源石虫", 0, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["W·悬赏", "W", 1, 1], ["碎骨·悬赏", "碎骨", 1, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·损伤I", "心虚设计师", 1, 1], ["悬赏·损伤II", "灼藤", 2, 1], ["悬赏·隐匿II", "家族暗影灭迹人", 2, 1], ["悬赏·折射II", "愤怒的守墓石像", 2, 1], ["悬赏·飞行I", "法术大师A2", 1, 1], ["悬赏·特异III", "萨卡兹骸骨拷打者", 3, 1]] } + }, + "17": { + "3": { "family": "bounty", "cards": [["悬赏·特异II", "圣堂剑士", 2, 2], ["悬赏·特异I", "迷茫的修理小助手", 1, 2], ["悬赏·特异II", "寻仇者", 2, 2], ["悬赏·损伤I", "临时收音师", 1, 2], ["悬赏·损伤III", "主角阵营角色", 3, 2], ["悬赏·特异I", "高能源石虫", 1, 2]] }, + "9": { "family": "bounty", "cards": [["碎骨·悬赏", "碎骨", 1, 1], ["“自在”·悬赏", "“自在”", 4, 1], ["陷落雪祀·悬赏", "陷落雪祀", 3, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["源石虫·特训", "源石虫", 0, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·飞行II", "枯朽萃聚使徒", 2, 1], ["悬赏·特异III", "泥岩巨像", 3, 1], ["悬赏·持续I", "假想敌:蚀裂", 1, 1], ["悬赏·隐匿I", "重弩突袭者", 1, 1], ["悬赏·频次II", "新硎", 2, 1], ["悬赏·折射II", "深池重甲卫队队长", 2, 1]] } + }, + "18": { + "3": { "family": "bounty", "cards": [["悬赏·损伤III", "术师快艇", 3, 2], ["悬赏·隐匿I", "隐形弩手", 1, 2], ["悬赏·频次I", "俗心", 1, 2], ["悬赏·飞行I", "妖怪", 1, 2], ["悬赏·折射II", "深池暗影术师", 2, 2], ["悬赏·频次II", "烹泉", 2, 2]] }, + "9": { "family": "bounty", "cards": [["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1], ["“自在”·悬赏", "“自在”", 4, 1], ["源石虫·特训", "源石虫", 0, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1], ["“鼠王”·悬赏", "“鼠王”", 2, 1], ["弑君者·悬赏", "弑君者", 1, 1]] }, + "11": { "family": "tactic", "cards": [["整备"], ["玛恩纳的盟誓"], ["斯卡蒂的盟誓"], ["萨尔贡驰援"], ["财富"], ["升华"]] } + }, + "19": { + "3": { "family": "bounty", "cards": [["悬赏·隐匿I", "隐形弩手", 1, 2], ["悬赏·持续II", "逐腐兽", 2, 2], ["悬赏·频次I", "磨砻", 1, 2], ["悬赏·损伤I", "底海滑动者", 1, 2], ["悬赏·特异III", "自制投石机", 3, 2], ["悬赏·折射II", "深池暗影术师", 2, 2]] }, + "9": { "family": "bounty", "cards": [["“自在”·悬赏", "“自在”", 4, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1], ["陷落雪祀·悬赏", "陷落雪祀", 3, 1], ["W·悬赏", "W", 1, 1], ["碎骨·悬赏", "碎骨", 1, 1], ["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·特异III", "伊利昂的木驮兽", 3, 1], ["悬赏·隐匿II", "家族暗影灭迹人", 2, 1], ["悬赏·特异I", "转译基底·α", 1, 1], ["悬赏·持续I", "假想敌:蚀裂", 1, 1], ["悬赏·飞行I", "法术大师A2", 1, 1], ["悬赏·特异II", "异质裂兽·α", 2, 1]] } + }, + "20": { + "3": { "family": "bounty", "cards": [["悬赏·隐匿II", "隐形术师", 2, 2], ["悬赏·损伤I", "底海滑动者", 1, 2], ["悬赏·频次III", "清明", 3, 2], ["悬赏·持续I", "萨卡兹枯朽战士组长", 1, 2], ["悬赏·飞行I", "妖怪", 1, 2], ["悬赏·折射II", "深池暗影术师", 2, 2]] }, + "9": { "family": "bounty", "cards": [["“庞贝”·悬赏", "“庞贝”", 2, 1], ["“复仇者”·悬赏", "“复仇者”", 6, 1], ["源石虫·特训", "源石虫", 0, 1], ["萨卡兹百夫长·悬赏", "萨卡兹百夫长", 2, 1], ["澪·悬赏", "澪", 3, 1], ["W·悬赏", "W", 1, 1]] }, + "11": { "family": "tactic", "cards": [["阿戈尔驰援"], ["补给"], ["列装"], ["叙拉古驰援"], ["银灰的盟誓"], ["莫斯提马的盟誓"]] } + }, + "21": { + "3": { "family": "bounty", "cards": [["悬赏·持续II", "逐腐兽", 2, 2], ["悬赏·特异III", "自制投石机", 3, 2], ["悬赏·折射II", "深池暗影术师", 2, 2], ["悬赏·隐匿I", "隐形弩手", 1, 2], ["悬赏·频次I", "磨砻", 1, 2], ["悬赏·损伤I", "底海滑动者", 1, 2]] }, + "9": { "family": "bounty", "cards": [["弑君者·悬赏", "弑君者", 1, 1], ["碎骨·悬赏", "碎骨", 1, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1], ["“鼠王”·悬赏", "“鼠王”", 2, 1], ["杰斯顿·威廉姆斯·悬赏", "杰斯顿·威廉姆斯", 4, 1], ["W·悬赏", "W", 1, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·特异III", "温顺的武装大驮兽", 3, 1], ["悬赏·折射II", "深池重甲卫队队长", 2, 1], ["悬赏·持续II", "尖端萨卡兹枯朽战车", 2, 1], ["悬赏·特异II", "异质裂兽·α", 2, 1], ["悬赏·频次I", "沏虹", 1, 1], ["悬赏·飞行I", "法术大师A2", 1, 1]] } + }, + "22": { + "3": { "family": "bounty", "cards": [["悬赏·特异II", "咸鳞汁推荐者", 2, 2], ["悬赏·飞行II", "吉兆飞鳞", 2, 2], ["悬赏·特异I", "简饲源石虫", 1, 2], ["悬赏·特异I", "节日气球", 1, 2], ["悬赏·折射I", "深池侦察犬pro", 1, 2], ["悬赏·损伤III", "反派阵营角色", 3, 2]] }, + "9": { "family": "bounty", "cards": [["澪·悬赏", "澪", 3, 1], ["弑君者·悬赏", "弑君者", 1, 1], ["喷气人·悬赏", "喷气人", 3, 1], ["W·悬赏", "W", 1, 1], ["纠缠藤蔓·悬赏", "纠缠藤蔓", 3, 1], ["大鲍勃·悬赏", "大鲍勃", 2, 1]] }, + "11": { "family": "bounty", "cards": [["悬赏·特异III", "温顺的武装大驮兽", 3, 1], ["悬赏·频次I", "沏虹", 1, 1], ["悬赏·飞行I", "法术大师A2", 1, 1], ["悬赏·特异II", "异质裂兽·α", 2, 1], ["悬赏·持续II", "尖端萨卡兹枯朽战车", 2, 1], ["悬赏·损伤II", "灼藤", 2, 1]] } } }, "extra": { diff --git a/test/match/bosshp.test.js b/test/match/bosshp.test.js index cc50844a..21d51071 100644 --- a/test/match/bosshp.test.js +++ b/test/match/bosshp.test.js @@ -116,16 +116,24 @@ test('绝境 Final Assault: both pair fields drain the one pool, every hit exact m.dispose(); }); -test('终极 Final Assault vs 假想敌:胄 (seed 12): both players\' 奥术 never multiply on the leader; a drone costs it 2 % of the pool', () => { +test('终极 Final Assault vs 假想敌:胄 (seeded bot match): both players\' 奥术 never multiply on the leader; a drone costs it 2 % of the pool', () => { // DESIGN §20.10: one 奥术 instance per target (the strongest — PRTS 作战机制 同名buff, 巴哈姆特 12316 "共享型buff會跟對面搶"); // 死亡集群's "最大生命值2%" = the leader's shown max HP, the pool (DRONE_LINK_BASE 'pool' [ASSUMED]): 72 000 at 终极 - // seed 12: since the elite-to-board merge (DESIGN §20.11) the bots' boards differ; seed 7 no longer pairs two 奥术 players - const h = toFinalAssault({ difficulty: 'ABYSS', seed: 12, bossId: 'boss_1' }); + // the bots' boards follow every draw of the match (the elite-to-board merge, DESIGN §20.11, moved seed 7 to 12; the + // 战术决策 drawn with replacement moved 12 on): the first of these seeds whose bots pair two 奥术 players + const pairOf = (m) => m.fields.filter((f) => f.battle).find((f) => f.players.length === 2 && f.players.every((pid) => f.battle.getPlayer(pid).bonds.arcaneShip?.active)); + let h = null; + for (const seed of [13, 7, 11, 21, 23]) { + h = toFinalAssault({ difficulty: 'ABYSS', seed, bossId: 'boss_1' }); + if (pairOf(h.m)) break; + h.m.dispose(); + h = null; + } + assert.ok(h, 'precondition: a pair field where both players run 奥术 (bot lineups of one of the seeds)'); const m = h.m; const fields = m.fields.filter((f) => f.battle); const bb = bondBb('arcaneShip'); - const both = fields.find((f) => f.players.length === 2 && f.players.every((pid) => f.battle.getPlayer(pid).bonds.arcaneShip?.active)); - assert.ok(both, 'precondition: a pair field where both players run 奥术 (bot lineups of seed 12)'); + const both = pairOf(m); const allowed = []; for (const pid of both.players) { const b = both.battle.getPlayer(pid).bonds.arcaneShip; diff --git a/test/match/feedback1-bounty.test.js b/test/match/feedback1-bounty.test.js index 57d43b06..aa3ff6b1 100644 --- a/test/match/feedback1-bounty.test.js +++ b/test/match/feedback1-bounty.test.js @@ -1,15 +1,18 @@ // Player feedback after 0.1.0, report #2 (workstream WB): "本来应该后期出的悬赏的怪物在前期的悬赏就出现了,导致选了打不过". -// The user then collected the official 悬赏决策 of rounds 3, 9 and 11 in 11 official co-op matches (33 screenshots, 绝境 / -// 终极; the readings are test/fixtures/official-bounty-drafts.json, player names left out). They settle the draft rules -// (tools/build-data.mjs BOUNTY_INITIAL_SETS, server/match/choices.js bountyDraftCards): -// R3 six "接下来两场作战" cards, 3 × I + 2 × II + 1 × III, one of the official fixed sets (a whole series 17 / 18 / 19, -// or one card from each of 6 of the series 10–15 / 20) — 7 of the 10 events seen; -// R9 boss bounties + 源石虫·特训: a group of named bosses that come together + cheap ones to 6; -// R11 悬赏决策 / 机密商店 / 战术决策 (never 道具补给); its bounty: a group (one 特异III giant + 1–4 tier-II "下场战斗" cards, -// always together — matches 1 and 6 share the whole group) + tier-I cards to 6, at most one per faction series; +// The user then collected the official 机变 of rounds 3, 9 and 11 in 22 official co-op matches (66 screenshots, 绝境 / +// 终极, one season — videos of the end of March 2026; the readings are test/fixtures/official-bounty-drafts.json, player +// names left out). They settle the draft rules (tools/build-data.mjs BOUNTY_INITIAL_SETS, server/match/choices.js +// bountyDraftCards): a 悬赏决策 event is a fixed card list and the draft shows 6 different cards of it — +// R3 a set of six "接下来两场作战" cards (all six), 3 × I + 2 × II + 1 × III: 9 of the 10 events seen; +// R9 a group of up to 9 boss bounties / 源石虫·特训: 6 groups (9, 9, 9, 9, 8, 6 cards) for the 6 events, the 鼠王 +// group in 14 of 22 matches; +// R11 悬赏决策 14 / 机密商店 4 / 战术决策 4 / 道具补给 0; its bounty: a list of 7 "下场战斗" cards (one 特异III giant), +// one per faction series — 7 lists seen, three of them whole (each draft leaves out one card), picked uniformly +// (no list built from nothing; which of the 15 bounty_hunter events R11 fires is open); // no draft shows a multi-round card, a pre-series card (enemyeffect_3_*), 战术特训 or the 鸭爵 set; no card twice. // Each card's enemy is fixed by its effect; the title only names category and tier (悬赏·损伤I = 底海滑动者 in // enemyeffect_12_4, 临时收音师 in enemyeffect_18_1). Real data, real draft code, the real match path for the players' case. +// The 机密商店 is in test/match/feedback1-secret-shop.test.js. import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync, existsSync } from 'node:fs'; @@ -27,57 +30,39 @@ const SPEC = DATA.choices.bountyDrafts; const COOP_BOUNTY_MODES = ['mode_multi_normal', 'mode_multi_hard', 'mode_multi_abyss']; const isBoss = (key) => DATA.enemies[key] && DATA.enemies[key].rank === 'BOSS'; const sameSet = (a, b) => a.length === b.length && [...a].sort().join() === [...b].sort().join(); +const subset = (a, b) => a.every((x) => b.includes(x)); +const EE = (s) => `enemyeffect_${s}`; /** The data card of a screenshot reading [title, enemy, coins, battles] (by title, the enemy in the text, coins, battles). */ function resolve([title, enemy, coin, battles]) { const name = OFFICIAL.aliases[enemy] || enemy; - const hits = CARDS.filter((c) => c.name === title && c.coin === coin && (c.desc.includes(`1只${name}`) || c.desc.includes(`1个${name}`)) + // "1只萨卡兹枯朽战士," — the enemy's whole name (萨卡兹枯朽战士 is not 萨卡兹枯朽战士组长) + const hits = CARDS.filter((c) => c.name === title && c.coin === coin && (c.desc.includes(`1只${name},`) || c.desc.includes(`1个${name},`)) && (battles === 2 ? c.rounds === 2 : c.rounds === 1)); assert.equal(hits.length, 1, `${title} ${enemy} ${coin}: ${hits.map((c) => c.effectId).join(', ') || 'no card'}`); return hits[0].effectId; } -/** Every official draft of the fixture: [{ where, round, family, ids? }] (ids for 悬赏决策). */ +/** Every official draft of the fixture: [{ where, match, round, family, ids? }] (ids for 悬赏决策). */ function officialDrafts() { const out = []; for (const [match, rounds] of Object.entries(OFFICIAL.matches)) { - for (const [round, d] of Object.entries(rounds)) out.push({ where: `match ${match} R${round}`, round: Number(round), family: d.family, ids: d.family === 'bounty' ? d.cards.map(resolve) : null }); + for (const [round, d] of Object.entries(rounds)) out.push({ where: `match ${match} R${round}`, match: Number(match), round: Number(round), family: d.family, ids: d.family === 'bounty' ? d.cards.map(resolve) : null }); } - for (const [key, d] of Object.entries(OFFICIAL.extra)) out.push({ where: key, round: 9, family: d.family, ids: d.cards.map(resolve) }); + for (const [key, d] of Object.entries(OFFICIAL.extra)) out.push({ where: key, match: key, round: 9, family: d.family, ids: d.cards.map(resolve) }); return out; } const tiersOf = (ids) => ids.map((id) => CARD.get(id).tier).sort().join(''); - -/** The rule of the unseen R3 slots (and of the seen mixed sets): one card from each of 6 of the series, I I I II II III. */ -function mixedRule(ids) { - const mx = SPEC.initial.mixed; - const series = ids.map((id) => CARD.get(id).series); - return ids.length === mx.count && ids.every((id) => CARD.get(id).draftPool === 'initial') && new Set(series).size === series.length - && series.every((s) => mx.series.includes(s)) && tiersOf(ids) === mx.tiers.slice().sort().join(''); -} -/** Which official R3 structure a set of ids is: 'set:' (a seen set), 'mixed' (the unseen-slot rule) or null. */ -function initialFit(ids) { - const i = SPEC.initial.sets.findIndex((s) => sameSet(s.cards, ids)); - if (i >= 0) return `set:${i}`; - return mixedRule(ids) ? 'mixed' : null; -} -/** The R9 groups a set of ids fits (its featured bosses all there, the rest from the group's fill). */ -const bossFits = (ids) => SPEC.boss.templates.map((t, i) => [t, i]).filter(([t]) => ids.length === SPEC.boss.count - && t.featured.every((id) => ids.includes(id)) && ids.filter((id) => !t.featured.includes(id)).every((id) => t.fill.includes(id))).map(([, i]) => i); +/** The group of `spec` whose `seen` lists the draft's match. */ +const groupOf = (spec, d) => spec.groups.filter((g) => g.seen.includes(d.match)); /** At most one card per faction series 10–15 (every official R11 draft). */ function onePerSeries(ids) { - const series = ids.map((id) => CARD.get(id).series).filter((s) => SPEC.hunter.onePerSeries.includes(s)); + const series = ids.map((id) => CARD.get(id).series).filter((s) => SPEC.hunter.rule.onePerSeries.includes(s)); return new Set(series).size === series.length; } -/** The seen R11 groups a set of ids fits (the group's giant + tier-II cards all there, the rest from its fill). */ -const hunterFits = (ids) => SPEC.hunter.templates.map((t, i) => [t, i]).filter(([t]) => ids.length === SPEC.hunter.count && onePerSeries(ids) - && t.featured.every((id) => ids.includes(id)) && ids.filter((id) => !t.featured.includes(id)).every((id) => t.fill.includes(id))).map(([, i]) => i); -/** The R11 shape an unseen slot is built by: one tier-III giant, 1–4 tier-II group cards, tier-I fill, one per faction series. */ -function hunterShape(ids) { - const r = SPEC.hunter.rule; - const giants = ids.filter((id) => r.giants.includes(id)).length; - const group = ids.filter((id) => r.groupCards.includes(id)).length; - const fill = ids.filter((id) => r.fill.includes(id)).length; - return ids.length === SPEC.hunter.count && giants === 1 && r.groupSizes.includes(group) && giants + group + fill === ids.length && onePerSeries(ids); +const giantsIn = (ids) => ids.filter((id) => SPEC.hunter.rule.giants.includes(id)).length; +/** The weights the data gives a group's cards: 1 + the official drafts of that group the card appeared in. */ +function expectedWeights(g, drafts) { + return g.cards.map((id) => 1 + drafts.filter((d) => d.ids.includes(id)).length); } /** Bounty drafts generated for `modeId` at `round` over `seeds` seeds. */ @@ -91,13 +76,23 @@ function drafts(modeId, round, seeds, data = DATA) { return out; } +/** An unseen-slot R3 set (`rule`): two-battle cards of its series, I I I II II III, ≤ perSeries a series, the III preferred. */ +function initialRule(ids) { + const r = SPEC.initial.rule; + const series = ids.map((id) => CARD.get(id).series); + return ids.length === 6 && ids.every((id) => CARD.get(id).draftPool === 'initial' && r.series.includes(CARD.get(id).series)) + && series.every((s) => series.filter((x) => x === s).length <= r.perSeries) && tiersOf(ids) === r.tiers.slice().sort().join('') + && ids.some((id) => r.prefer.includes(id)); +} + test('#2 screenshots → data: every card read is one act2autochess (下半) effect, whose enemy_id is the enemy the card brings', (t) => { const seen = new Set(); for (const d of officialDrafts()) for (const id of d.ids || []) seen.add(id); - assert.equal(seen.size, 72, 'distinct cards in the 27 bounty drafts: 36 at R3, 20 at R9, 16 at R11'); + assert.equal(seen.size, 81, 'distinct cards in the 59 bounty drafts: 40 at R3, 20 at R9, 21 at R11'); // the R3(1) question: the title names category and tier only — two different 悬赏·损伤I cards, each with its own enemy assert.equal(resolve(['悬赏·损伤I', '临时收音师', 1, 2]), 'enemyeffect_18_1'); assert.equal(resolve(['悬赏·损伤I', '底海滑动者', 1, 2]), 'enemyeffect_12_4'); + assert.equal(resolve(['悬赏·持续I', '萨卡兹枯朽战士', 1, 2]), 'enemyeffect_20_1', 'not 萨卡兹枯朽战士组长 (13_4)'); assert.equal(CARD.get('enemyeffect_18_1').enemyKey, 'enemy_10094_crstf'); assert.equal(CARD.get('enemyeffect_12_4').enemyKey, 'enemy_1148_dssbr'); const p = new URL('../../.cache/gamedata/excel/activity_table.json', import.meta.url); @@ -112,40 +107,47 @@ test('#2 screenshots → data: every card read is one act2autochess (下半) eff assert.ok(seen.has(id) && !act.act1autochess.effectInfoDataDict[id], `${id} is 下半-only`); } assert.match(act.act1autochess.effectInfoDataDict.enemyeffect_11_6.effectDesc, /沉沙/); + // all 22 matches are one season: 终极 (mode_multi_abyss) opened on 2026-03-27 16:00 (UTC+8), before the end-of-March videos + assert.equal(act.act2autochess.modeDataDict.mode_multi_abyss.startTime, Date.UTC(2026, 2, 27, 8) / 1000); }); -test('#2 R3 (11 of 11 official drafts): one of the official sets of six "接下来两场作战" cards, 3 × I + 2 × II + 1 × III', () => { +test('#2 R3 (22 of 22 official drafts): one of the official sets of six "接下来两场作战" cards, 3 × I + 2 × II + 1 × III — 9 of the 10 seen', () => { const r3 = officialDrafts().filter((d) => d.round === 3); - assert.equal(r3.length, 11); - const hits = SPEC.initial.sets.map(() => 0); + assert.equal(r3.length, 22); + const hits = SPEC.initial.groups.map(() => []); for (const d of r3) { assert.equal(d.family, 'bounty', `${d.where}: R3 is a 悬赏决策`); assert.ok(d.ids.every((id) => CARD.get(id).rounds === 2 && CARD.get(id).draftPool === 'initial'), `${d.where}: two-battle cards`); assert.equal(tiersOf(d.ids), '111223', `${d.where}: tiers`); assert.ok(d.ids.every((id) => !isBoss(CARD.get(id).enemyKey)), `${d.where}: no boss`); - const fit = initialFit(d.ids); - assert.match(fit || '', /^set:/, `${d.where}: a seen set`); - hits[Number(fit.slice(4))]++; + const i = SPEC.initial.groups.findIndex((s) => sameSet(s.cards, d.ids)); + assert.ok(i >= 0, `${d.where}: a seen set`); + hits[i].push(d.match); } - assert.deepEqual(hits, [4, 1, 1, 2, 1, 1, 1], 'series 18 ×4, 19, 17, the 10_5… set ×2, three more mixed sets'); - // each seen set is a whole series 17 / 18 / 19 or follows the rule the unseen slots are built by - for (const s of SPEC.initial.sets) { - const series = new Set(s.cards.map((id) => CARD.get(id).series)); - assert.ok(series.size === 1 ? [17, 18, 19].includes([...series][0]) && s.cards.length === 6 : mixedRule(s.cards), s.cards.join()); - assert.equal(tiersOf(s.cards), '111223'); - } - assert.equal(SPEC.initial.slots, 10, 'enemy_initial_1..10'); + assert.deepEqual(hits, SPEC.initial.groups.map((s) => s.seen), 'each set\'s `seen` lists the matches it came in'); + assert.deepEqual(hits.map((x) => x.length), [5, 3, 2, 3, 2, 1, 2, 1, 3]); + // hand-made sets, not one card per series: two series-20 cards (match 12), a series-17 card among faction cards (13 / 19 / 21) + assert.deepEqual(SPEC.initial.groups[7].cards.filter((id) => CARD.get(id).series === 20), [EE('20_1'), EE('20_5')]); + assert.ok(SPEC.initial.groups[8].cards.includes(EE('17_6'))); + for (const s of SPEC.initial.groups) assert.equal(tiersOf(s.cards), '111223', s.cards.join()); + assert.equal(SPEC.initial.slots, 10, 'enemy_initial_1..10: one unseen'); + assert.equal(SPEC.initial.pick, 'slot'); + // the only two-battle cards no draft showed are the unseen set's preferred tier-III cards + const shown = new Set(r3.flatMap((d) => d.ids)); + assert.deepEqual(CARDS.filter((c) => c.draftPool === 'initial' && !shown.has(c.effectId)).map((c) => c.effectId), SPEC.initial.rule.prefer); + assert.ok(SPEC.initial.rule.prefer.every((id) => CARD.get(id).tier === 3)); }); -test('#2 R3 generated: a seen set or an unseen-slot set (one card from each of 6 of the series 10–15 / 20, I I I II II III) — every seen set comes up, the unseen slots about 3 in 10', () => { +test('#2 R3 generated: a seen set (all six cards) or the unseen 10th set — every seen set comes up, the unseen one about 1 in 10', () => { const counts = new Map(); let n = 0; for (const modeId of COOP_BOUNTY_MODES) { for (const round of DATA.choices.schedule[modeId].spRounds.filter((r) => bountyDraftKind(r) === 'initial')) { - for (const d of drafts(modeId, round, modeId === 'mode_multi_hard' ? 400 : 60)) { + for (const d of drafts(modeId, round, modeId === 'mode_multi_hard' ? 600 : 60)) { const ids = d.cards.map((c) => c.id); assert.equal(new Set(ids).size, 6, 'six different cards'); - const fit = initialFit(ids); + const i = SPEC.initial.groups.findIndex((s) => sameSet(s.cards, ids)); + const fit = i >= 0 ? `set:${i}` : initialRule(ids) ? 'rule' : null; assert.ok(fit, `${modeId} R${round}: ${d.cards.map((c) => c.name).join(', ')}`); assert.ok(d.cards.every((c) => c.rounds === 2 && !isBoss(c.enemyKey)), 'two-battle cards, no boss'); assert.match(d.eventId, /^enemy_initial_\d+$/); @@ -153,9 +155,9 @@ test('#2 R3 generated: a seen set or an unseen-slot set (one card from each of 6 } } } - for (let i = 0; i < SPEC.initial.sets.length; i++) assert.ok(counts.get(`set:${i}`) > 0, `set ${i} offered`); - const mixed = (counts.get('mixed') || 0) / n; - assert.ok(mixed > 0.2 && mixed < 0.4, `unseen-slot sets ${(mixed * 100).toFixed(0)} %`); + for (let i = 0; i < SPEC.initial.groups.length; i++) assert.ok(counts.get(`set:${i}`) > 0, `set ${i} offered`); + const rule = (counts.get('rule') || 0) / n; + assert.ok(rule > 0.05 && rule < 0.16, `unseen-set drafts ${(rule * 100).toFixed(0)} %`); // solo: 3 cards of such a set for (const d of drafts('mode_single_hard', 3, 40)) { assert.equal(d.cards.length, 3); @@ -163,88 +165,158 @@ test('#2 R3 generated: a seen set or an unseen-slot set (one card from each of 6 } }); -test('#2 R9 (12 of 12 official drafts): boss bounties + 源石虫·特训 — a group of named bosses always together, filled to 6 with the cheap ones', () => { +test('#2 R9 (23 official drafts): six groups (9, 9, 9, 9, 8, 6 cards) of boss bounties / 源石虫·特训, 6 cards a draft — 庞贝 and 鼠王 never together, the 鼠王 group in 14 of 22 matches', () => { const r9 = officialDrafts().filter((d) => d.round === 9); - assert.equal(r9.length, 12, '11 matches + the Bahamut co-op screenshot'); - const hits = SPEC.boss.templates.map(() => 0); + assert.equal(r9.length, 23, '22 matches + the Bahamut co-op screenshot'); + const B = SPEC.boss; + assert.equal(B.groups.length, B.events.length, 'one group per bossInitial event'); + // the groups as they are: 9 cards where three named bosses came; the single-draft groups completed only with the + // base cards they lack — 腐败骑士 9, 泥岩 + 澪 8, match 4 (the base alone) 6 [ASSUMED] + assert.deepEqual(B.groups.map((g) => g.cards.length), [9, 9, 9, 9, 8, 6]); + const base = B.groups.find((g) => g.seen.includes(4)); + assert.deepEqual(base.seen, [4]); + assert.ok(sameSet(base.cards, ['b_10', 'b_1', 'b_3', 'b_13', 'b_12', '5_1'].map(EE)), 'match 4: W 碎骨 弑君者 大鲍勃 庞贝 源石虫'); + // …which is also six cards of the 喷气人 and 泥岩 groups: match 4 may be a draft of one of them (open question) + for (const boss of ['b_8', 'b_4']) assert.ok(subset(base.cards, B.groups.find((g) => g.cards.includes(EE(boss))).cards)); for (const d of r9) { assert.equal(d.family, 'bounty', `${d.where}: R9 is a 悬赏决策`); assert.ok(d.ids.every((id) => CARD.get(id).draftPool === 'boss' && CARD.get(id).rounds === 1), `${d.where}: boss bounties / 源石虫·特训, 下场作战`); - const fits = bossFits(d.ids); - assert.equal(fits.length, 1, `${d.where}: fits exactly one seen group (${fits.join(', ')})`); - hits[fits[0]]++; + const g = groupOf(B, d); + assert.equal(g.length, 1, `${d.where}: listed by one group`); + assert.ok(subset(d.ids, g[0].cards), `${d.where}: six cards of its group`); + assert.ok(!(d.ids.includes(EE('b_12')) && d.ids.includes(EE('b_11'))), `${d.where}: 庞贝 and 鼠王 never together`); } - assert.ok(hits.every((x) => x > 0), `every group seen (${hits.join(' ')})`); - for (const d of drafts('mode_multi_abyss', 9, 300)) { + for (const g of B.groups) { + const ds = r9.filter((d) => g.seen.includes(d.match)); + assert.equal(ds.length, g.seen.length, `${g.cards.join(' ')}: every match it lists`); + assert.deepEqual(g.weights, expectedWeights(g, ds), `${g.cards.join(' ')}: weights = 1 + the drafts each card showed in`); + // every group seen in 3 or more drafts shows exactly 9 different cards — the list + if (ds.length >= 3) assert.ok(sameSet([...new Set(ds.flatMap((d) => d.ids))], g.cards) && g.cards.length === 9, `${g.cards.join(' ')}: the 9 cards its drafts show`); + } + // a named boss does not always come with its partners: 杰斯顿 alone (12, 15, 21); 复仇者 + 百夫长 without 邪魔的利刃 (20) + const named = (d) => d.ids.filter((id) => ['b_9', 'b_14', 'b_23'].map(EE).includes(id)); + for (const m of [12, 15, 21]) assert.deepEqual(named(r9.find((d) => d.match === m)), [EE('b_9')], `match ${m}`); + const m20 = r9.find((d) => d.match === 20).ids; + assert.ok(m20.includes(EE('b_21')) && m20.includes(EE('b_2')) && !m20.includes(EE('b_22'))); + // the 鼠王 group: 14 of 22 matches, every match on the dark grey board (7 of 7) — something of the match picks the group + const rat = B.groups.find((g) => g.cards.includes(EE('b_11'))); + assert.equal(rat.seen.length, 14); + for (const m of OFFICIAL.boards.grey) assert.ok(rat.seen.includes(m), `match ${m} (grey board): the 鼠王 group`); + assert.equal(B.pick, 'seen'); + // generated: six different cards of one group; the 鼠王 group about 14 / 22; every card of every group offered + const offered = new Set(); + let ratN = 0; + const gen = drafts('mode_multi_abyss', 9, 1500); + for (const d of gen) { const ids = d.cards.map((c) => c.id); assert.equal(new Set(ids).size, 6); - assert.ok(bossFits(ids).length > 0, ids.join(', ')); + assert.ok(B.groups.some((g) => subset(ids, g.cards)), ids.join(', ')); + assert.ok(!(ids.includes(EE('b_12')) && ids.includes(EE('b_11'))), '庞贝 and 鼠王 never together'); assert.match(d.eventId, /^bossInitial_\d+$/); + if (ids.some((id) => ['b_11', 'b_9', 'b_14', 'b_23'].map(EE).includes(id)) && subset(ids, rat.cards)) ratN++; + ids.forEach((id) => offered.add(id)); } - const offered = new Set(drafts('mode_multi_hard', 9, 300).flatMap((d) => d.cards.map((c) => c.id))); - for (const t of SPEC.boss.templates) for (const id of t.featured) assert.ok(offered.has(id), `${CARD.get(id).name} offered`); + assert.ok(ratN / gen.length > 0.55 && ratN / gen.length < 0.73, `the 鼠王 group ${(100 * ratN / gen.length).toFixed(0)} %`); + for (const g of B.groups) for (const id of g.cards) assert.ok(offered.has(id), `${CARD.get(id).name} offered`); for (const id of ['enemyeffect_b_6', 'enemyeffect_b_7', 'enemyeffect_b_15', 'enemyeffect_b_16', 'enemyeffect_b_18']) { assert.equal(CARD.get(id).draftExcluded, 'unseen', `${CARD.get(id).name}: in no official R9 draft`); assert.ok(!offered.has(id)); } }); -test('#2 R11 (11 matches: 悬赏决策 5, 机密商店 4, 战术决策 2, 道具补给 0): the families, and the bounty — a group (one 特异III giant + its tier-II cards, always together) + tier-I fill, one card per faction series', () => { +test('#2 R11 (22 matches: 悬赏决策 14, 机密商店 4, 战术决策 4, 道具补给 0): the families, and the bounty — 6 of a list of 7 "下场战斗" cards, one per faction series', () => { const r11 = officialDrafts().filter((d) => d.round === 11); const fam = {}; for (const d of r11) fam[d.family] = (fam[d.family] || 0) + 1; - assert.deepEqual(fam, { bounty: 5, shop: 4, tactic: 2 }); - const hits = SPEC.hunter.templates.map(() => 0); - const byMatch = {}; - for (const d of r11.filter((x) => x.family === 'bounty')) { + assert.deepEqual(fam, { bounty: 14, shop: 4, tactic: 4 }); + const H = SPEC.hunter; + const bounty = r11.filter((x) => x.family === 'bounty'); + for (const d of bounty) { assert.ok(d.ids.every((id) => CARD.get(id).draftPool === 'hunter' && CARD.get(id).rounds === 1), `${d.where}: R11 cards, 下场战斗`); - assert.ok(hunterShape(d.ids), `${d.where}: the shape the unseen slots are built by (${tiersOf(d.ids)})`); - const fits = hunterFits(d.ids); - assert.equal(fits.length, 1, `${d.where}: fits exactly one seen group (${fits.join(', ')})`); - hits[fits[0]]++; - byMatch[d.where.split(' ')[1]] = d.ids; + assert.ok(onePerSeries(d.ids), `${d.where}: one card per faction series`); + assert.ok(giantsIn(d.ids) <= 1, `${d.where}: at most one giant`); + const g = groupOf(H, d); + assert.equal(g.length, 1, `${d.where}: listed by one group`); + assert.ok(subset(d.ids, g[0].cards), `${d.where}: six cards of its group`); } - assert.deepEqual(hits, [2, 1, 1, 1], 'the 16_4 group in matches 1 and 6, three more groups once'); - // the evidence against a free draw: matches 1 and 6 share the giant and all four tier-II cards, only the tier-I card differs - const shared = byMatch['1'].filter((id) => byMatch['6'].includes(id)); - assert.equal(shared.length, 5); - assert.deepEqual(byMatch['1'].filter((id) => !shared.includes(id)).concat(byMatch['6'].filter((id) => !shared.includes(id))).map((id) => CARD.get(id).tier), [1, 1]); - for (const id of ['enemyeffect_10_8', 'enemyeffect_11_8', 'enemyeffect_12_8']) assert.ok(!Object.values(byMatch).flat().includes(id), `${id} in no official R11 draft`); + assert.equal(bounty.filter((d) => giantsIn(d.ids) === 1).length, 13, 'a giant in 13 of 14 (not match 15)'); + for (const g of H.groups) { + const ds = bounty.filter((d) => g.seen.includes(d.match)); + assert.equal(ds.length, g.seen.length); + assert.equal(g.cards.length + (g.open || 0), H.rule.size, `${g.cards.join(' ')}: a list of 7`); + assert.deepEqual(g.weights, expectedWeights(g, ds), `${g.cards.join(' ')}: weights = 1 + hits`); + assert.ok(sameSet([...new Set(ds.flatMap((d) => d.ids))], g.cards), `${g.cards.join(' ')}: the cards its drafts show`); + assert.ok(onePerSeries(g.cards) && giantsIn(g.cards) <= 1); + if (!giantsIn(g.cards)) assert.equal(g.open, 1, 'a list showing no giant gets one by the rule'); + } + // the evidence for lists of 7: the 16_4 group's four drafts each leave out a different one of the same 7 cards + const big = H.groups.find((g) => g.cards.includes(EE('16_4'))); + const left = bounty.filter((d) => big.seen.includes(d.match)).map((d) => big.cards.find((id) => !d.ids.includes(id))); + assert.equal(new Set(left).size, 4, left.join(' ')); + assert.equal(H.groups.filter((g) => !g.open).length, 3, 'three groups seen whole'); + assert.deepEqual(CARDS.filter((c) => c.draftPool === 'hunter' && !bounty.some((d) => d.ids.includes(c.effectId))).map((c) => c.effectId), + ['12_8', '16_2', '16_6'].map(EE), 'R11 cards no draft showed'); for (const modeId of ['mode_multi_hard', 'mode_multi_abyss', 'mode_single_hard', 'mode_single_abyss']) { const sch = DATA.choices.schedule[modeId].rounds['11']; - assert.deepEqual(sch.families.map((f) => f.family).sort(), ['bounty', 'shop', 'tactic'], `${modeId} R11 (solo: extrapolated from co-op, [ASSUMED])`); + assert.deepEqual(sch.families, [{ family: 'bounty', weight: 14 }, { family: 'shop', weight: 4 }, { family: 'tactic', weight: 4 }], `${modeId} R11 (solo: extrapolated from co-op, [ASSUMED])`); assert.equal(sch.bountyDraft, 'hunter'); assert.equal(sch.assumed, true); } - assert.equal(SPEC.hunter.slots, 15, 'bounty_hunter_1..15'); - // generated: a seen group (about 4 in 15) or a group of the same shape; every seen group and every R11 card comes up + // the list is one of the 7 seen, uniform — no list built from nothing [ASSUMED]: 15 equally likely events would show 7 + // lists or fewer in 14 drafts about 6 % of the time; 7, 8 or 9 events show exactly 7 about equally often (37 / 45 / 39 %) + assert.equal(H.events.length, 15, 'bounty_hunter_1..15 in the data'); + assert.equal(H.slots, H.groups.length); + assert.equal(H.slots, 7); + assert.equal(H.pick, 'slot'); + // the data's block order, which does NOT settle which events R11 fires: bounty_hunter_1..7 after bossInitial_1..6; + // 8..15 after artifact_paid_4 / 5 and right before the 绝境 / 终极-only hardbuff_select (read by blocks, R11 = 8..15) + const p = new URL('../../.cache/gamedata/excel/activity_table.json', import.meta.url); + if (existsSync(p)) { + const keys = Object.keys(JSON.parse(readFileSync(p, 'utf8')).activity.AUTOCHESS_SEASON.act2autochess.effectChoiceInfoDict); + const at = (k) => keys.indexOf(k); + assert.equal(at('bounty_hunter_1'), at('bossInitial_6') + 1, 'bounty_hunter_1..7 right after the R9 events'); + for (let i = 2; i <= 7; i++) assert.equal(at(`bounty_hunter_${i}`), at('bounty_hunter_1') + i - 1); + assert.ok(at('artifact_paid_5') > at('bounty_hunter_7') + 1, 'bounty_hunter_8..15 not with 1..7'); + for (let i = 8; i <= 15; i++) assert.equal(at(`bounty_hunter_${i}`), at('artifact_paid_5') + i - 7, 'bounty_hunter_8..15 right after artifact_paid_4 / 5'); + assert.equal(at('hardbuff_select_1'), at('bounty_hunter_15') + 1); + } + // generated: six different cards, one per faction series, at most one giant, at most the `open` card outside one seen + // list; a whole seen list about 3 in 7; every R11 card comes up (12_8 / 16_2 / 16_6 only as an `open` card, rarely) const gd = new GameData(DATA, 'mode_multi_hard'); const seen = {}; - const groups = SPEC.hunter.templates.map(() => 0); const offered = new Set(); - let bounty = 0; + const never = ['12_8', '16_2', '16_6'].map(EE); + let n = 0; let fitSeen = 0; - for (let seed = 1; seed <= 1500; seed++) { + let giants = 0; + let unseenCard = 0; + for (let seed = 1; seed <= 2000; seed++) { const d = generateDraft(gd, createRng(seed * 13 + 11), 11, { stageId: 'act2autochess_m01' }); seen[d.family] = (seen[d.family] || 0) + 1; if (d.family !== 'bounty') continue; const ids = d.cards.map((c) => c.id); assert.equal(new Set(ids).size, 6); - assert.ok(hunterShape(ids), d.cards.map((c) => c.name).join(', ')); + assert.ok(ids.every((id) => CARD.get(id).draftPool === 'hunter') && onePerSeries(ids) && giantsIn(ids) <= 1, d.cards.map((c) => c.name).join(', ')); assert.match(d.eventId, /^bounty_hunter_\d+$/); - const fits = hunterFits(ids); - if (fits.length) { fitSeen++; groups[fits[0]]++; } - bounty++; + assert.ok(H.groups.some((g) => ids.filter((id) => !g.cards.includes(id)).length <= (g.open || 0)), `six cards of a seen list (+ its open card): ${d.cards.map((c) => c.name).join(', ')}`); + if (H.groups.some((g) => !g.open && subset(ids, g.cards))) fitSeen++; + if (ids.some((id) => never.includes(id))) unseenCard++; + giants += giantsIn(ids); + n++; ids.forEach((id) => offered.add(id)); } assert.deepEqual(Object.keys(seen).sort(), ['bounty', 'shop', 'tactic'], 'no 道具补给 at R11'); - assert.ok(seen.bounty > seen.shop && seen.shop > seen.tactic, JSON.stringify(seen)); - assert.ok(groups.every((x) => x > 0), `every seen group offered (${groups.join(' ')})`); - assert.ok(fitSeen / bounty > 0.17 && fitSeen / bounty < 0.4, `seen groups ${(100 * fitSeen / bounty).toFixed(0)} % of ${bounty}`); + assert.ok(seen.bounty / 2000 > 0.56 && seen.bounty / 2000 < 0.71, JSON.stringify(seen)); + assert.ok(fitSeen / n > 0.36 && fitSeen / n < 0.5, `drafts of the three whole seen groups ${(100 * fitSeen / n).toFixed(0)} % (3 / 7)`); + // a card no official draft showed: rare enough that 14 drafts without one (the official sample) stays likely + const q = unseenCard / n; + assert.ok(q > 0.02 && q < 0.1, `12_8 / 16_2 / 16_6 in ${(100 * q).toFixed(1)} % of R11 bounty drafts`); + assert.ok((1 - q) ** 14 > 0.25, `14 drafts without one: ${(100 * (1 - q) ** 14).toFixed(0)} %`); + assert.ok(giants / n > 0.78 && giants / n < 0.93, `a giant in ${(100 * giants / n).toFixed(0)} % (official 13 / 14)`); for (const c of CARDS.filter((x) => x.draftPool === 'hunter')) assert.ok(offered.has(c.effectId), `${c.effectId} ${c.name} offered at R11`); }); -test('#2 never offered by a draft (in none of the 27 official bounty drafts): multi-round cards, enemyeffect_3_*, 战术特训, the 鸭爵 set', () => { +test('#2 never offered by a draft (in none of the 59 official bounty drafts): multi-round cards, enemyeffect_3_*, 战术特训, the 鸭爵 set', () => { const reasons = {}; for (const c of CARDS) { if (!c.draft) reasons[c.draftExcluded] = (reasons[c.draftExcluded] || 0) + 1; @@ -288,7 +360,8 @@ test('#2 E2E (co-op 绝境, the players\' case): the real R3 draft is an officia assert.ok(h.drive(() => m.phase === PHASE.SP_DRAFT && m.round === 3, { ready: true }), 'the R3 draft'); assert.equal(m.sp.family, 'bounty', 'R3 of 绝境 is always a bounty draft'); const names = m.sp.cards.map((c) => c.name).join(', '); - assert.ok(initialFit(m.sp.cards.map((c) => c.id)), `seed ${seed}: ${names}`); + const ids = m.sp.cards.map((c) => c.id); + assert.ok(SPEC.initial.groups.some((g) => sameSet(g.cards, ids)) || initialRule(ids), `seed ${seed}: ${names}`); for (const c of m.sp.cards) assert.ok(!isBoss(c.enemyKey), `seed ${seed}: ${c.name} is a boss bounty`); assert.equal(m.publicView().sp.cards.length, m.sp.cards.length); // the human takes a card when its turn comes; the bot picks by itself diff --git a/test/match/feedback1-secret-shop.test.js b/test/match/feedback1-secret-shop.test.js new file mode 100644 index 00000000..71683b40 --- /dev/null +++ b/test/match/feedback1-secret-shop.test.js @@ -0,0 +1,142 @@ +// The 机密商店 after the official screenshots (the user, after the R3 / R9 / R11 screenshots of 22 official matches: +// "机密商店按官方改成可以重复吧"). The 4 official 机密商店 (R11 of matches 2, 4, 5 and 8 in +// test/fixtures/official-bounty-drafts.json) offer the same item twice (盟约之币 ×2 in 4 and 5, 变形同构体 ×2 in 8) and +// share one composition: exactly two tier-VI items, at least one tier V, at least one 盟约之币, no other tier-I / II item. +// choices.json `shopDraft` (tools/build-data.mjs SHOP_DRAFT) draws six slots on their own, with replacement, at R11 (the +// round of the screenshots; 绝境 / 终极 only); the earlier 机密商店 of 标准 / 险境 (no screenshot) keep the previous draw, +// any tier I–VI with replacement. Picking one of two identical cards is in test/content/choices.test.js (E2E), the +// overlay with two identical cards in test/ui/feedback1-secret-shop.test.js. +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { DATA } from './harness.js'; +import { GameData } from '../../server/match/gamedata.js'; +import { generateDraft, cardView } from '../../server/match/choices.js'; +import { createRng } from '../../server/sim/rng.js'; + +const OFFICIAL = JSON.parse(readFileSync(new URL('../fixtures/official-bounty-drafts.json', import.meta.url), 'utf8')); +const SHOP = DATA.choices.shopDraft; +const COIN = SHOP.coin; +const itemByName = (name) => Object.values(DATA.items).find((i) => i.name === name && !i.isGolden && i.itemType === 'EQUIP'); +/** The official 机密商店: [{ match, cards: [[name, tier]] }]. */ +const SHOPS = Object.entries(OFFICIAL.matches).flatMap(([m, rs]) => Object.values(rs).filter((d) => d.family === 'shop').map((d) => ({ match: Number(m), cards: d.cards }))); +const count = (list, pred) => list.filter(pred).length; + +test('机密商店 (4 official shops): six free items, two of them tier VI, a tier V and a 盟约之币 in each, the same item twice in three', () => { + assert.deepEqual(SHOPS.map((s) => s.match), [2, 4, 5, 8]); + assert.deepEqual(SHOP.seen, [2, 4, 5, 8]); + let dupShops = 0; + for (const { match, cards } of SHOPS) { + assert.equal(cards.length, 6, `match ${match}`); + for (const [name, tier] of cards) assert.equal(itemByName(name)?.tier, tier, `match ${match}: ${name} is tier ${tier} in the data`); + assert.equal(count(cards, ([, t]) => t === 6), 2, `match ${match}: exactly two tier-VI items`); + assert.ok(count(cards, ([, t]) => t === 5) >= 1, `match ${match}: a tier-V item`); + assert.ok(count(cards, ([n]) => n === '盟约之币') >= 1, `match ${match}: a 盟约之币`); + assert.ok(cards.every(([n, t]) => t >= 3 || n === '盟约之币'), `match ${match}: no other tier-I / II item`); + if (new Set(cards.map(([n]) => n)).size < cards.length) dupShops++; + } + assert.equal(dupShops, 3, '盟约之币 ×2 (matches 4, 5), 变形同构体 ×2 (match 8)'); + // the data: four fixed slots (VI, VI, V, 盟约之币) + two drawn by what the other two cards of each shop were + assert.equal(DATA.items[COIN].name, '盟约之币'); + assert.deepEqual(SHOP.slots.slice(0, 4), [{ 6: 1 }, { 6: 1 }, { 5: 1 }, { coin: 1 }]); + const rest = { 3: 0, 4: 0, 5: 0, coin: 0 }; + for (const { cards } of SHOPS) { + const left = cards.map(([n, t]) => (n === '盟约之币' ? 'coin' : String(t))); + for (const k of ['6', '6', '5', 'coin']) left.splice(left.indexOf(k), 1); + for (const k of left) rest[k]++; + } + assert.deepEqual(rest, { 3: 1, 4: 2, 5: 3, coin: 2 }); + for (const s of SHOP.slots.slice(4)) assert.deepEqual(s, rest); + assert.equal(SHOP.slots.length, 6); + assert.deepEqual(SHOP.rounds, [11], 'the composition where the screenshots are: R11 (绝境 / 终极)'); + // an item's weight within its tier: 1 + the official cards it showed on + const seen = {}; + for (const { cards } of SHOPS) for (const [n] of cards) if (n !== '盟约之币') seen[itemByName(n).id] = (seen[itemByName(n).id] || 0) + 1; + assert.deepEqual(SHOP.itemWeights, Object.fromEntries(Object.entries(seen).map(([id, k]) => [id, 1 + k]).sort())); + assert.equal(SHOP.itemWeights[itemByName('变形同构体').id], 5, '变形同构体 on 4 of the 8 tier-VI cards'); +}); + +test('机密商店 generated (co-op 绝境 R11): the official composition, drawn with replacement — the same item can come twice', () => { + const gd = new GameData(DATA, 'mode_multi_hard'); + let shops = 0; + let dup = 0; + let dupItem = 0; + let coins2 = 0; + const offered = new Set(); + for (let seed = 1; shops < 2000 && seed < 20000; seed++) { + const d = generateDraft(gd, createRng(seed * 104729 + 7), 11, { stageId: 'act2autochess_m01' }); + if (d.family !== 'shop') continue; + shops++; + assert.equal(d.name, '机密商店'); + assert.equal(d.cards.length, 6); + const tiers = d.cards.map((c) => DATA.items[c.id].tier); + assert.equal(count(tiers, (t) => t === 6), 2, 'two tier-VI items'); + assert.ok(count(tiers, (t) => t === 5) >= 1, 'a tier-V item'); + assert.ok(count(d.cards, (c) => c.id === COIN) >= 1, 'a 盟约之币'); + assert.ok(d.cards.every((c) => c.id === COIN || DATA.items[c.id].tier >= 3), 'no other tier-I / II item'); + assert.deepEqual(d.cards.map((c) => c.idx), [0, 1, 2, 3, 4, 5], 'each card its own index'); + for (const c of d.cards) { + assert.equal(c.kind, 'item'); + assert.equal(cardView(c).price, 0, '无需消耗资金'); + assert.ok(!DATA.items[c.id].isGolden && !DATA.items[c.id].shopExcluded); + offered.add(c.id); + } + const ids = d.cards.map((c) => c.id); + if (new Set(ids).size < ids.length) dup++; + if (new Set(ids.filter((id) => id !== COIN)).size < count(ids, (id) => id !== COIN)) dupItem++; + if (count(ids, (id) => id === COIN) >= 2) coins2++; + } + assert.equal(shops, 2000); + assert.ok(dup / shops > 0.45 && dup / shops < 0.75, `a repeated item in ${(100 * dup / shops).toFixed(0)} % (official 3 of 4)`); + assert.ok(coins2 / shops > 0.35 && coins2 / shops < 0.55, `盟约之币 ×2 in ${(100 * coins2 / shops).toFixed(0)} % (official 2 of 4)`); + assert.ok(dupItem / shops > 0.08, `another item twice in ${(100 * dupItem / shops).toFixed(0)} % (official: 变形同构体 ×2)`); + // every shop item of tiers III–VI can come + for (const t of [3, 4, 5, 6]) for (const id of gd.shopItemsByTier[t]) assert.ok(offered.has(id), `${DATA.items[id].name} (tier ${t}) offered`); + // solo: 3 of the slots + const solo = new GameData(DATA, 'mode_single_hard'); + for (let seed = 1, n = 0; n < 30 && seed < 5000; seed++) { + const d = generateDraft(solo, createRng(seed * 31 + 5), 11, {}); + if (d.family !== 'shop') continue; + n++; + assert.equal(d.cards.length, 3); + assert.ok(d.cards.every((c) => c.id === COIN || DATA.items[c.id].tier >= 3)); + } +}); + +test('机密商店 outside R11 (标准 R3 / R9, 险境 R3 / R6 / R9 — no screenshot): the previous draw, any tier I–VI per card, with replacement', () => { + // the data's shop events sit in three blocks (artifact_paid_1 by the R3 events, _2 / _3 by the R9 ones, _4 / _5 by + // hardbuff_select), so an early 机密商店 need not look like the R11 one [ASSUMED: keep the previous draw] + const all = new Set([1, 2, 3, 4, 5, 6].flatMap((t) => new GameData(DATA, 'mode_multi_funny').shopItemsByTier[t] || [])); + for (const [modeId, rounds] of [['mode_multi_funny', [3, 9]], ['mode_multi_normal', [3, 6, 9]]]) { + assert.deepEqual(DATA.choices.schedule[modeId].spRounds, rounds); + const gd = new GameData(DATA, modeId); + for (const round of rounds) { + let shops = 0; + let dup = 0; + let twoVI = 0; + let lowTier = 0; + const tiers = new Set(); + for (let seed = 1; shops < 300 && seed < 40000; seed++) { + const d = generateDraft(gd, createRng(seed * 7717 + round), round, { stageId: 'act2autochess_m01' }); + if (d.family !== 'shop') continue; + shops++; + assert.equal(d.cards.length, 6); + assert.deepEqual(d.cards.map((c) => c.idx), [0, 1, 2, 3, 4, 5]); + for (const c of d.cards) { + assert.ok(all.has(c.id), `${modeId} R${round}: ${c.name} is a normal shop item`); + assert.equal(cardView(c).price, 0); + tiers.add(DATA.items[c.id].tier); + } + const ids = d.cards.map((c) => c.id); + if (new Set(ids).size < ids.length) dup++; + if (count(ids, (id) => DATA.items[id].tier === 6) === 2) twoVI++; + if (ids.some((id) => id !== COIN && DATA.items[id].tier <= 2)) lowTier++; + } + assert.equal(shops, 300, `${modeId} R${round}`); + assert.deepEqual([...tiers].sort(), [1, 2, 3, 4, 5, 6], `${modeId} R${round}: every tier`); + assert.ok(twoVI / shops < 0.4, `${modeId} R${round}: two tier-VI items in ${(100 * twoVI / shops).toFixed(0)} % (R11: always)`); + assert.ok(lowTier / shops > 0.5, `${modeId} R${round}: a tier-I / II item besides 盟约之币 in ${(100 * lowTier / shops).toFixed(0)} %`); + assert.ok(dup / shops > 0.12 && dup / shops < 0.42, `${modeId} R${round}: a repeat in ${(100 * dup / shops).toFixed(0)} % (6 of 51, with replacement: about 26 %)`); + } + } +}); diff --git a/test/match/feedback1-tactic.test.js b/test/match/feedback1-tactic.test.js new file mode 100644 index 00000000..5b50e7e7 --- /dev/null +++ b/test/match/feedback1-tactic.test.js @@ -0,0 +1,199 @@ +// The 战术决策 after the official screenshots (the user, after the R3 / R9 / R11 screenshots of 22 official matches: +// "战术决策也按官方改成可以重复吧"). The 4 official 战术决策 (R11 of matches 7, 9, 18 and 20 in +// test/fixtures/official-bounty-drafts.json) show six cards each; match 7 offers 补给 twice, the other three six different +// cards. All 24 cards are ally cards (no 排斥 / 责罚 / 裁决 debuff, no 模拟战场演变 terrain card), and 列装 / 财富 / 补给 / +// 整备 / 升华 make half of them. choices.json `tacticDraft` (tools/build-data.mjs TACTIC_DRAFT) draws each card on its own, +// with replacement, at R11 (绝境 / 终极 only, the round of the screenshots) from the ally cards weighted 1 + the official +// cards each showed on; other rounds (标准 / 险境, no screenshot) keep every card, uniform, now with replacement too. +// Picking one of two identical cards through the match: test/content/choices.test.js (E2E); the overlay: +// test/ui/feedback1-tactic.test.js; headless Chrome: test/ui/feedback1-tactic.e2e.test.js (SP_E2E=1). +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import { DATA, makeMatch } from './harness.js'; +import { GameData } from '../../server/match/gamedata.js'; +import { generateDraft, cardView, tacticDraftCards } from '../../server/match/choices.js'; +import { botPickCard } from '../../server/match/bot.js'; +import { createRng } from '../../server/sim/rng.js'; + +const OFFICIAL = JSON.parse(readFileSync(new URL('../fixtures/official-bounty-drafts.json', import.meta.url), 'utf8')); +const SPEC = DATA.choices.tacticDraft; +const TACTIC = DATA.choices.cards.tactic; +const ALLY = TACTIC.filter((c) => c.kind === 'ally'); +const byName = (name) => TACTIC.filter((c) => c.name === name); +/** The official 战术决策: [{ match, names }]. */ +const DRAFTS = Object.entries(OFFICIAL.matches).flatMap(([m, rs]) => Object.entries(rs).filter(([, d]) => d.family === 'tactic').map(([r, d]) => ({ match: Number(m), round: Number(r), names: d.cards.map(([n]) => n) }))); +const BASIC = ['列装', '财富', '补给', '整备', '升华']; +const repeats = (ids) => ids.length - new Set(ids).size; +const count = (list, pred) => list.filter(pred).length; + +test('战术决策 (4 official drafts, R11): six ally cards each, 补给 twice in match 7, half of the cards 列装 / 财富 / 补给 / 整备 / 升华', () => { + assert.deepEqual(DRAFTS.map((d) => [d.match, d.round]), [[7, 11], [9, 11], [18, 11], [20, 11]]); + for (const { match, names } of DRAFTS) { + assert.equal(names.length, 6, `match ${match}`); + for (const n of names) { + assert.equal(byName(n).length, 1, `match ${match}: ${n} is one cards.tactic entry`); + assert.equal(byName(n)[0].kind, 'ally', `match ${match}: ${n} is an ally card`); + } + } + assert.deepEqual(DRAFTS.map((d) => repeats(d.names)), [1, 0, 0, 0], 'one repeat in four drafts'); + assert.equal(count(DRAFTS[0].names, (n) => n === '补给'), 2, 'match 7: 补给 ×2'); + const all = DRAFTS.flatMap((d) => d.names); + assert.equal(all.length, 24); + assert.equal(new Set(all).size, 14, '14 different cards'); + assert.equal(count(all, (n) => BASIC.includes(n)), 12, 'the five basic cards: 12 of 24 (a uniform draw of the 26 ally cards: about 4.6)'); + // the data: R11, ally cards, weight 1 + the official cards a card showed on + assert.deepEqual(SPEC.seen, [7, 9, 18, 20]); + assert.deepEqual(SPEC.rounds, [11], 'where the screenshots are: R11 (绝境 / 终极)'); + assert.deepEqual(SPEC.kinds, ['ally']); + assert.equal(SPEC.count, 6); + const seen = {}; + for (const n of all) seen[byName(n)[0].effectId] = (seen[byName(n)[0].effectId] || 0) + 1; + assert.deepEqual(SPEC.weights, Object.fromEntries(Object.entries(seen).map(([id, k]) => [id, 1 + k]))); + assert.equal(SPEC.weights[byName('补给')[0].effectId], 4, '补给 on 3 of the 24 cards'); + // open: every official draft holds a 驰援, a 盟誓 and two basic cards (a slot structure?) — the draws stay independent, marked + for (const { match, names } of DRAFTS) { + assert.ok(names.some((n) => n.endsWith('驰援')) && names.some((n) => n.endsWith('的盟誓')), `match ${match}: a 驰援 and a 盟誓`); + assert.ok(count(names, (n) => BASIC.includes(n)) >= 2, `match ${match}: two basic cards`); + } + assert.ok(SPEC.assumed.includes('independent draws (no slot structure)'), 'the independent draws are marked assumed'); + // the official header of the event + for (const id of ['buff_select_1', 'hardbuff_select_1']) assert.equal(DATA.choices.events[id].desc, '进行协同调整,做好迎战准备。'); + assert.equal(DATA.choices.families.tactic.desc, '进行协同调整,做好迎战准备。'); +}); + +test('战术决策 generated (co-op 绝境 / 终极 R11): six ally cards, each drawn on its own — the same card can come twice', () => { + for (const modeId of ['mode_multi_hard', 'mode_multi_abyss']) { + const gd = new GameData(DATA, modeId); + let drafts = 0; + let dup = 0; + let basic = 0; + const freq = {}; + for (let seed = 1; drafts < 2000 && seed < 40000; seed++) { + // act1 m02 is a 绝境 / 终极 stage with two terrain cards (map_m02_1 / 2): none comes at R11 + const d = generateDraft(gd, createRng(seed * 7919 + 3), 11, { stageId: 'act1autochess_m02', bondAvailable: () => true }); + if (d.family !== 'tactic') continue; + drafts++; + assert.equal(d.name, '战术决策'); + assert.equal(d.desc, '进行协同调整,做好迎战准备。'); + assert.equal(d.cards.length, 6); + assert.deepEqual(d.cards.map((c) => c.idx), [0, 1, 2, 3, 4, 5], 'each card its own index'); + assert.equal(new Set(d.cards).size, 6, 'each card its own object'); + for (const c of d.cards) { + assert.equal(c.kind, 'tactic'); + assert.equal(c.tacticKind, 'ally', `${modeId}: ${c.name} is an ally card`); + freq[c.id] = (freq[c.id] || 0) + 1; + if (BASIC.includes(c.name)) basic++; + } + if (repeats(d.cards.map((c) => c.id))) dup++; + } + assert.equal(drafts, 2000, modeId); + assert.ok(dup / drafts > 0.4 && dup / drafts < 0.7, `${modeId}: a repeated card in ${(100 * dup / drafts).toFixed(0)} % (official 1 of 4)`); + assert.ok(basic / drafts > 1.6 && basic / drafts < 2.5, `${modeId}: ${(basic / drafts).toFixed(2)} basic cards a draft (official 3; uniform 1.2)`); + for (const c of ALLY) assert.ok(freq[c.effectId] > 0, `${modeId}: ${c.name} can come`); + const of = (name) => freq[byName(name)[0].effectId]; + assert.ok(of('补给') > 2.5 * of('自愈'), `${modeId}: 补给 (weight 4) ${of('补给')} vs 自愈 (weight 1) ${of('自愈')}`); + } +}); + +test('战术决策 seeded (co-op 绝境 R11, seed 30): 补给 twice — two cards with their own index and the same face', () => { + const gd = new GameData(DATA, 'mode_multi_hard'); + const d = generateDraft(gd, createRng(30), 11, { stageId: 'act1autochess_m02' }); + assert.equal(d.family, 'tactic'); + const names = d.cards.map((c) => c.name); + const at = names.flatMap((n, i) => (n === '补给' ? [i] : [])); + assert.equal(at.length, 2, `补给 twice: ${names.join(' ')}`); + const [a, b] = at.map((i) => d.cards[i]); + assert.notEqual(a, b); + assert.notEqual(a.idx, b.idx); + const { idx: ia, ...va } = cardView(a); + const { idx: ib, ...vb } = cardView(b); + assert.deepEqual([ia, ib], at); + assert.deepEqual(va, vb, 'the same card face'); + assert.deepEqual(va, { kind: 'tactic', id: 'allybuff_select_4', name: '补给', desc: byName('补给')[0].desc, tier: null, team: true, tacticKind: 'ally' }); +}); + +test('战术决策 solo 绝境 R11: three ally cards, a repeat sometimes [ASSUMED: solo extrapolated from co-op]', () => { + const gd = new GameData(DATA, 'mode_single_hard'); + let drafts = 0; + let dup = 0; + for (let seed = 1; drafts < 1000 && seed < 40000; seed++) { + const d = generateDraft(gd, createRng(seed * 31 + 5), 11, {}); + if (d.family !== 'tactic') continue; + drafts++; + assert.equal(d.cards.length, 3); + assert.ok(d.cards.every((c) => c.tacticKind === 'ally')); + if (repeats(d.cards.map((c) => c.id))) dup++; + } + assert.equal(drafts, 1000); + assert.ok(dup / drafts > 0.05 && dup / drafts < 0.3, `a repeated card in ${(100 * dup / drafts).toFixed(0)} %`); +}); + +test('战术决策 outside R11 (标准 R3 / R9, 险境 R3 / R6 / R9, 险境 solo R9 — no screenshot): every card uniform, with replacement', () => { + for (const [modeId, rounds, stageId, cards] of [ + ['mode_multi_funny', [3, 9], 'act1autochess_m01', 6], + ['mode_multi_normal', [3, 6, 9], 'act1autochess_m02', 6], + ['mode_single_normal', [9], 'act1autochess_m02', 3], + ]) { + const gd = new GameData(DATA, modeId); + const stageTerrain = TACTIC.filter((c) => c.kind === 'terrain' && c.stageId === stageId).map((c) => c.effectId); + for (const round of rounds) { + let drafts = 0; + let dup = 0; + const kinds = new Set(); + const ids = new Set(); + for (let seed = 1; drafts < 600 && seed < 60000; seed++) { + const d = generateDraft(gd, createRng(seed * 104729 + round), round, { stageId }); + if (d.family !== 'tactic') continue; + drafts++; + assert.equal(d.cards.length, cards); + assert.deepEqual(d.cards.map((c) => c.idx), [...Array(cards).keys()]); + for (const c of d.cards) { + kinds.add(c.tacticKind); + ids.add(c.id); + if (c.tacticKind === 'terrain') assert.ok(stageTerrain.includes(c.id), `${modeId} R${round}: ${c.name} belongs to ${stageId}`); + } + if (repeats(d.cards.map((c) => c.id))) dup++; + } + assert.equal(drafts, 600, `${modeId} R${round}`); + assert.deepEqual([...kinds].sort(), ['ally', 'enemyDebuff', 'terrain'], `${modeId} R${round}: ally, debuff and the stage's terrain cards`); + for (const id of stageTerrain) assert.ok(ids.has(id), `${modeId} R${round}: ${id}`); + const [lo, hi] = cards === 6 ? [0.2, 0.5] : [0.02, 0.2]; + assert.ok(dup / drafts > lo && dup / drafts < hi, `${modeId} R${round}: a repeated card in ${(100 * dup / drafts).toFixed(0)} %`); + } + } +}); + +test('tacticDraftCards: a draw over one card fills every place; dead-bond cards never come; without tacticDraft every card is uniform', () => { + const gd = new GameData(DATA, 'mode_multi_hard'); + // a 驰援 whose bond is dead: never offered, even at R11 + const yan = byName('炎盟约驰援')[0].effectId; + for (let s = 1; s <= 300; s++) assert.ok(!tacticDraftCards(gd, createRng(s), 6, { round: 11, bondAvailable: (b) => b !== 'yanShip' }).some((c) => c.id === yan)); + // only one card left: six copies of it, six separate objects + const only = { ...DATA, choices: { ...DATA.choices, cards: { ...DATA.choices.cards, tactic: TACTIC.filter((c) => c.name === '升华') } } }; + const six = tacticDraftCards(new GameData(only, 'mode_multi_hard'), createRng(1), 6, { round: 11 }); + assert.deepEqual(six.map((c) => c.name), Array(6).fill('升华')); + assert.equal(new Set(six).size, 6); + // R11 kinds that leave nothing (a debuff-only pool): every card instead + const debuffs = { ...DATA, choices: { ...DATA.choices, cards: { ...DATA.choices.cards, tactic: TACTIC.filter((c) => c.kind === 'enemyDebuff') } } }; + assert.equal(tacticDraftCards(new GameData(debuffs, 'mode_multi_hard'), createRng(2), 6, { round: 11 }).length, 6); + // no tacticDraft (older data): every card, uniform, with replacement, at R11 too + const { tacticDraft, ...rest } = DATA.choices; // eslint-disable-line no-unused-vars + const plain = new GameData({ ...DATA, choices: rest }, 'mode_multi_hard'); + const kinds = new Set(); + for (let s = 1; s <= 200; s++) for (const c of tacticDraftCards(plain, createRng(s), 6, { round: 11 })) kinds.add(c.tacticKind); + assert.deepEqual([...kinds].sort(), ['ally', 'enemyDebuff']); +}); + +test('bot: two identical tactic cards are two choices — it takes one index, and the other once the first is gone', () => { + // the merged bot (DESIGN §21.6) scores a tactic card on the player's own bonds, so a real seat; no jitter + const m = makeMatch({ mode: 'solo', difficulty: 'HARD', seed: 7, seats: [{ seat: 0, playerId: 'ai_0', name: 'AI', isBot: true, connected: true }] }).start().m; + const ps = m.order[0]; + m.rngBots = () => 0; + const card = (idx, team) => ({ idx, kind: 'tactic', id: 'allybuff_select_4', name: '补给', team, tacticKind: 'ally' }); + const cards = [card(0, true), card(1, false), card(2, true)]; + assert.equal(botPickCard(m, ps, cards, [0, 1, 2]), 0, 'the first of the two team cards'); + assert.equal(botPickCard(m, ps, cards, [1, 2]), 2, 'the twin, once the first is taken'); + assert.equal(botPickCard(m, ps, cards, [1]), 1); + m.dispose(); +}); diff --git a/test/match/playtest6-matchflow.test.js b/test/match/playtest6-matchflow.test.js index 6dc28e9e..d42edd27 100644 --- a/test/match/playtest6-matchflow.test.js +++ b/test/match/playtest6-matchflow.test.js @@ -109,7 +109,7 @@ test('#19 a tier short of different operators: the offer tops up from the tier b // v2.4.1 drafted 战术特训 (only 法术教鞭 makes those) and the hidden 鸭爵 set, put one or more multi-round "之后 / 后续的每场 // 作战" cards in about half of the co-op R3 drafts and showed every card as plain text, so a "每场" card looked like a // "下场" one. Now: no 战术特训 / 鸭爵 set (战术特训 is the 教鞭 Art's, test/content/items.test.js); since player feedback -// #2 the drafts follow the 33 official screenshots (test/match/feedback1-bounty.test.js), where no multi-round card +// #2 the drafts follow the 66 official screenshots (test/match/feedback1-bounty.test.js), where no multi-round card // appears; each card names its battles in the official colours (blue "下场作战" / "两场作战", red "每场"); a 1–2-battle // bounty stops after its battles; a multi-round card (教鞭's 法术大师A2·多轮战术特训) lasts two battles. @@ -161,9 +161,9 @@ test('#4 data: cards.bounty marks the draft pool — 战术特训 (教鞭), the assert.equal(list.filter((c) => c.draft).length, 86); const multi = list.filter((c) => c.rounds >= 99 && c.payout === 'kill'); assert.equal(multi.length, 7, '多轮悬赏 · 假想敌 ×6 + 山海众头目·多轮悬赏'); - assert.ok(multi.every((c) => !c.draft && c.draftExcluded === 'unseen'), 'in none of the 27 official bounty drafts'); + assert.ok(multi.every((c) => !c.draft && c.draftExcluded === 'unseen'), 'in none of the 59 official bounty drafts'); const slime = list.find((c) => c.effectId === 'enemyeffect_5_1'); - assert.ok(slime.draft && slime.draftPool === 'boss', '源石虫·特训 is an R9 card (8 of the 11 official R9 drafts)'); + assert.ok(slime.draft && slime.draftPool === 'boss', '源石虫·特训 is an R9 card (16 of the 23 official R9 drafts)'); }); /** Drive a co-op 绝境 match to its R3 bounty draft; the human takes the first free card `want(card, free)` accepts. */ diff --git a/test/ui/feedback1-secret-shop.e2e.test.js b/test/ui/feedback1-secret-shop.e2e.test.js new file mode 100644 index 00000000..2acb1eb1 --- /dev/null +++ b/test/ui/feedback1-secret-shop.e2e.test.js @@ -0,0 +1,83 @@ +// The 机密商店 overlay with the same item twice, in headless Chrome (puppeteer-core + system Chrome) through the mock +// harness (public/dev/game-mock.html ?phase=SP_DRAFT&variant=shop: the official 机密商店 of match 8 R11 — 变形同构体 in +// slots 1 and 4). Opt-in: SP_E2E=1. +// +// SP_E2E=1 node --test test/ui/feedback1-secret-shop.e2e.test.js +// +// Two identical cards render as two cards; a teammate taking the first leaves the second pickable; two taps on the +// second pick it — its own index goes to the server (g.choice), only it shows my avatar. Screenshots: +// test/e2e/out/fb1-secret-shop-*.png. +import { test, describe, before, after } from 'node:test'; +import assert from 'node:assert/strict'; +import { existsSync, mkdirSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); +const OUT = path.join(ROOT, 'test/e2e/out'); +const CHROME = process.env.CHROME_PATH || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'; +const ENABLED = process.env.SP_E2E === '1' && existsSync(CHROME); +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); + +describe('机密商店: the same item twice (mock harness, headless Chrome)', { skip: !ENABLED && 'set SP_E2E=1 (and have Chrome) to run' }, () => { + let srv; + let browser; + let base; + + before(async () => { + const { startServer } = await import('../../server/index.js'); + const puppeteer = (await import('puppeteer-core')).default; + srv = await startServer({ port: 0, host: '127.0.0.1', quiet: true }); + base = `http://127.0.0.1:${srv.port}`; + browser = await puppeteer.launch({ executablePath: CHROME, headless: true, args: ['--no-sandbox'] }); + mkdirSync(OUT, { recursive: true }); + }); + + after(async () => { + await browser?.close(); + await srv?.close(); + }); + + const cards = (page) => page.$$eval('.spov__grid .spcard', (els) => els.map((c) => ({ + name: c.querySelector('.spcard__name')?.textContent, taken: c.classList.contains('is-taken'), mine: c.classList.contains('is-mine'), + armed: c.classList.contains('is-armed'), disabled: c.disabled, badge: !!c.querySelector('.spcard__taker'), + }))); + + for (const [name, w, h, touch] of [['756x366', 756, 366, true], ['1920x1080', 1920, 1080, false]]) { + test(`${name}: two 变形同构体 are two cards; the second stays pickable after the first is taken, and picking it sends its own index`, { timeout: 120000 }, async () => { + const page = await browser.newPage(); + await page.setViewport({ width: w, height: h, deviceScaleFactor: 1, isMobile: touch, hasTouch: touch }); + const problems = []; + page.on('pageerror', (e) => problems.push(`pageerror: ${e.message}`)); + page.on('console', (m) => { if (m.type() === 'error') problems.push(`console: ${m.text()}`); }); + await page.goto(`${base}/dev/game-mock.html?shot=1&phase=SP_DRAFT&variant=shop`, { waitUntil: 'networkidle0' }); + await page.waitForSelector('.spov__grid .spcard', { timeout: 20000 }); + await sleep(600); + // the teammate p4 has taken the first 变形同构体 (slot 0) + await page.evaluate(() => { const S = globalThis.__MOCK__.S(); S.pub.sp = { ...S.pub.sp, picks: { p4: 0 }, turn: 'p1' }; globalThis.__MOCK__.pushPublic(); }); + await sleep(300); + let c = await cards(page); + assert.equal(c.length, 6); + assert.equal(c[0].name, '变形同构体'); + assert.equal(c[3].name, '变形同构体'); + assert.ok(c[0].taken && c[0].badge && c[0].disabled, 'the first twin: taken, with the taker\'s avatar'); + assert.ok(!c[3].taken && !c[3].badge && !c[3].disabled, 'the second twin: free'); + await page.screenshot({ path: path.join(OUT, `fb1-secret-shop-${name}.png`) }); + // two taps on the second twin + const tap = async (i) => { const btn = (await page.$$('.spov__grid .spcard'))[i]; if (touch) await btn.tap(); else await btn.click(); await sleep(250); }; + await tap(3); + c = await cards(page); + assert.deepEqual(c.map((x) => x.armed), [false, false, false, true, false, false], 'only the tapped twin is armed'); + await page.screenshot({ path: path.join(OUT, `fb1-secret-shop-${name}-armed.png`) }); + await tap(3); + const picks = await page.evaluate(() => ({ ...globalThis.__MOCK__.S().pub.sp.picks })); + assert.deepEqual(picks, { p4: 0, p1: 3 }, 'g.choice sent the second twin\'s index'); + await sleep(250); + c = await cards(page); + assert.ok(c[3].mine && c[3].badge, 'the second twin is mine'); + assert.ok(c[0].taken && !c[0].mine, 'the first twin stays the teammate\'s'); + assert.deepEqual(problems, []); + await page.close(); + }); + } +}); diff --git a/test/ui/feedback1-secret-shop.test.js b/test/ui/feedback1-secret-shop.test.js new file mode 100644 index 00000000..e4207518 --- /dev/null +++ b/test/ui/feedback1-secret-shop.test.js @@ -0,0 +1,96 @@ +// The 机密商店 overlay with the same item twice (the user: "机密商店按官方改成可以重复吧"; official match 8 R11: 变形同构体 ×2, +// matches 4 / 5: 盟约之币 ×2). A real server draft (server/match/choices.js generateDraft → cardView), through m.public's +// normalisation (ui/gameLogic.js normalizeSp), rendered by the overlay's pure view (ui/choiceOverlay.js ChoiceView): two +// identical cards are two buttons keyed by their index — selecting one does not select the other, a teammate taking one +// leaves the other pickable, and the pick sends that card's own index. The browser render is +// test/ui/feedback1-secret-shop.e2e.test.js (SP_E2E=1). +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); + +// the browser data store reads the real data files from disk +globalThis.fetch = async (url) => { + const name = String(url).split('/').pop(); + try { + const body = readFileSync(path.join(ROOT, 'data', name), 'utf8'); + return { ok: true, status: 200, json: async () => JSON.parse(body) }; + } catch { + return { ok: false, status: 404, json: async () => ({}) }; + } +}; + +const { ChoiceView, cardPickable, spTap, armedCard } = await import('../../public/js/ui/choiceOverlay.js'); +const { normalizeSp } = await import('../../public/js/ui/gameLogic.js'); +const { DATA } = await import('../match/harness.js'); +const { GameData } = await import('../../server/match/gamedata.js'); +const { generateDraft, cardView } = await import('../../server/match/choices.js'); +const { createRng } = await import('../../server/sim/rng.js'); +const { data } = await import('../../public/js/data.js'); + +/** Every vnode of a preact tree (htm output), depth first. */ +function* walk(v) { + if (Array.isArray(v)) { for (const x of v) yield* walk(x); return; } + if (!v || typeof v !== 'object') return; + yield v; + yield* walk(v.props?.children); +} +const hasClass = (v, c) => typeof v?.props?.class === 'string' && v.props.class.split(/\s+/).includes(c); + +await data.loadAll('items', 'effects', 'choices', 'assets', 'chess', 'bonds'); + +/** A generated co-op 绝境 R11 机密商店 with the same non-coin item twice. */ +function shopWithTwin() { + const gd = new GameData(DATA, 'mode_multi_hard'); + const coin = DATA.choices.shopDraft.coin; + for (let seed = 1; seed < 50000; seed++) { + const d = generateDraft(gd, createRng(seed * 104729 + 7), 11, {}); + if (d.family !== 'shop') continue; + const ids = d.cards.map((c) => c.id); + const twin = ids.find((id, i) => id !== coin && ids.indexOf(id) !== i); + if (twin) return { d, twin, at: ids.flatMap((id, i) => (id === twin ? [i] : [])) }; + } + throw new Error('no generated shop with a repeated item'); +} + +test('机密商店 overlay: the same item twice is two cards — own keys, own selection, one taken leaves the other pickable', () => { + const { d, twin, at } = shopWithTwin(); + const [a, b] = at; + const players = [{ playerId: 'me', seat: 0, name: 'Me' }, { playerId: 'p2', seat: 1, name: 'P2' }]; + const pub = (picks) => normalizeSp({ family: 'shop', name: d.name, desc: d.desc, cards: d.cards.map(cardView), order: ['p2', 'me'], turn: Object.keys(picks).length ? 'me' : 'p2', picks, taken: {} }, players); + const view = (sp, armed = null) => [...walk(ChoiceView({ pub: { players, deadline: 0 }, sp, myId: 'me', solo: false, armed }))].filter((n) => hasClass(n, 'spcard')); + + // before any pick: six buttons, keyed by index; the twins have the same name, icon and text + let sp = pub({}); + let cards = view(sp); + assert.equal(cards.length, 6); + assert.deepEqual(cards.map((c) => c.key), [0, 1, 2, 3, 4, 5], 'keyed by index, never by item id'); + const name = (c) => [...walk(c)].find((n) => hasClass(n, 'spcard__name')).props.children; + assert.equal(name(cards[a]), DATA.items[twin].name); + assert.equal(name(cards[b]), DATA.items[twin].name); + assert.equal(sp.cards[a].id, sp.cards[b].id); + + // the teammate takes the first twin: only that card shows the taker; the second twin is still mine to pick + sp = pub({ p2: a }); + assert.equal(sp.cards[a].takenBy, 'p2'); + assert.equal(sp.cards[b].takenBy, null); + assert.equal(cardPickable(sp, sp.cards[a], { myId: 'me', solo: false }), false); + assert.equal(cardPickable(sp, sp.cards[b], { myId: 'me', solo: false }), true); + cards = view(sp); + assert.ok(hasClass(cards[a], 'is-taken') && !hasClass(cards[b], 'is-taken')); + assert.ok([...walk(cards[a])].some((n) => hasClass(n, 'spcard__taker')) && ![...walk(cards[b])].some((n) => hasClass(n, 'spcard__taker'))); + assert.equal(cards[a].props.disabled, true); + assert.equal(cards[b].props.disabled, false); + + // two taps on the second twin: it alone is armed, then its own index is sent + let r = spTap(null, b, cardPickable(sp, sp.cards[b], { myId: 'me', solo: false })); + assert.deepEqual(r, { armed: b, pick: null }); + assert.equal(armedCard(r.armed, sp, { myId: 'me', solo: false }), b); + cards = view(sp, r.armed); + assert.deepEqual(cards.map((c) => hasClass(c, 'is-armed')), cards.map((_, i) => i === b), 'only the tapped twin is armed'); + r = spTap(r.armed, b, true); + assert.deepEqual(r, { armed: null, pick: b }); +}); diff --git a/test/ui/feedback1-tactic.e2e.test.js b/test/ui/feedback1-tactic.e2e.test.js new file mode 100644 index 00000000..be3c42a7 --- /dev/null +++ b/test/ui/feedback1-tactic.e2e.test.js @@ -0,0 +1,87 @@ +// The 战术决策 overlay with the same card twice, in headless Chrome (puppeteer-core + system Chrome) through the mock +// harness (public/dev/game-mock.html ?phase=SP_DRAFT&variant=tactic: the official 战术决策 of match 7 R11 — 补给 in +// slots 1 and 2; the user: "战术决策也按官方改成可以重复吧"). Opt-in: SP_E2E=1. +// +// SP_E2E=1 node --test test/ui/feedback1-tactic.e2e.test.js +// +// Two identical cards render as two cards with the same face (name, 全队获得, text) under the official header; a +// teammate taking the first leaves the second pickable; two taps on the second pick it — its own index goes to the +// server (g.choice), only it shows my avatar. Screenshots: test/e2e/out/fb1-tactic-*.png. +import { test, describe, before, after } from 'node:test'; +import assert from 'node:assert/strict'; +import { existsSync, mkdirSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); +const OUT = path.join(ROOT, 'test/e2e/out'); +const CHROME = process.env.CHROME_PATH || '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'; +const ENABLED = process.env.SP_E2E === '1' && existsSync(CHROME); +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); + +describe('战术决策: the same card twice (mock harness, headless Chrome)', { skip: !ENABLED && 'set SP_E2E=1 (and have Chrome) to run' }, () => { + let srv; + let browser; + let base; + + before(async () => { + const { startServer } = await import('../../server/index.js'); + const puppeteer = (await import('puppeteer-core')).default; + srv = await startServer({ port: 0, host: '127.0.0.1', quiet: true }); + base = `http://127.0.0.1:${srv.port}`; + browser = await puppeteer.launch({ executablePath: CHROME, headless: true, args: ['--no-sandbox'] }); + mkdirSync(OUT, { recursive: true }); + }); + + after(async () => { + await browser?.close(); + await srv?.close(); + }); + + const cards = (page) => page.$$eval('.spov__grid .spcard', (els) => els.map((c) => ({ + name: c.querySelector('.spcard__name')?.textContent, taken: c.classList.contains('is-taken'), mine: c.classList.contains('is-mine'), + armed: c.classList.contains('is-armed'), disabled: c.disabled, badge: !!c.querySelector('.spcard__taker'), + team: !!c.querySelector('.spcard__tag--team'), desc: c.querySelector('.spcard__desc')?.textContent, w: c.getBoundingClientRect().width, + }))); + + for (const [name, w, h, touch] of [['756x366', 756, 366, true], ['1920x1080', 1920, 1080, false]]) { + test(`${name}: two 补给 are two cards; the second stays pickable after the first is taken, and picking it sends its own index`, { timeout: 120000 }, async () => { + const page = await browser.newPage(); + await page.setViewport({ width: w, height: h, deviceScaleFactor: 1, isMobile: touch, hasTouch: touch }); + const problems = []; + page.on('pageerror', (e) => problems.push(`pageerror: ${e.message}`)); + page.on('console', (m) => { if (m.type() === 'error') problems.push(`console: ${m.text()}`); }); + await page.goto(`${base}/dev/game-mock.html?shot=1&phase=SP_DRAFT&variant=tactic`, { waitUntil: 'networkidle0' }); + await page.waitForSelector('.spov__grid .spcard', { timeout: 20000 }); + await sleep(600); + const head = await page.$eval('.spov__title', (e) => e.textContent); + assert.ok(head.includes('战术决策') && head.includes('进行协同调整,做好迎战准备。'), `the official header: ${head}`); + // the teammate p4 has taken the first 补给 (slot 0) + await page.evaluate(() => { const S = globalThis.__MOCK__.S(); S.pub.sp = { ...S.pub.sp, picks: { p4: 0 }, turn: 'p1' }; globalThis.__MOCK__.pushPublic(); }); + await sleep(300); + let c = await cards(page); + assert.equal(c.length, 6); + assert.deepEqual(c.map((x) => x.name), ['补给', '补给', '谢拉格驰援', '列装', '莫斯提马的盟誓', '升华']); + assert.deepEqual([c[0].team, c[0].desc, Math.round(c[0].w)], [c[1].team, c[1].desc, Math.round(c[1].w)], 'the same face'); + assert.ok(c[0].team && /2.*次刷新/.test(c[0].desc), `补给: ${c[0].desc}`); + assert.ok(c[0].taken && c[0].badge && c[0].disabled, 'the first twin: taken, with the taker\'s avatar'); + assert.ok(!c[1].taken && !c[1].badge && !c[1].disabled, 'the second twin: free'); + await page.screenshot({ path: path.join(OUT, `fb1-tactic-${name}.png`) }); + // two taps on the second twin + const tap = async (i) => { const btn = (await page.$$('.spov__grid .spcard'))[i]; if (touch) await btn.tap(); else await btn.click(); await sleep(250); }; + await tap(1); + c = await cards(page); + assert.deepEqual(c.map((x) => x.armed), [false, true, false, false, false, false], 'only the tapped twin is armed'); + await page.screenshot({ path: path.join(OUT, `fb1-tactic-${name}-armed.png`) }); + await tap(1); + const picks = await page.evaluate(() => ({ ...globalThis.__MOCK__.S().pub.sp.picks })); + assert.deepEqual(picks, { p4: 0, p1: 1 }, 'g.choice sent the second twin\'s index'); + await sleep(250); + c = await cards(page); + assert.ok(c[1].mine && c[1].badge, 'the second twin is mine'); + assert.ok(c[0].taken && !c[0].mine, 'the first twin stays the teammate\'s'); + assert.deepEqual(problems, []); + await page.close(); + }); + } +}); diff --git a/test/ui/feedback1-tactic.test.js b/test/ui/feedback1-tactic.test.js new file mode 100644 index 00000000..4721e285 --- /dev/null +++ b/test/ui/feedback1-tactic.test.js @@ -0,0 +1,100 @@ +// The 战术决策 overlay with the same card twice (the user: "战术决策也按官方改成可以重复吧"; official match 7 R11: 补给 ×2). +// A real server draft (server/match/choices.js generateDraft → cardView; co-op 绝境 R11, seed 30: 补给 twice), through +// m.public's normalisation (ui/gameLogic.js normalizeSp), rendered by the overlay's pure view (ui/choiceOverlay.js +// ChoiceView): two identical cards are two buttons keyed by their index, with the same face (name, icon, 全队获得, text) — +// selecting one does not select the other, a teammate taking one leaves the other pickable, and the pick sends that +// card's own index. The header is the official one. The browser render is test/ui/feedback1-tactic.e2e.test.js (SP_E2E=1). +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync } from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); + +// the browser data store reads the real data files from disk +globalThis.fetch = async (url) => { + const name = String(url).split('/').pop(); + try { + const body = readFileSync(path.join(ROOT, 'data', name), 'utf8'); + return { ok: true, status: 200, json: async () => JSON.parse(body) }; + } catch { + return { ok: false, status: 404, json: async () => ({}) }; + } +}; + +const { ChoiceView, cardPickable, spTap, armedCard, resolveSpCard } = await import('../../public/js/ui/choiceOverlay.js'); +const { normalizeSp } = await import('../../public/js/ui/gameLogic.js'); +const { DATA } = await import('../match/harness.js'); +const { GameData } = await import('../../server/match/gamedata.js'); +const { generateDraft, cardView } = await import('../../server/match/choices.js'); +const { createRng } = await import('../../server/sim/rng.js'); +const { data } = await import('../../public/js/data.js'); + +/** Every vnode of a preact tree (htm output), depth first. */ +function* walk(v) { + if (Array.isArray(v)) { for (const x of v) yield* walk(x); return; } + if (!v || typeof v !== 'object') return; + yield v; + yield* walk(v.props?.children); +} +const hasClass = (v, c) => typeof v?.props?.class === 'string' && v.props.class.split(/\s+/).includes(c); +const text = (v) => [...walk(v)].flatMap((n) => (typeof n.props?.children === 'string' ? [n.props.children] : Array.isArray(n.props?.children) ? n.props.children.filter((x) => typeof x === 'string') : [])).join(''); + +await data.loadAll('items', 'effects', 'choices', 'assets', 'chess', 'bonds'); + +test('战术决策 overlay: the same card twice is two cards — own keys, same face, own selection, one taken leaves the other pickable', () => { + const d = generateDraft(new GameData(DATA, 'mode_multi_hard'), createRng(30), 11, { stageId: 'act1autochess_m02' }); + assert.equal(d.family, 'tactic'); + const at = d.cards.flatMap((c, i) => (c.name === '补给' ? [i] : [])); + assert.equal(at.length, 2, 'seed 30: 补给 twice'); + const [a, b] = at; + const players = [{ playerId: 'me', seat: 0, name: 'Me' }, { playerId: 'p2', seat: 1, name: 'P2' }]; + const pub = (picks) => normalizeSp({ family: 'tactic', name: d.name, desc: d.desc, cards: d.cards.map(cardView), order: ['p2', 'me'], turn: Object.keys(picks).length ? 'me' : 'p2', picks, taken: {} }, players); + const view = (sp, armed = null) => [...walk(ChoiceView({ pub: { players, deadline: 0 }, sp, myId: 'me', solo: false, armed }))]; + const cardsOf = (nodes) => nodes.filter((n) => hasClass(n, 'spcard')); + + // the official header + let sp = pub({}); + const all = view(sp); + assert.ok(text(all.find((n) => hasClass(n, 'spov__title'))).includes('战术决策')); + assert.equal(all.find((n) => hasClass(n, 'spov__desc')).props.children.props.text, '进行协同调整,做好迎战准备。'); + + // six buttons keyed by index; the twins have the same name, icon, team tag and text + let cards = cardsOf(all); + assert.equal(cards.length, 6); + assert.deepEqual(cards.map((c) => c.key), [0, 1, 2, 3, 4, 5], 'keyed by index, never by card id'); + const face = (c) => ({ name: [...walk(c)].find((n) => hasClass(n, 'spcard__name')).props.children, team: [...walk(c)].some((n) => hasClass(n, 'spcard__tag--team')), title: c.props.title }); + assert.deepEqual(face(cards[a]), face(cards[b])); + assert.equal(face(cards[a]).name, '补给'); + assert.equal(face(cards[a]).team, true, '全队获得'); + assert.deepEqual(resolveSpCard(sp.cards[a], 'tactic'), resolveSpCard(sp.cards[b], 'tactic')); + assert.equal(sp.cards[a].id, sp.cards[b].id); + assert.notEqual(sp.cards[a].idx, sp.cards[b].idx); + + // the teammate takes the first twin: only that card shows the taker; the second twin is still mine to pick + sp = pub({ p2: a }); + assert.equal(sp.cards[a].takenBy, 'p2'); + assert.equal(sp.cards[b].takenBy, null); + assert.equal(cardPickable(sp, sp.cards[a], { myId: 'me', solo: false }), false); + assert.equal(cardPickable(sp, sp.cards[b], { myId: 'me', solo: false }), true); + cards = cardsOf(view(sp)); + assert.ok(hasClass(cards[a], 'is-taken') && !hasClass(cards[b], 'is-taken')); + assert.ok([...walk(cards[a])].some((n) => hasClass(n, 'spcard__taker')) && ![...walk(cards[b])].some((n) => hasClass(n, 'spcard__taker'))); + assert.equal(cards[a].props.disabled, true); + assert.equal(cards[b].props.disabled, false); + + // two taps on the second twin: it alone is armed, then its own index is sent + let r = spTap(null, b, cardPickable(sp, sp.cards[b], { myId: 'me', solo: false })); + assert.deepEqual(r, { armed: b, pick: null }); + assert.equal(armedCard(r.armed, sp, { myId: 'me', solo: false }), b); + cards = cardsOf(view(sp, r.armed)); + assert.deepEqual(cards.map((c) => hasClass(c, 'is-armed')), cards.map((_, i) => i === b), 'only the tapped twin is armed'); + r = spTap(r.armed, b, true); + assert.deepEqual(r, { armed: null, pick: b }); + // after my pick: the first twin the teammate's, the second mine + sp = pub({ p2: a, me: b }); + cards = cardsOf(view(sp)); + assert.ok(hasClass(cards[b], 'is-mine') && !hasClass(cards[a], 'is-mine')); + assert.ok(cards.every((c) => c.props.disabled), 'nothing left to pick for me'); +}); diff --git a/tools/build-data.mjs b/tools/build-data.mjs index b5b9caea..1e4050d3 100644 --- a/tools/build-data.mjs +++ b/tools/build-data.mjs @@ -2400,7 +2400,7 @@ const ROMAN = { I: 1, II: 2, III: 3 }; * "※以下悬赏任务仅由法术教鞭生成" * 'hidden' 鸭爵 / 高普尼克 / 流泪小子 / 圆仔·悬赏 (enemyeffect_5..8): commented out of the table (the 鸭爵 strategy * “神秘顾客” swaps those enemies into the waves instead) - * 'unseen' kill bounties no official draft showed (33 screenshots of 11 official matches, player feedback after + * 'unseen' kill bounties no official draft showed (66 screenshots of 22 official matches, player feedback after * 0.1.0 report #2 — see BOUNTY_INITIAL_SETS below): the 7 multi-round cards ("之后 / 后续的每场作战": 山海众头目· * 多轮悬赏, 多轮悬赏·假想敌 ×6), the pre-series cards enemyeffect_3_* and the boss bounties of no seen R9 group * (凋零骑士, “遗弃者”, 锏, 扎罗, 迷路的巨像) [ASSUMED: not offered] @@ -2421,76 +2421,147 @@ function bountyDraftExclusion(e, main) { /** * The official 悬赏决策 drafts (player feedback after 0.1.0, report #2: "本来应该后期出的悬赏的怪物在前期的悬赏就出现了,导致选了 - * 打不过"), read from 33 screenshots of 11 official co-op 绝境 / 终极 matches at the start of rounds 3, 9 and 11 (collected - * by the user, 2026-10-03; the readings are test/fixtures/official-bounty-drafts.json). Every card's title, enemy and coin - * value is an act2autochess (下半) effect. A card's enemy is fixed by its effect (blackboard `enemy_id`); the title only - * names the category and tier, so 悬赏·损伤I is 底海滑动者 in enemyeffect_12_4 and 临时收音师 in enemyeffect_18_1. The draft - * of a round is one of three kinds (the event ids are the data's; which event lists which cards is server-side): - * initial R3 (enemy_initial_1..10): six "接下来两场作战" cards, always 3 × I (1 coin) + 2 × II + 1 × III. All 11 R3 - * drafts are one of 7 fixed sets (BOUNTY_INITIAL_SETS): a whole series 17 / 18 / 19 (18 in 4 matches) or one - * card from each of 6 of the series 10–15 and 20 (one such set in two matches). The 3 other events of the 10 - * are unseen: built by that rule (BOUNTY_INITIAL_MIXED) [ASSUMED]. - * boss R9 (bossInitial_1..6): the boss bounties "X·悬赏" and 源石虫·特训, all "下场作战". All 12 drafts (11 matches + - * the Bahamut 12294 co-op screenshot) are a group of 0–3 named bosses that always come together, filled up to 6 - * with cheap ones (W / 碎骨 / 弑君者 1, 大鲍勃 2, 庞贝 or 鼠王 2, 源石虫·特训 0): BOUNTY_BOSS_TEMPLATES. 7 groups - * were seen for 6 events (庞贝 and 鼠王 never in one draft; 杰斯顿 only in matches 7–11): two game versions, - * or a group set by something of the match (its leader, its map — the 杰斯顿 groups came on both boards) — - * open; uniform among the seen groups [ASSUMED]. 凋零骑士, “遗弃者”, 锏, 扎罗 and 迷路的巨像 never appeared: not - * offered [ASSUMED]. - * hunter R11 (bounty_hunter_1..15; R11 is a 悬赏决策 in 5 of the 11 matches): six "下场战斗" cards, exactly one 特异III - * giant (enemyeffect_16_1..8, 3 coins), the others tier II / I faction _7 / _8 cards and enemyeffect_16_9..12, - * at most one per faction series 10–15 (5 of 5 drafts). Not a free draw within that rule: matches 1 and 6 - * show the same giant (16_4) and the same four tier-II cards (16_10 15_7 12_7 13_8) and differ only in their - * one tier-I card (10_7 / 11_7); 15_7 + 13_8 come together in matches 1, 3 and 6; 10_8, 11_8 and 12_8 never - * show (a uniform draw under the rule gives some pair of 5 drafts 5 shared cards in about 2.5 % of samples). - * Like R9, a draft is a group — the giant + 1–4 tier-II cards, always together — filled to 6 with tier-I - * cards: BOUNTY_HUNTER_TEMPLATES, 4 groups seen for the 15 events (fill = the 5 tier-I cards seen); an unseen - * event draws a group of that shape over all the R11 cards (BOUNTY_HUNTER) [ASSUMED: the group / fill split - * by tier, uniform among the 15 events]. The fill cards 16_11 and 13_7 only came in matches 10–11 (the - * 杰斯顿 period of R9) — too few drafts to split the fill by period. - * In none of the 27 bounty drafts: the 7 multi-round cards (山海众头目·多轮悬赏, 多轮悬赏·假想敌 ×6), the pre-series cards + * 打不过"), read from 66 screenshots of 22 official co-op 绝境 / 终极 matches at the start of rounds 3, 9 and 11 (collected + * by the user, 2026-10-03, from videos of this season recorded at the end of March 2026; the readings are + * test/fixtures/official-bounty-drafts.json, `seen` below = its match numbers). Every card's title, enemy and coin value is + * an act2autochess (下半) effect. A card's enemy is fixed by its effect (blackboard `enemy_id`); the title only names the + * category and tier, so 悬赏·损伤I is 底海滑动者 in enemyeffect_12_4 and 临时收音师 in enemyeffect_18_1. The players pick + * in turn from ONE shared draft (a taken card stays greyed with the taker's avatar: match 17 R3, match 21 R9). + * + * One rule covers all three rounds: the draft's event is a fixed list of cards, and the draft shows 6 different cards of + * it (positions shuffled): R3 lists hold 6 cards (all shown), R9 lists up to 9 (every R9 group seen in 3 or more drafts — + * and only those — shows exactly 9 different cards: 鼠王 group, 喷气人 group, 复仇者 group), R11 lists 7 (the three R11 groups + * seen in 2–4 drafts show exactly 7: matches 1 / 6 / 21 / 22 each leave out a different one of the same 7 cards). Within a + * list a card is drawn with weight 1 + the drafts of its group it appeared in (`hits`; a card no draft of the group has + * shown yet, 1) [ASSUMED: smooths the official counts — in the 鼠王 group 鼠王 showed in 4 of 14, 杰斯顿 in 12]. + * initial R3 (enemy_initial_1..10): six "接下来两场作战" cards, always 3 × I (1 coin) + 2 × II + 1 × III (22 of 22). + * 9 of the 10 fixed sets seen (BOUNTY_INITIAL_SETS: 18 ×5, 19 / the 10_5 set / the 17_6 set ×3, 17 / two more + * ×2, two ×1 — consistent with a uniform pick among 10). Hand-made: a set can hold two series-20 cards (12) or + * one card of series 17 (13 / 19 / 21). The unseen 10th set: BOUNTY_INITIAL_RULE [ASSUMED] — its III is one of + * the only two two-battle cards no draft showed (法术大师A1 10_6, 鼎沸 20_6). + * boss R9 (bossInitial_1..6): the boss bounties "X·悬赏" and 源石虫·特训 (16 of 22), all "下场作战". Six groups, one + * per event (BOUNTY_BOSS_GROUPS); 庞贝 and 鼠王 are never in one draft. The 鼠王 group (W 碎骨 弑君者 大鲍勃 源石虫 + * 鼠王 杰斯顿 “自在” 陷落雪祀) came in 14 of the 22 matches, so the event is not picked uniformly: something of + * the match decides — every match on the dark grey board (7) had it (if independent of the board, 2 %); the + * leader, the map or the difficulty (终极 opened 2026-03-27) are candidates. Picked by the matches each group + * came in [ASSUMED]. A named boss does not always come with its partners (杰斯顿 alone in 12 / 15 / 21, 复仇者 + * and 萨卡兹百夫长 without 邪魔的利刃 in 20). The groups hold 9, 9, 9, 9, 8 and 6 cards: the three seen in 3 or + * more drafts show 9 (the 庞贝 / 鼠王 base of 6 + three named bosses); the three single-draft groups are + * completed only with the base cards they lack [ASSUMED] — 腐败骑士 group 9, 泥岩 + 澪 group 8, and match 4 + * (the base alone) 6, so that one always shows the same six. Match 4 may instead be a draft of another group + * (most likely the 泥岩 group: 1 in 28 for a uniform 6 of 8), leaving one event unseen — open. + * 凋零骑士, “遗弃者”, 锏, 扎罗 and 迷路的巨像 never appeared: not offered [ASSUMED]. + * hunter R11 (R11 is a 悬赏决策 in 14 of the 22 matches): six "下场战斗" cards, the faction _7 / _8 cards and series 16 + * (16_1..8 the 特异III giants), at most one per faction series 10–15 (14 of 14). 7 groups seen + * (BOUNTY_HUNTER_GROUPS): three complete (7 cards), four with 6 cards seen and a 7th drawn by the rule (`open`; + * the group of match 15 shows no giant, so its 7th is one). The list is one of these 7, uniform [ASSUMED], + * because that invents no list. The data does not say which of the 15 events bounty_hunter_1..15 R11 fires: + * in effectChoiceInfoDict bounty_hunter_1..7 sit after bossInitial_1..6, and bounty_hunter_8..15 sit after + * artifact_paid_4 / 5 and right before hardbuff_select (the tactic event only 绝境 / 终极 have, the modes + * with an R11) — read by blocks, as SHOP_DRAFT reads the shop events, R11 would be the 8 events 8..15. The + * sample fits 7, 8 or 9 events about equally (14 drafts showing exactly 7 lists: 7 events 37 %, 8 events + * 45 %, 9 events 39 %) but not 15 (7 lists or fewer 6 %); the counts 4 / 2 / 3 / 1 / 2 / 1 / 1 fit a uniform + * pick (χ² = 4, 6 df). With 8 events, a list nobody has seen would come in about 1 R11 bounty draft in 8 — + * open. No list is built from nothing: the R11 cards no draft showed (12_8 异光体孽生者, 16_2 “越长尘”, 16_6 + * 高准度伦蒂尼姆城防自行炮) come only as an `open` card (BOUNTY_HUNTER_RULE: one giant for a list without one, + * else tier I / II cards of the free faction series, at most two of 16_9..12), in about 1 R11 bounty draft in + * 15. + * In none of the 59 bounty drafts: the 7 multi-round cards (山海众头目·多轮悬赏, 多轮悬赏·假想敌 ×6), the pre-series cards * enemyeffect_3_* (法术大师A2·悬赏 …), 战术特训 (法术教鞭 only) and the 鸭爵 set; no card twice in one draft. */ const EE = (s) => `enemyeffect_${s}`; const seriesIds = (n) => [1, 2, 3, 4, 5, 6].map((i) => EE(`${n}_${i}`)); -/** The R3 sets seen (`seen` = match numbers of test/fixtures/official-bounty-drafts.json). */ +/** The R3 sets seen. */ const BOUNTY_INITIAL_SETS = [ - { cards: seriesIds(18), seen: [1, 3, 5, 9] }, - { cards: seriesIds(19), seen: [2] }, - { cards: seriesIds(17), seen: [7] }, - { cards: ['10_5', '11_4', '12_5', '13_6', '15_4', '20_3'].map(EE), seen: [4, 10] }, - { cards: ['10_4', '11_5', '12_6', '14_4', '15_5', '20_2'].map(EE), seen: [6] }, + { cards: seriesIds(18), seen: [1, 3, 5, 9, 17] }, + { cards: seriesIds(19), seen: [2, 15, 22] }, + { cards: seriesIds(17), seen: [7, 14] }, + { cards: ['10_5', '11_4', '12_5', '13_6', '15_4', '20_3'].map(EE), seen: [4, 10, 16] }, + { cards: ['10_4', '11_5', '12_6', '14_4', '15_5', '20_2'].map(EE), seen: [6, 18] }, { cards: ['10_4', '11_5', '12_4', '14_6', '15_4', '20_4'].map(EE), seen: [8] }, - { cards: ['10_4', '11_6', '12_4', '13_4', '14_5', '15_5'].map(EE), seen: [11] }, -]; -/** An unseen R3 set: one card from each of `count` of these series, with these tiers (the seen mixed sets' rule). */ -const BOUNTY_INITIAL_MIXED = { series: [10, 11, 12, 13, 14, 15, 20], count: 6, tiers: [1, 1, 1, 2, 2, 3] }; -const BOSS_FILL_A = ['b_1', 'b_3', 'b_10', 'b_12', 'b_13', '5_1'].map(EE); // 碎骨 弑君者 W 庞贝 大鲍勃 源石虫·特训 -const BOSS_FILL_B = ['b_1', 'b_3', 'b_10', 'b_11', 'b_13', '5_1'].map(EE); // 鼠王 in place of 庞贝 -/** The R9 groups seen: `featured` always all on the card row, `fill` drawn to make 6. */ -const BOUNTY_BOSS_TEMPLATES = [ - { featured: [], fill: BOSS_FILL_A, seen: [4] }, - { featured: ['b_8', 'b_24'].map(EE), fill: BOSS_FILL_A, seen: [1, 5] }, // 喷气人 纠缠藤蔓 - { featured: ['b_4', 'b_19'].map(EE), fill: BOSS_FILL_A, seen: [2] }, // 泥岩 澪 - { featured: ['b_5', 'b_17', 'b_20'].map(EE), fill: BOSS_FILL_A, seen: [3] }, // 腐败骑士 “墓碑” “巨大的丑东西” - { featured: ['b_22', 'b_21', 'b_2'].map(EE), fill: BOSS_FILL_A, seen: [6, 'bahamut-12294'] }, // “邪魔的利刃” “复仇者” 萨卡兹百夫长 - { featured: ['b_9', 'b_23'].map(EE), fill: BOSS_FILL_B, seen: [7, 11] }, // 杰斯顿·威廉姆斯 陷落雪祀 - { featured: ['b_9', 'b_14'].map(EE), fill: BOSS_FILL_B, seen: [8, 9, 10] }, // 杰斯顿·威廉姆斯 “自在” -]; -const HUNTER_FILL = ['10_7', '11_7', '13_7', '14_7', '16_11'].map(EE); // 法术大师A2 沏虹 假想敌:蚀裂 重弩突袭者 心虚设计师 -/** The R11 groups seen: `featured` (the 特异III giant + its tier-II cards) always all on the card row, `fill` (tier I) drawn to make 6. */ -const BOUNTY_HUNTER_TEMPLATES = [ - { featured: ['16_4', '16_10', '15_7', '12_7', '13_8'].map(EE), fill: HUNTER_FILL, seen: [1, 6] }, // 温顺的武装大驮兽 异质裂兽·α 深池重甲卫士队长 灼藤 尖端萨卡兹枯朽战车 - { featured: ['16_3', '15_7', '13_8'].map(EE), fill: HUNTER_FILL, seen: [3] }, // 狂暴宿主组长 深池重甲卫士队长 尖端萨卡兹枯朽战车 - { featured: ['16_5', '14_8', '12_7', '15_8'].map(EE), fill: HUNTER_FILL, seen: [10] }, // 萨卡兹骸骨拷打者 家族暗影灭迹人 灼藤 愤怒的守墓石像 - { featured: ['16_7', '16_9'].map(EE), fill: HUNTER_FILL, seen: [11] }, // 乌顶巨角卢鲁 拥霜羽兽 + { cards: ['10_4', '11_6', '12_4', '13_4', '14_5', '15_5'].map(EE), seen: [11, 20] }, + { cards: ['10_4', '11_4', '12_5', '15_6', '20_1', '20_5'].map(EE), seen: [12] }, + { cards: ['11_4', '12_4', '13_5', '14_4', '15_5', '17_6'].map(EE), seen: [13, 19, 21] }, ]; /** - * An unseen R11 group (the seen groups' shape): one tier-III giant + `groupSizes` (one drawn: the seen 4 / 2 / 3 / 1) - * tier-II cards, filled with tier-I cards, at most one card per series of `onePerSeries` — over the R11 cards by tier - * (buildChoices). [ASSUMED] + * The unseen R3 set [ASSUMED]: six two-battle cards of these series with the seen sets' tiers, at most `perSeries` of one + * series (the 20_1 / 20_5 set has two), its tier-III card one of `prefer` (the two-battle cards no draft showed). */ -const BOUNTY_HUNTER = { groupSizes: [1, 2, 3, 4], onePerSeries: [10, 11, 12, 13, 14, 15], count: 6 }; +const BOUNTY_INITIAL_RULE = { series: [10, 11, 12, 13, 14, 15, 20], tiers: [1, 1, 1, 2, 2, 3], perSeries: 2, prefer: ['10_6', '20_6'].map(EE) }; +// R9 cards by name (enemyeffect_b_N, 源石虫·特训 enemyeffect_5_1) +const R9 = { + W: 'b_10', 碎骨: 'b_1', 弑君者: 'b_3', 大鲍勃: 'b_13', 庞贝: 'b_12', 鼠王: 'b_11', 源石虫: '5_1', 杰斯顿: 'b_9', 自在: 'b_14', 陷落雪祀: 'b_23', + 喷气人: 'b_8', 纠缠藤蔓: 'b_24', 澪: 'b_19', 邪魔的利刃: 'b_22', 复仇者: 'b_21', 萨卡兹百夫长: 'b_2', 腐败骑士: 'b_5', 墓碑: 'b_17', 巨大的丑东西: 'b_20', 泥岩: 'b_4', +}; +/** A group from [name, hits] pairs (hits = the drafts of the group the card appeared in). */ +const r9Group = (pairs, seen) => ({ cards: pairs.map(([n]) => EE(R9[n])), hits: pairs.map(([, h]) => h), seen }); +/** The R9 groups (one per bossInitial event), picked by the matches they came in. */ +const BOUNTY_BOSS_GROUPS = [ + r9Group([['W', 11], ['碎骨', 12], ['弑君者', 11], ['大鲍勃', 11], ['源石虫', 10], ['鼠王', 4], ['杰斯顿', 12], ['自在', 7], ['陷落雪祀', 6]], [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21]), + r9Group([['W', 3], ['碎骨', 1], ['弑君者', 1], ['大鲍勃', 3], ['庞贝', 1], ['源石虫', 2], ['喷气人', 3], ['纠缠藤蔓', 3], ['澪', 1]], [1, 5, 22]), + r9Group([['W', 3], ['碎骨', 2], ['弑君者', 1], ['庞贝', 2], ['源石虫', 1], ['澪', 1], ['邪魔的利刃', 2], ['复仇者', 3], ['萨卡兹百夫长', 3]], [6, 20, 'bahamut-12294']), + r9Group([['W', 1], ['碎骨', 1], ['弑君者', 0], ['大鲍勃', 0], ['庞贝', 0], ['源石虫', 1], ['腐败骑士', 1], ['墓碑', 1], ['巨大的丑东西', 1]], [3]), + r9Group([['W', 0], ['碎骨', 0], ['弑君者', 1], ['大鲍勃', 1], ['庞贝', 1], ['源石虫', 1], ['泥岩', 1], ['澪', 1]], [2]), + r9Group([['W', 1], ['碎骨', 1], ['弑君者', 1], ['大鲍勃', 1], ['庞贝', 1], ['源石虫', 1]], [4]), +]; +/** The R11 groups seen: 7 cards, or 6 + `open` cards drawn by BOUNTY_HUNTER_RULE. */ +const hunterGroup = (ids, hits, seen, open = 0) => ({ cards: ids.map(EE), hits, seen, ...(open ? { open } : {}) }); +const BOUNTY_HUNTER_GROUPS = [ + hunterGroup(['16_4', '16_10', '15_7', '12_7', '13_8', '10_7', '11_7'], [4, 4, 3, 3, 4, 3, 3], [1, 6, 21, 22]), // 温顺的武装大驮兽 … + hunterGroup(['16_3', '15_7', '13_8', '16_9', '14_7', '11_7', '10_7'], [2, 2, 2, 1, 2, 2, 1], [3, 13]), // 狂暴宿主组长 … + hunterGroup(['16_5', '15_8', '12_7', '14_8', '10_7', '16_11', '11_7'], [3, 3, 3, 2, 3, 3, 1], [10, 12, 16]), // 萨卡兹骸骨拷打者 … + hunterGroup(['16_7', '16_9', '14_7', '16_11', '11_7', '13_7'], [1, 1, 1, 1, 1, 1], [11], 1), // 乌顶巨角卢鲁 … + hunterGroup(['16_8', '16_10', '14_8', '10_7', '16_12', '13_7'], [2, 2, 2, 2, 2, 2], [14, 19], 1), // 伊利昂的木驮兽 … + hunterGroup(['16_1', '10_8', '11_8', '15_7', '13_7', '14_7'], [1, 1, 1, 1, 1, 1], [17], 1), // 泥岩巨像 … + hunterGroup(['10_8', '12_7', '13_7', '14_7', '11_7', '16_12'], [1, 1, 1, 1, 1, 1], [15], 1), // no giant seen (枯朽萃聚使徒 …) +]; +/** + * The `open` card of a seen R11 list [ASSUMED]: up to `size` cards — one tier-III giant (a list without one gets one) + + * tier I / II cards, at most one per series of `onePerSeries` and `maxSeries16` of 16_9..12 — over the R11 cards by tier + * (buildChoices). + */ +const BOUNTY_HUNTER_RULE = { size: 7, onePerSeries: [10, 11, 12, 13, 14, 15], maxSeries16: 2 }; +/** + * The official 机密商店 (R11 of matches 2, 4, 5 and 8; the user: "机密商店按官方改成可以重复吧"): six item cards, free, and + * the same item can be offered twice (盟约之币 ×2 in 4 and 5, 变形同构体 ×2 in 8). Every one of the 4 has exactly two tier-VI + * items, at least one tier V and at least one 盟约之币 — never a tier-I / II item besides 盟约之币; the other two cards came + * out V ×3, IV ×2, III ×1, 盟约之币 ×2. So: six slots, each drawn on its own (with replacement) — VI, VI, V, 盟约之币 and + * twice a pick of V 3 / IV 2 / III 1 / 盟约之币 2 [ASSUMED: the slot split]; an item within its tier with weight 1 + the + * official 机密商店 cards it showed on (`seen`: 变形同构体 on 4 of the 8 tier-VI cards) [ASSUMED]. Solo shows 3 of the 6 + * [ASSUMED]. Only at R11 (`rounds`; R11 is 绝境 / 终极 only, the rounds of the screenshots): the 机密商店 of 标准 R3 / R9 + * and 险境 R3 / R6 / R9 has no screenshot, and the data's shop events sit in three blocks (artifact_paid_1 by the R3 + * events, _2 / _3 by bossInitial / bounty_hunter_1..7, _4 / _5 by bounty_hunter_8..15 and hardbuff_select — the same + * block reading leaves open which hunter events R11 fires, see `hunter` above), so those keep the previous draw — + * any normal shop item of tiers I–VI per card, with replacement (the same item can come twice there too) [ASSUMED]. + */ +const SHOP_DRAFT = { + rounds: [11], + slots: [{ 6: 1 }, { 6: 1 }, { 5: 1 }, { coin: 1 }, { 5: 3, 4: 2, 3: 1, coin: 2 }, { 5: 3, 4: 2, 3: 1, coin: 2 }], + coin: '盟约之币', + seen: { 变形同构体: 4, 天师古鼎: 1, 人事部文档: 1, 家族徽章: 1, 铳骑之威: 1, 天马之盔: 2, 双模机械臂: 2, 商业包装方案: 2, 博士投影: 1, 护盾无人机: 1, 寻呼模块: 1, 骑士储蓄罐: 1, 盟约之币: 6 }, + matches: [2, 4, 5, 8], +}; +/** + * The official 战术决策 (R11 of matches 7, 9, 18 and 20; the user: "战术决策也按官方改成可以重复吧"): six cards, and the same + * card can be offered twice (补给 ×2 in match 7; the other three show six different cards). All 24 cards are ally cards + * (allybuff_select_*: 盟誓, 驰援, 列装 / 财富 / 补给 / 整备 / 升华, 锐利): no 排斥 / 责罚 / 裁决 debuff (four drafts without + * one: about 0.04 % for the previous draw, 6 different cards of the 26 ally + 9 debuff cards) and no 模拟战场演变 terrain + * card. 列装 / 财富 / 补给 / 整备 / 升华 made 12 of the 24 cards (a uniform draw of the 26 ally cards: about 0.07 %), so + * the draw is weighted. At R11 (`rounds`; 绝境 / 终极 only, the round of the screenshots): each card drawn on its own (with + * replacement) from the ally cards (`kinds`), weight 1 + the official cards it showed on (`seen`) [ASSUMED: the weights; + * terrain cards left out — the maps of the 4 matches are unknown]; solo shows 3 [ASSUMED]. Other rounds (标准 / 险境, no + * screenshot) keep every card, uniform, terrain cards only for the match stage — with replacement too [ASSUMED]. + * Open: a slot structure like SHOP_DRAFT's. Every one of the 4 drafts has at least one 驰援, at least one 盟誓 and at least + * two of 列装 / 财富 / 补给 / 整备 / 升华; under these independent draws a draft has 驰援 + 盟誓 about 70 % of the time (all + * four: about 24 %) and all three about 41 % (all four: about 3 %). The pattern was spotted after the fact, so it is kept as + * a question rather than slots [ASSUMED: independent draws]; more R11 战术决策 screenshots would settle it. + */ +const TACTIC_DRAFT = { + rounds: [11], + kinds: ['ally'], + seen: { 补给: 3, 列装: 3, 升华: 3, 莫斯提马的盟誓: 2, 银灰的盟誓: 2, 阿戈尔驰援: 2, 财富: 2, 谢拉格驰援: 1, 锐利: 1, 整备: 1, 玛恩纳的盟誓: 1, 斯卡蒂的盟誓: 1, 萨尔贡驰援: 1, 叙拉古驰援: 1 }, + matches: [7, 9, 18, 20], +}; /** The kind of a round's 悬赏决策: R3 (and 险境 R6, [ASSUMED]) initial, R9 boss, R11 hunter. */ const bountyDraftOf = (r) => (r < 8 ? 'initial' : r < 11 ? 'boss' : 'hunter'); @@ -2555,8 +2626,8 @@ function buildChoices(ctx, effects, items, chess) { let draftExcluded = bountyDraftExclusion(e, main); if (draftExcluded === 'hidden' && !/鸭爵|高普尼克|流泪小子|圆仔/.test(e.name || '')) warn(`bounty ${e.effectId} "${e.name}": expected one of the 鸭爵 set`); let draftPool = bountyDraftPool(e, main, draftExcluded); - // a boss bounty is offered only through a seen R9 group (BOUNTY_BOSS_TEMPLATES) - if (draftPool === 'boss' && !BOUNTY_BOSS_TEMPLATES.some((t) => t.featured.includes(e.effectId) || t.fill.includes(e.effectId))) draftPool = null; + // a boss bounty is offered only through a seen R9 group (BOUNTY_BOSS_GROUPS) + if (draftPool === 'boss' && !BOUNTY_BOSS_GROUPS.some((g) => g.cards.includes(e.effectId))) draftPool = null; if (!draftExcluded && !draftPool) draftExcluded = 'unseen'; const sm = /^enemyeffect_(\d+)_\d+$/.exec(e.effectId); bounty.push({ @@ -2570,16 +2641,21 @@ function buildChoices(ctx, effects, items, chess) { const bountyById = new Map(bounty.map((c) => [c.effectId, c])); const checkKind = (ids, kind, what) => { for (const id of ids) if (bountyById.get(id)?.draftPool !== kind) warn(`bounty draft ${what}: ${id} is not a "${kind}" card`); }; for (const s of BOUNTY_INITIAL_SETS) checkKind(s.cards, 'initial', 'R3 set'); - for (const t of BOUNTY_BOSS_TEMPLATES) checkKind([...t.featured, ...t.fill], 'boss', 'R9 group'); - for (const t of BOUNTY_HUNTER_TEMPLATES) { - checkKind([...t.featured, ...t.fill], 'hunter', 'R11 group'); - const tiers = t.featured.map((id) => bountyById.get(id)?.tier); - if (tiers.filter((x) => x === 3).length !== 1 || tiers.some((x) => x !== 3 && x !== 2)) warn(`bounty draft R11 group ${t.featured.join(' ')}: not one giant + tier-II cards`); - if (t.fill.some((id) => bountyById.get(id)?.tier !== 1)) warn(`bounty draft R11 group ${t.featured.join(' ')}: a fill card is not tier I`); + for (const g of BOUNTY_BOSS_GROUPS) checkKind(g.cards, 'boss', 'R9 group'); + for (const g of BOUNTY_HUNTER_GROUPS) checkKind(g.cards, 'hunter', 'R11 group'); + for (const g of [...BOUNTY_INITIAL_SETS, ...BOUNTY_BOSS_GROUPS, ...BOUNTY_HUNTER_GROUPS]) { + if (new Set(g.cards).size !== g.cards.length) warn(`bounty draft group ${g.cards.join(' ')}: a card twice`); + if (g.hits && g.hits.length !== g.cards.length) warn(`bounty draft group ${g.cards.join(' ')}: hits do not match the cards`); } - // the unseen R11 groups draw over the R11 cards by tier: III the giants, II the group cards, I the fill + for (const s of BOUNTY_INITIAL_SETS) if (s.cards.map((id) => bountyById.get(id)?.tier).sort().join('') !== '111223') warn(`bounty draft R3 set ${s.cards.join(' ')}: not I I I II II III`); + for (const g of BOUNTY_HUNTER_GROUPS) { + const giants = g.cards.filter((id) => bountyById.get(id)?.tier === 3).length; + if (giants > 1 || g.cards.length + (g.open || 0) !== BOUNTY_HUNTER_RULE.size) warn(`bounty draft R11 group ${g.cards.join(' ')}: not ${BOUNTY_HUNTER_RULE.size} cards with at most one giant`); + } + // the R11 rule draws over the R11 cards by tier: III the giants, II / I the rest const hunterTier = (t) => bounty.filter((c) => c.draftPool === 'hunter' && c.tier === t).map((c) => c.effectId); if (hunterTier(1).length + hunterTier(2).length + hunterTier(3).length !== bounty.filter((c) => c.draftPool === 'hunter').length) warn('bounty: an R11 card of no tier I–III'); + const withWeights = ({ hits, ...g }) => ({ ...g, weights: hits.map((h) => h + 1) }); // Tactic cards (BUFF_GAIN effects). const tactic = []; @@ -2592,6 +2668,13 @@ function buildChoices(ctx, effects, items, chess) { tactic.push({ effectId: e.effectId, name: e.name, desc: e.desc, kind, stageId, team }); } tactic.sort((a, b) => naturalCmp(a.effectId, b.effectId)); + // the official 战术决策 (TACTIC_DRAFT) names cards of its `kinds` only + const tacticByName = (name) => { + const hits = tactic.filter((c) => c.name === name); + if (hits.length !== 1) warn(`tactic draft card "${name}": ${hits.length} cards of that name`); + if (hits[0] && !TACTIC_DRAFT.kinds.includes(hits[0].kind)) warn(`tactic draft card "${name}" is a ${hits[0].kind} card`); + return hits[0]?.effectId ?? null; + }; const equipNormal = Object.values(items).filter((i) => i.itemType === 'EQUIP' && !i.isGolden); const itemByName = (name) => equipNormal.find((i) => i.name === name)?.id || (warn(`pool item "${name}" not found`), null); @@ -2613,11 +2696,11 @@ function buildChoices(ctx, effects, items, chess) { let families; if (diff === 'TRAINING') families = [{ family: 'supply', weight: 100 }]; else if (diff === 'HARD' || diff === 'ABYSS') { - // R11 of the 11 official co-op matches (player feedback after 0.1.0 report #2, the screenshots of BOUNTY_INITIAL_SETS): - // 悬赏决策 5, 机密商店 4, 战术决策 2, 道具补给 0 — the weights follow those counts [ASSUMED]. Solo 绝境 / 终极 take the + // R11 of the 22 official co-op matches (player feedback after 0.1.0 report #2, the screenshots of BOUNTY_INITIAL_SETS): + // 悬赏决策 14, 机密商店 4, 战术决策 4, 道具补给 0 — the weights are those counts [ASSUMED]. Solo 绝境 / 终极 take the // same weights [ASSUMED: no solo screenshot; extrapolated from co-op — the data has solo 悬赏决策 events for R11, // bounty_hunter_*_s, which the previous supply 50 / shop 50 never used] - families = r === 11 ? [{ family: 'bounty', weight: 45 }, { family: 'shop', weight: 35 }, { family: 'tactic', weight: 20 }] : [{ family: 'bounty', weight: 100 }]; + families = r === 11 ? [{ family: 'bounty', weight: 14 }, { family: 'shop', weight: 4 }, { family: 'tactic', weight: 4 }] : [{ family: 'bounty', weight: 100 }]; } else if (diff === 'NORMAL') { families = solo ? [{ family: r === 9 ? 'tactic' : 'supply', weight: 100 }] @@ -2643,10 +2726,11 @@ function buildChoices(ctx, effects, items, chess) { return { events, families: { - bounty: { name: '悬赏决策', desc: '选定悬赏目标,获取额外奖励。', cards: 'bountyDrafts[schedule[*].bountyDraft] — the official draft structure of the round (initial: one of the R3 sets; boss: an R9 group + cheap fill; hunter: an R11 group — one 特异III giant + tier-II cards — + tier-I fill, one per faction series), over cards.bounty entries with draft: true and that draftPool' }, + bounty: { name: '悬赏决策', desc: '选定悬赏目标,获取额外奖励。', cards: 'bountyDrafts[schedule[*].bountyDraft] — one official card list of the round (initial: an R3 set of 6; boss: an R9 group of up to 9; hunter: one of the 7 seen R11 lists of 7), six different cards of it drawn by weight, over cards.bounty entries with draft: true and that draftPool' }, supply: { name: '道具补给', desc: '无需消耗资金,获得装备补给。', cards: 'random normal EQUIP items in schedule[*].supplyTiers (duplicates allowed)' }, - shop: { name: '机密商店', desc: '无需消耗资金,获得装备补给。', cards: 'random normal EQUIP items of any tier I–VI (duplicates allowed)' }, - tactic: { name: '战术决策', desc: '选择战术增益。', cards: 'cards.tactic (terrain cards only for the match stage)' }, + shop: { name: '机密商店', desc: '无需消耗资金,获得装备补给。', cards: 'at shopDraft.rounds (R11): six slots drawn with replacement (VI, VI, V, 盟约之币, 2 × V / IV / III / 盟约之币); other rounds: random normal EQUIP shop items of tiers I–VI (duplicates allowed) — the same item can come twice' }, + // desc = the official header (effectChoiceInfoDict buff_select_* / hardbuff_select_* "进行协同调整,做好迎战准备。") + tactic: { name: '战术决策', desc: '进行协同调整,做好迎战准备。', cards: 'cards.tactic, each card drawn on its own (with replacement) — the same card can come twice; at tacticDraft.rounds (R11) the ally cards by tacticDraft.weights, other rounds every card uniform (terrain cards only for the match stage)' }, }, format: { multi: { cards: 6, pickOrder: 'random', firstPickSec: 30, otherPickSec: 16, onTimeout: 'autoPickRandom', eachPlayerPicks: 1 }, @@ -2655,17 +2739,42 @@ function buildChoices(ctx, effects, items, chess) { }, cards: { bounty, tactic }, // the official 悬赏决策 structures by kind (tools/build-data.mjs BOUNTY_INITIAL_SETS; `seen` = the match numbers of - // test/fixtures/official-bounty-drafts.json; `slots` = the official events, the unseen ones built by `mixed` / `rule`) + // test/fixtures/official-bounty-drafts.json; `slots` = the official events, the unseen ones built by `rule`) bountyDrafts: { - initial: { events: eventsOf('bounty', (e) => bountyEventRe.initial.test(e.id) && !e.solo), slots: eventsOf('bounty', (e) => bountyEventRe.initial.test(e.id) && !e.solo).length, sets: BOUNTY_INITIAL_SETS, mixed: BOUNTY_INITIAL_MIXED, count: 6, assumed: ['the unseen slots built by `mixed`', '险境 R6 drafts like R3'] }, - boss: { events: eventsOf('bounty', (e) => bountyEventRe.boss.test(e.id) && !e.solo), templates: BOUNTY_BOSS_TEMPLATES, count: 6, assumed: ['a uniform pick among the seen groups', 'boss bounties of no seen group are not offered'] }, - hunter: { - events: eventsOf('bounty', (e) => bountyEventRe.hunter.test(e.id) && !e.solo), slots: eventsOf('bounty', (e) => bountyEventRe.hunter.test(e.id) && !e.solo).length, - templates: BOUNTY_HUNTER_TEMPLATES, - rule: { giants: hunterTier(3), groupCards: hunterTier(2), groupSizes: BOUNTY_HUNTER.groupSizes, fill: hunterTier(1) }, - onePerSeries: BOUNTY_HUNTER.onePerSeries, count: BOUNTY_HUNTER.count, - assumed: ['a group (the giant + tier-II cards) + tier-I fill, like R9', 'the unseen slots built by `rule`', 'a uniform pick among the 15 events'], + initial: { + events: eventsOf('bounty', (e) => bountyEventRe.initial.test(e.id) && !e.solo), slots: eventsOf('bounty', (e) => bountyEventRe.initial.test(e.id) && !e.solo).length, + pick: 'slot', groups: BOUNTY_INITIAL_SETS, rule: BOUNTY_INITIAL_RULE, count: 6, + assumed: ['a uniform pick among the 10 events', 'the unseen 10th set built by `rule`', '险境 R6 drafts like R3'], }, + boss: { + events: eventsOf('bounty', (e) => bountyEventRe.boss.test(e.id) && !e.solo), slots: BOUNTY_BOSS_GROUPS.length, + pick: 'seen', groups: BOUNTY_BOSS_GROUPS.map(withWeights), count: 6, + assumed: ['a group picked by the matches it came in (the per-match cause is open)', 'card weights 1 + hits', 'the single-draft groups completed with their base cards', 'boss bounties of no seen group are not offered'], + }, + hunter: { + events: eventsOf('bounty', (e) => bountyEventRe.hunter.test(e.id) && !e.solo), slots: BOUNTY_HUNTER_GROUPS.length, + // one of the 7 seen lists, uniform [ASSUMED]: `slots` 7, so no list is built from nothing (which of the 15 events + // R11 fires is open — by the data's blocks it would be 8..15); `rule` builds the `open` cards only + pick: 'slot', groups: BOUNTY_HUNTER_GROUPS.map(withWeights), + rule: { ...BOUNTY_HUNTER_RULE, giants: hunterTier(3), cards: [...hunterTier(2), ...hunterTier(1)] }, count: 6, + assumed: ['one of the 7 seen lists, picked uniformly (which of the 15 events R11 fires is open)', 'card weights 1 + hits', 'the `open` cards built by `rule`'], + }, + }, + // the official 机密商店 (SHOP_DRAFT) at `rounds`: `slots` tier → weight (`coin` = 盟约之币), each drawn on its own; + // `itemWeights` = 1 + the official cards an item showed on (other shop items 1) + shopDraft: { + rounds: SHOP_DRAFT.rounds, slots: SHOP_DRAFT.slots, coin: itemByName(SHOP_DRAFT.coin), + itemWeights: Object.fromEntries(Object.entries(SHOP_DRAFT.seen).filter(([n]) => n !== SHOP_DRAFT.coin).map(([n, k]) => [itemByName(n), 1 + k]).sort((a, b) => naturalCmp(a[0], b[0]))), + seen: SHOP_DRAFT.matches, count: 6, + assumed: ['the slot split', 'item weights 1 + seen', 'solo shows 3 of the 6', 'other rounds (标准 / 险境) keep the previous draw: tiers I–VI with replacement'], + }, + // the official 战术决策 (TACTIC_DRAFT) at `rounds`: each card drawn on its own (with replacement) from the cards.tactic + // entries of `kinds`, by `weights` (1 + the official cards it showed on; other cards of those kinds 1) + tacticDraft: { + rounds: TACTIC_DRAFT.rounds, kinds: TACTIC_DRAFT.kinds, + weights: Object.fromEntries(Object.entries(TACTIC_DRAFT.seen).map(([n, k]) => [tacticByName(n), 1 + k]).filter(([id]) => id).sort((a, b) => naturalCmp(a[0], b[0]))), + seen: TACTIC_DRAFT.matches, count: 6, + assumed: ['card weights 1 + seen', 'independent draws (no slot structure)', 'no terrain card at R11', 'solo shows 3', 'other rounds (标准 / 险境) keep every card, uniform, with replacement'], }, schedule, pools: {