feedback5: merge W5C — 琳琅诗怀雅 S2 bomb on x-6 (#116), 新硎 / 沉沙 one 断刃 layer (#107), the owner's ACTIVE_RANGE trigger rule, AUTO-skill audit (伺夜 S2, 浊心斯卡蒂 S2)
# Conflicts: # data/backups.json # tools/build-data.mjs
This commit is contained in:
commit
65ac4afbd8
32 files changed
+2432
-1959
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
{"units":{"char_600_cpione":{"charId":"char_600_cpione","name":"预备干员-先锋","appellation":"Reserve Operator - Vanguard","rarity":4,"profession":"PIONEER","subProfessionId":"pioneer","subProfessionName":"尖兵","position":"MELEE","nationId":null,"isNotObtainable":true,"assets":{"avatar":"char_600_cpione","avatarGolden":"char_600_cpione","portrait":"char_600_cpione_1","portraitGolden":"char_600_cpione_1","spine":"char_600_cpione","subProfIcon":"sub_pioneer_icon"},"moduleNames":{},"standsIn":["chess_char_5_01_a"],"forms":{"2/1/4/0":{"status":{"phase":2,"level":1,"skillLevel":4,"equipLevel":0},"stats":{"maxHp":1225,"atk":320,"def":272,"res":0,"cost":11,"blockCnt":2,"bat":1.05,"aspd":100,"respawnTime":70,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"rangeId":"1-1","rangeGrid":[[0,0],[0,1]],"dmgType":"phys","attackKind":"melee","projectile":"none","canHitFly":false,"targetPriority":null,"trait":{"desc":"能够阻挡两个敌人","descRaw":"能够阻挡两个敌人","bb":{},"bbStr":{},"rangeGrid":null},"skills":[{"skillId":"skcom_charge_cost[1]","iconId":"skcom_charge_cost[1]","name":"冲锋号令·α型","level":4,"desc":"立即获得6点部署费用","descRaw":"立即获得<@ba.vup>6</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":27,"initSp":3,"maxChargeTime":1,"increment":1,"bb":{"cost":6},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[2]","iconId":"skcom_charge_cost[2]","name":"冲锋号令·β型","level":4,"desc":"立即获得9点部署费用","descRaw":"立即获得<@ba.vup>9</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":36,"initSp":9,"maxChargeTime":1,"increment":1,"bb":{"cost":9},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[3]","iconId":"skcom_charge_cost[3]","name":"冲锋号令·γ型","level":4,"desc":"立即获得12点部署费用","descRaw":"立即获得<@ba.vup>12</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":41,"initSp":12,"maxChargeTime":1,"increment":1,"bb":{"cost":12},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":2,"overrideTokenKey":null}],"talents":[{"index":0,"name":"攻击提升","desc":"攻击力+8%","descRaw":"攻击力+8%","bb":{"atk":0.08},"bbStr":{},"rangeGrid":null,"tokenKey":null,"hidden":false,"fromModule":false}],"displayTokens":[],"tokens":[]},"2/60/7/1":{"status":{"phase":2,"level":60,"skillLevel":7,"equipLevel":1},"stats":{"maxHp":1674,"atk":380,"def":322,"res":0,"cost":11,"blockCnt":2,"bat":1.05,"aspd":100,"respawnTime":70,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"rangeId":"1-1","rangeGrid":[[0,0],[0,1]],"dmgType":"phys","attackKind":"melee","projectile":"none","canHitFly":false,"targetPriority":null,"trait":{"desc":"能够阻挡两个敌人","descRaw":"能够阻挡两个敌人","bb":{},"bbStr":{},"rangeGrid":null},"skills":[{"skillId":"skcom_charge_cost[1]","iconId":"skcom_charge_cost[1]","name":"冲锋号令·α型","level":7,"desc":"立即获得6点部署费用","descRaw":"立即获得<@ba.vup>6</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":25,"initSp":6,"maxChargeTime":1,"increment":1,"bb":{"cost":6},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[2]","iconId":"skcom_charge_cost[2]","name":"冲锋号令·β型","level":7,"desc":"立即获得9点部署费用","descRaw":"立即获得<@ba.vup>9</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":33,"initSp":10,"maxChargeTime":1,"increment":1,"bb":{"cost":9},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[3]","iconId":"skcom_charge_cost[3]","name":"冲锋号令·γ型","level":7,"desc":"立即获得12点部署费用","descRaw":"立即获得<@ba.vup>12</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WILine truncated
|
||||
{"units":{"char_600_cpione":{"charId":"char_600_cpione","name":"预备干员-先锋","appellation":"Reserve Operator - Vanguard","rarity":4,"profession":"PIONEER","subProfessionId":"pioneer","subProfessionName":"尖兵","position":"MELEE","nationId":null,"isNotObtainable":true,"assets":{"avatar":"char_600_cpione","avatarGolden":"char_600_cpione","portrait":"char_600_cpione_1","portraitGolden":"char_600_cpione_1","spine":"char_600_cpione","subProfIcon":"sub_pioneer_icon"},"moduleNames":{},"standsIn":["chess_char_5_01_a"],"forms":{"2/1/4/0":{"status":{"phase":2,"level":1,"skillLevel":4,"equipLevel":0},"stats":{"maxHp":1225,"atk":320,"def":272,"res":0,"cost":11,"blockCnt":2,"bat":1.05,"aspd":100,"respawnTime":70,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"rangeId":"1-1","rangeGrid":[[0,0],[0,1]],"dmgType":"phys","attackKind":"melee","projectile":"none","canHitFly":false,"targetPriority":null,"trait":{"desc":"能够阻挡两个敌人","descRaw":"能够阻挡两个敌人","bb":{},"bbStr":{},"rangeGrid":null},"skills":[{"skillId":"skcom_charge_cost[1]","iconId":"skcom_charge_cost[1]","name":"冲锋号令·α型","level":4,"desc":"立即获得6点部署费用","descRaw":"立即获得<@ba.vup>6</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":27,"initSp":3,"maxChargeTime":1,"increment":1,"bb":{"cost":6},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[2]","iconId":"skcom_charge_cost[2]","name":"冲锋号令·β型","level":4,"desc":"立即获得9点部署费用","descRaw":"立即获得<@ba.vup>9</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":36,"initSp":9,"maxChargeTime":1,"increment":1,"bb":{"cost":9},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[3]","iconId":"skcom_charge_cost[3]","name":"冲锋号令·γ型","level":4,"desc":"立即获得12点部署费用","descRaw":"立即获得<@ba.vup>12</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":41,"initSp":12,"maxChargeTime":1,"increment":1,"bb":{"cost":12},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":2,"overrideTokenKey":null}],"talents":[{"index":0,"name":"攻击提升","desc":"攻击力+8%","descRaw":"攻击力+8%","bb":{"atk":0.08},"bbStr":{},"rangeGrid":null,"tokenKey":null,"hidden":false,"fromModule":false}],"displayTokens":[],"tokens":[]},"2/60/7/1":{"status":{"phase":2,"level":60,"skillLevel":7,"equipLevel":1},"stats":{"maxHp":1674,"atk":380,"def":322,"res":0,"cost":11,"blockCnt":2,"bat":1.05,"aspd":100,"respawnTime":70,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"rangeId":"1-1","rangeGrid":[[0,0],[0,1]],"dmgType":"phys","attackKind":"melee","projectile":"none","canHitFly":false,"targetPriority":null,"trait":{"desc":"能够阻挡两个敌人","descRaw":"能够阻挡两个敌人","bb":{},"bbStr":{},"rangeGrid":null},"skills":[{"skillId":"skcom_charge_cost[1]","iconId":"skcom_charge_cost[1]","name":"冲锋号令·α型","level":7,"desc":"立即获得6点部署费用","descRaw":"立即获得<@ba.vup>6</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":25,"initSp":6,"maxChargeTime":1,"increment":1,"bb":{"cost":6},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[2]","iconId":"skcom_charge_cost[2]","name":"冲锋号令·β型","level":7,"desc":"立即获得9点部署费用","descRaw":"立即获得<@ba.vup>9</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WITH_TIME","spCost":33,"initSp":10,"maxChargeTime":1,"increment":1,"bb":{"cost":9},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_charge_cost","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null},{"skillId":"skcom_charge_cost[3]","iconId":"skcom_charge_cost[3]","name":"冲锋号令·γ型","level":7,"desc":"立即获得12点部署费用","descRaw":"立即获得<@ba.vup>12</>点部署费用","skillType":"AUTO","durationType":"NONE","duration":0,"spType":"INCREASE_WILine truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"chess_char_1_01_a":{"chessId":"chess_char_1_01_a","baseId":"chess_char_1_01_a","goldenId":"chess_char_1_01_b","isGolden":false,"tier":1,"identifier":0,"isHidden":false,"isDiy":false,"visible":true,"chessType":"PRESET","backup":{"charId":"char_498_inside","tmplId":null,"skillIndex":1,"uniEquipId":"uniequip_002_inside","potRank":0},"shopSortId":1,"charId":"char_498_inside","name":"隐现","appellation":"Insider","rarity":5,"profession":"SNIPER","subProfessionId":"fastshot","subProfessionName":"速射手","position":"RANGED","nationId":"laterano","bonds":["lateranoShip","swiftShip"],"garrisonIds":["garrison_16_a"],"price":2,"sellPrice":1,"upgradeNum":3,"upgradeChessId":"chess_char_1_01_b","status":{"phase":1,"level":55,"skillLevel":4,"equipLevel":0},"stats":{"maxHp":1123,"atk":399,"def":140,"res":0,"cost":15,"blockCnt":1,"bat":1,"aspd":100,"respawnTime":80,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"rangeId":"3-3","rangeGrid":[[1,0],[1,1],[1,2],[1,3],[0,0],[0,1],[0,2],[0,3],[-1,0],[-1,1],[-1,2],[-1,3]],"dmgType":"phys","attackKind":"ranged","projectile":"arrow","canHitFly":true,"targetPriority":"fly","trait":{"desc":"优先攻击空中单位","descRaw":"优先攻击空中单位","bb":{},"bbStr":{},"rangeGrid":null},"skill":{"skillId":"skchr_inside_2","iconId":"skchr_inside_2","name":"“解决麻烦”","level":4,"desc":"攻击力+80%,攻击间隔略微缩短,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n攻击装有14发弹药,打完后结束(可随时停止技能)","descRaw":"攻击力<@ba.vup>+80%</>,攻击间隔<@ba.vup>略微缩短</>,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n<@ba.rem>攻击装有14发弹药,打完后结束(可随时停止技能)</>","skillType":"MANUAL","durationType":"AMMO","duration":0,"spType":"INCREASE_WITH_TIME","spCost":24,"initSp":8,"maxChargeTime":1,"increment":1,"bb":{"atk":0.8,"base_attack_time":-0.3,"attack@trigger_time":14},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skchr_inside_2","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null},"talents":[{"index":0,"name":"火力支援","desc":"在场停留20秒后,自身弹药类技能弹药上限+2","descRaw":"在场停留20秒后,自身弹药类技能弹药上限+2","bb":{"self_ammo":2,"duration":20},"bbStr":{},"rangeGrid":null,"tokenKey":null,"hidden":false,"fromModule":false}],"tokens":[],"module":{"id":"uniequip_002_inside","name":"“最初的惊喜”","type":"MAR-X","level":0,"active":false},"assets":{"avatar":"char_498_inside","portrait":"char_498_inside_1","spine":"char_498_inside","skillIcon":"skchr_inside_2","subProfIcon":"sub_fastshot_icon"},"skills":[{"skillId":"skchr_inside_1","iconId":"skchr_inside_1","name":"“不惹麻烦”","level":4,"desc":"每次攻击造成相当于攻击力185%的物理伤害\n攻击装有4发弹药,打完后结束(可随时停止技能)","descRaw":"每次攻击造成相当于攻击力<@ba.vup>185%</>的物理伤害\n<@ba.rem>攻击装有4发弹药,打完后结束(可随时停止技能)</>","skillType":"AUTO","durationType":"AMMO","duration":0,"spType":"INCREASE_WHEN_ATTACK","spCost":14,"initSp":0,"maxChargeTime":1,"increment":1,"bb":{"attack@atk_scale":1.85,"attack@trigger_time":4},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skchr_inside_1","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0,"overrideTokenKey":null,"isDefault":false},{"skillId":"skchr_inside_2","iconId":"skchr_inside_2","name":"“解决麻烦”","level":4,"desc":"攻击力+80%,攻击间隔略微缩短,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n攻击装有14发弹药,打完后结束(可随时停止技能)","descRaw":"攻击力<@ba.vup>+80%</>,攻击间隔<@ba.vup>略微缩短</>,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n<@ba.rem>攻击装有14发弹药,打完后结束(可随时停止技能)</>","skillType":"MANUAL","durationType":"AMMO","duration":0,"spType":"INCREASE_WITH_TIME","spCost":24,"initSp":8,"maxChargeTime":1,"increment":1,"bb":{"atk":0.8,"base_attack_time":-0.3,"attack@trigger_time":14},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skchr_inside_2","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null,"isDefault":true}]},"chess_char_1_01_b":{"chessId":"chess_char_1_01_b","baseId":"chess_char_1_01_a","goldenId":"chess_char_1_01_b","isGolden":true,"tier":1,"identifier":133,"isHidden":false,"isDiy":false,"visible":true,"chessType":"PRESET","backup":{"charId":"char_498_inside","tmplId":null,"skillIndex":1,"uniEquipId":"uniequip_002_inside","potRank":0},"shopSortId":1,"charId":"char_498Line truncated
|
||||
{"chess_char_1_01_a":{"chessId":"chess_char_1_01_a","baseId":"chess_char_1_01_a","goldenId":"chess_char_1_01_b","isGolden":false,"tier":1,"identifier":0,"isHidden":false,"isDiy":false,"visible":true,"chessType":"PRESET","backup":{"charId":"char_498_inside","tmplId":null,"skillIndex":1,"uniEquipId":"uniequip_002_inside","potRank":0},"shopSortId":1,"charId":"char_498_inside","name":"隐现","appellation":"Insider","rarity":5,"profession":"SNIPER","subProfessionId":"fastshot","subProfessionName":"速射手","position":"RANGED","nationId":"laterano","bonds":["lateranoShip","swiftShip"],"garrisonIds":["garrison_16_a"],"price":2,"sellPrice":1,"upgradeNum":3,"upgradeChessId":"chess_char_1_01_b","status":{"phase":1,"level":55,"skillLevel":4,"equipLevel":0},"stats":{"maxHp":1123,"atk":399,"def":140,"res":0,"cost":15,"blockCnt":1,"bat":1,"aspd":100,"respawnTime":80,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"immunities":{"stun":false,"silence":false,"sleep":false,"frozen":false,"levitate":false},"rangeId":"3-3","rangeGrid":[[1,0],[1,1],[1,2],[1,3],[0,0],[0,1],[0,2],[0,3],[-1,0],[-1,1],[-1,2],[-1,3]],"dmgType":"phys","attackKind":"ranged","projectile":"arrow","canHitFly":true,"targetPriority":"fly","trait":{"desc":"优先攻击空中单位","descRaw":"优先攻击空中单位","bb":{},"bbStr":{},"rangeGrid":null},"skill":{"skillId":"skchr_inside_2","iconId":"skchr_inside_2","name":"“解决麻烦”","level":4,"desc":"攻击力+80%,攻击间隔略微缩短,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n攻击装有14发弹药,打完后结束(可随时停止技能)","descRaw":"攻击力<@ba.vup>+80%</>,攻击间隔<@ba.vup>略微缩短</>,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n<@ba.rem>攻击装有14发弹药,打完后结束(可随时停止技能)</>","skillType":"MANUAL","durationType":"AMMO","duration":0,"spType":"INCREASE_WITH_TIME","spCost":24,"initSp":8,"maxChargeTime":1,"increment":1,"bb":{"atk":0.8,"base_attack_time":-0.3,"attack@trigger_time":14},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skchr_inside_2","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null},"talents":[{"index":0,"name":"火力支援","desc":"在场停留20秒后,自身弹药类技能弹药上限+2","descRaw":"在场停留20秒后,自身弹药类技能弹药上限+2","bb":{"self_ammo":2,"duration":20},"bbStr":{},"rangeGrid":null,"tokenKey":null,"hidden":false,"fromModule":false}],"tokens":[],"module":{"id":"uniequip_002_inside","name":"“最初的惊喜”","type":"MAR-X","level":0,"active":false},"assets":{"avatar":"char_498_inside","portrait":"char_498_inside_1","spine":"char_498_inside","skillIcon":"skchr_inside_2","subProfIcon":"sub_fastshot_icon"},"skills":[{"skillId":"skchr_inside_1","iconId":"skchr_inside_1","name":"“不惹麻烦”","level":4,"desc":"每次攻击造成相当于攻击力185%的物理伤害\n攻击装有4发弹药,打完后结束(可随时停止技能)","descRaw":"每次攻击造成相当于攻击力<@ba.vup>185%</>的物理伤害\n<@ba.rem>攻击装有4发弹药,打完后结束(可随时停止技能)</>","skillType":"AUTO","durationType":"AMMO","duration":0,"spType":"INCREASE_WHEN_ATTACK","spCost":14,"initSp":0,"maxChargeTime":1,"increment":1,"bb":{"attack@atk_scale":1.85,"attack@trigger_time":4},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skchr_inside_1","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0,"overrideTokenKey":null,"isDefault":false},{"skillId":"skchr_inside_2","iconId":"skchr_inside_2","name":"“解决麻烦”","level":4,"desc":"攻击力+80%,攻击间隔略微缩短,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n攻击装有14发弹药,打完后结束(可随时停止技能)","descRaw":"攻击力<@ba.vup>+80%</>,攻击间隔<@ba.vup>略微缩短</>,优先攻击使用远程武器的敌人并且不容易成为敌人的攻击目标\n<@ba.rem>攻击装有14发弹药,打完后结束(可随时停止技能)</>","skillType":"MANUAL","durationType":"AMMO","duration":0,"spType":"INCREASE_WITH_TIME","spCost":24,"initSp":8,"maxChargeTime":1,"increment":1,"bb":{"atk":0.8,"base_attack_time":-0.3,"attack@trigger_time":14},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skchr_inside_2","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1,"overrideTokenKey":null,"isDefault":true}]},"chess_char_1_01_b":{"chessId":"chess_char_1_01_b","baseId":"chess_char_1_01_a","goldenId":"chess_char_1_01_b","isGolden":true,"tier":1,"identifier":133,"isHidden":false,"isDiy":false,"visible":true,"chessType":"PRESET","backup":{"charId":"char_498_inside","tmplId":null,"skillIndex":1,"uniEquipId":"uniequip_002_inside","potRank":0},"shopSortId":1,"charId":"char_498Line truncated
|
||||
+9
-3
@@ -190,7 +190,7 @@ Top level: `{ season, seasonName, modes, economy, lpCapPerRound, bossOvertimeAft
|
||||
| `bb`, `bbStr` | `{"atk":1,"base_attack_time":-0.3,"attack@trigger_time":14}` | kit input (DESIGN §5.6) |
|
||||
| `rangeId`, `rangeGrid` | `null` | skill range override |
|
||||
| `prefabId`, `overrideTokenKey` | | |
|
||||
| `trigger` | `{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null}` | auto-cast rule (the official 技能策略, PRTS 卫戍协议/帮助 §作战阶段 技能操作; §2.2). `rule` ∈ `DEFAULT` (basic strategy), `SKILL_RANGE` (a MANUAL skill with a 技能范围 of its own: `customRangeGrid` = its `rangeGrid`, `rawRule` `DEFAULT` — no official row), `TAKE_DAMAGE` (every MANUAL 重装 skill but seven: 深巡 / 雷蛇 S2, 号角 S2 / S3 and 灰毫 S1 / S2 are `DEFAULT` with `rawRule` `TAKE_DAMAGE` — a deliberate deviation, `tools/build-data.mjs TRIGGER_DEVIATIONS`, DESIGN §21.29 — and 余 S2 is `SKILL_RANGE` with `rawRule` `TAKE_DAMAGE` and `customRangeGrid` its x-1, DESIGN §22.10), `SP_FULL` (official `ALWAYS`: 执旗手 / 战术家 / 吟游者 MANUAL skills), `CUSTOM_RANGE` (official `CUSTOM_RANGE_SEARCH_ENEMY`, uses `customRangeGrid`), `SEARCH` (解放者 / 阵法术师 MANUAL skills, 安洁莉娜 S2/S3), `MLYSS_WTRMAN` (缪尔赛思), `GDGLOW_SKILL_2` (荒芜拉普兰德, 纯烬艾雅法拉 S3: "全场存在可选目标时释放技能"). |
|
||||
| `trigger` | `{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null}` | auto-cast rule (the official 技能策略, PRTS 卫戍协议/帮助 §作战阶段 技能操作; §2.2). `rule` ∈ `DEFAULT` (basic strategy), `SKILL_RANGE` (a MANUAL skill with a 技能范围 of its own: `customRangeGrid` = its `rangeGrid`, `rawRule` `DEFAULT` — no official row), `ACTIVE_RANGE` (the owner's deliberate deviation of 2026-10-05: a MANUAL skill left on the basic strategy whose attack range while it runs strictly contains the operator's own range: `customRangeGrid` = that running range, `rawRule` `DEFAULT`), `TAKE_DAMAGE` (every MANUAL 重装 skill but seven: 深巡 / 雷蛇 S2, 号角 S2 / S3 and 灰毫 S1 / S2 are `DEFAULT` with `rawRule` `TAKE_DAMAGE` — a deliberate deviation, `tools/build-data.mjs TRIGGER_DEVIATIONS`, DESIGN §21.29 — and 余 S2 is `SKILL_RANGE` with `rawRule` `TAKE_DAMAGE` and `customRangeGrid` its x-1, DESIGN §22.10), `SP_FULL` (official `ALWAYS`: 执旗手 / 战术家 / 吟游者 MANUAL skills), `CUSTOM_RANGE` (official `CUSTOM_RANGE_SEARCH_ENEMY`, uses `customRangeGrid`), `SEARCH` (解放者 / 阵法术师 MANUAL skills, 安洁莉娜 S2/S3), `MLYSS_WTRMAN` (缪尔赛思), `GDGLOW_SKILL_2` (荒芜拉普兰德, 纯烬艾雅法拉 S3: "全场存在可选目标时释放技能"). |
|
||||
|
||||
### 2.1 Combat classification heuristic (`dmgType` / `attackKind` / `projectile` / `canHitFly`)
|
||||
- `dmgType`: MEDIC (except `incantationmedic`) and `bard` → `heal`; trait text containing 法术伤害 or profession CASTER → `arts`; else `phys`.
|
||||
@@ -212,7 +212,11 @@ everything needed to resolve a unit for `(chessId, skillIndex, moduleId)` (`simd
|
||||
skills: an AUTO skill keeps its own rule (DEFAULT; kits add a base-game rule where needed, e.g. 古米 S1). Then a
|
||||
MANUAL operator skill whose `rangeId` is a 技能范围 — its description is not an attack-range change ("攻击范围扩大 /
|
||||
改变 / 缩小 / 缩短", "攻击距离+N / 加长 / 缩短") — is `SKILL_RANGE` with `customRangeGrid` = its `rangeGrid`; summons keep
|
||||
DEFAULT. `customRangeGrid` of `CUSTOM_RANGE` from `skillRangeDict[skillId]`. (Research 03 Addendum C1 read the rows'
|
||||
DEFAULT. `customRangeGrid` of `CUSTOM_RANGE` from `skillRangeDict[skillId]`. Last, the owner's rule of 2026-10-05 (a
|
||||
deliberate deviation): a MANUAL operator skill still on DEFAULT (no row, no `TRIGGER_DEVIATIONS` entry) whose attack
|
||||
range while it runs — its `rangeId` grid when the text is an attack-range change, else the operator's range grown by
|
||||
`ability_range_forward_extend`; never "被动效果:攻击范围扩大" (引星棘刺 S3) — strictly contains the record's own
|
||||
`rangeGrid` is `ACTIVE_RANGE` with `customRangeGrid` = that running range (`activeAttackGrid`; stand-in forms alike). (Research 03 Addendum C1 read the rows'
|
||||
`skillIndex 0` as "skill 1 only" after BWIKI's transcription; superseded by user playtest #6.)
|
||||
- `modules[]` (golden, `equipLevel > 0`): every **ADVANCED** `uniequip` of the character (the INITIAL `uniequip_001_*`
|
||||
is "no module" = choice `'none'`), in official order, at the chess `equipLevel` (1, T6: 3):
|
||||
@@ -499,7 +503,9 @@ Glyph legend (`rows`):
|
||||
6. **Skill triggers** (§2.2): the class rows cover every MANUAL skill of the class (all 重装 MANUAL skills are
|
||||
`TAKE_DAMAGE` but the six of the deliberate deviation, DESIGN §21.29, which are `DEFAULT` with `rawRule` `TAKE_DAMAGE`, and 余 S2, `SKILL_RANGE` on its x-1 (DESIGN §22.10); 薄绿 / 卡涅利安 / 蜜蜡 / 玛恩纳 S2 `SEARCH`; 伺夜 / 魔王 / 浊心斯卡蒂 S3 `SP_FULL`) and no AUTO skill (古米 /
|
||||
雷蛇 / 瑕光 / 塞雷娅 / 号角 / 信仰搅拌机 S1, 伺夜 S1/S2, 魔王 S1); 13 MANUAL skills (26 normal + elite records) with
|
||||
their own 技能范围 are `SKILL_RANGE` (德克萨斯 S2, 凛御银灰 S2, 锏 S2/S3, 异客 S3, 忍冬 S2, 焰尾 S2 …); 余 S2 joins them by the §22.10 deviation, 14 skills / 28 records in the data.
|
||||
their own 技能范围 are `SKILL_RANGE` (德克萨斯 S2, 凛御银灰 S2, 锏 S2/S3, 异客 S3, 忍冬 S2, 焰尾 S2 …); 余 S2 joins them by the §22.10 deviation, 14 skills / 28 records in the data; 33 MANUAL skills (66 records) whose
|
||||
running attack range strictly contains the operator's own are `ACTIVE_RANGE` (the owner's rule of 2026-10-05; 莫斯提马 S3,
|
||||
银灰 S3, 史尔特尔 S2 / S3 …), plus 预备干员 Touch S2 / S3 and Raidian S3 in `backups.json`.
|
||||
7. **Trait candidate `rangeId`** (送葬人, 松果 1-3; 风丸, 归溟幽灵鲨 x-4) is the trait-effect area, exposed as
|
||||
`trait.rangeGrid`, not the attack range.
|
||||
8. **Passive skills** use numeric `spType 8` in skill_table → normalized to `ON_DEPLOY`.
|
||||
|
||||
+1
-1
@@ -304,7 +304,7 @@ Engine helpers (content must use these, never touch internals): `battle.dealDama
|
||||
|
||||
SP: `spType` `INCREASE_WITH_TIME` (+`spRecovery`/s), `INCREASE_WHEN_ATTACK` (+1 per attack), `INCREASE_WHEN_TAKEN_DAMAGE` (+1 per hit taken); starts at `initSp`; no SP gain while a duration skill is active. `maxChargeTime > 1` ⇒ charges.
|
||||
|
||||
Auto-trigger rules (`skillTrigger.rule` in data — the official 技能策略, PRTS 卫戍协议/帮助 §作战阶段 技能操作; §20.2): `DEFAULT` (SP ready AND about to attack/heal AND an enemy/injured ally inside the **initial** range, or an enemy the unit blocks; with `trigger.allies` + `hpAtMost` an ally of the skill grid at or below that HP ratio — 塞雷娅 S1 急救, whose cast replaces that attack and is withdrawn with its charge if the ally recovers first), `SKILL_RANGE` (a MANUAL skill with a 技能范围 of its own, not an attack-range change: any living enemy, stealthed ones included, on the skill range, checked every tick — "仅在技能范围内存在敌人(无视其不可选中)时释放技能"; 13 skills / 26 records by the official rule, 14 / 28 in the data with 余 S2's deviation, §22.10), `TAKE_DAMAGE` (on taking damage — any damage, 无来源 included, never a 流失; every MANUAL 重装 skill, §21.12 — but the six of the deliberate deviation, §21.29: 深巡 / 雷蛇 S2, 号角 S2 / S3 and 灰毫 S1 / S2 are `DEFAULT`, `rawRule` keeping the official TAKE_DAMAGE; and 余 S2, `SKILL_RANGE` on its x-1 (§22.10)), `SP_FULL` (immediately — 执旗手 / 战术家 / 吟游者 MANUAL skills, and AUTO DP skills such as 伺夜 S1, 焰尾 S1, 凛御银灰 S1), `CUSTOM_RANGE` (enemy inside the custom grid), `SEARCH` (an enemy inside the initial range, checked every tick — no attack needed; 解放者 / 阵法术师 MANUAL skills), `GDGLOW_SKILL_2` (a valid target anywhere on the field: 荒芜拉普兰德, 纯烬艾雅法拉 S3), special ids. The class rows cover **every MANUAL skill** of the class and never an AUTO skill (AUTO skills keep their own rule — an inference: PRTS names whole classes; the data's `skillIndex 0` / `-1` sentinel argues the other way, §20.2). **Operation cooldown**: the engine auto-casts a MANUAL skill no sooner than `AUTO_OP_COOLDOWN` (3 s) after its previous cast and after the unit's battle-start deployment ("自动操作具有3s冷却,在完成一次操作或作战开始时部署的单位将进入冷却"; `Battle._deploy` initial, `battle.flags.startOpCooldown`); kits with an automatic cast of their own check `skill.opCooling`; a pending "next attack" never takes a second charge. PASSIVE skills are always on.
|
||||
Auto-trigger rules (`skillTrigger.rule` in data — the official 技能策略, PRTS 卫戍协议/帮助 §作战阶段 技能操作; §20.2): `DEFAULT` (SP ready AND about to attack/heal AND an enemy/injured ally inside the **initial** range, or an enemy the unit blocks; with `trigger.allies` + `hpAtMost` an ally of the skill grid at or below that HP ratio — 塞雷娅 S1 急救, whose cast replaces that attack and is withdrawn with its charge if the ally recovers first), `SKILL_RANGE` (a MANUAL skill with a 技能范围 of its own, not an attack-range change: any living enemy, stealthed ones included, on the skill range, checked every tick — "仅在技能范围内存在敌人(无视其不可选中)时释放技能"; 13 skills / 26 records by the official rule, 14 / 28 in the data with 余 S2's deviation, §22.10), `ACTIVE_RANGE` (the owner's deliberate deviation of 2026-10-05, 0.2.0: a MANUAL skill left on the basic strategy whose attack range while it runs strictly contains the operator's own range — its rangeId grid, or the own range grown by `ability_range_forward_extend` — checks the DEFAULT condition on that running range every tick, no attack needed; `customRangeGrid` = the running range, `rawRule` the official DEFAULT; 33 skills / 66 records; 烛煌 S2 / S3, whose ranges do not contain her 3-1, keep DEFAULT), `TAKE_DAMAGE` (on taking damage — any damage, 无来源 included, never a 流失; every MANUAL 重装 skill, §21.12 — but the six of the deliberate deviation, §21.29: 深巡 / 雷蛇 S2, 号角 S2 / S3 and 灰毫 S1 / S2 are `DEFAULT`, `rawRule` keeping the official TAKE_DAMAGE; and 余 S2, `SKILL_RANGE` on its x-1 (§22.10)), `SP_FULL` (immediately — 执旗手 / 战术家 / 吟游者 MANUAL skills, and AUTO DP skills such as 伺夜 S1, 焰尾 S1, 凛御银灰 S1), `CUSTOM_RANGE` (enemy inside the custom grid), `SEARCH` (an enemy inside the initial range, checked every tick — no attack needed; 解放者 / 阵法术师 MANUAL skills), `GDGLOW_SKILL_2` (a valid target anywhere on the field: 荒芜拉普兰德, 纯烬艾雅法拉 S3), special ids. The class rows cover **every MANUAL skill** of the class and never an AUTO skill (AUTO skills keep their own rule — an inference: PRTS names whole classes; the data's `skillIndex 0` / `-1` sentinel argues the other way, §20.2). **Operation cooldown**: the engine auto-casts a MANUAL skill no sooner than `AUTO_OP_COOLDOWN` (3 s) after its previous cast and after the unit's battle-start deployment ("自动操作具有3s冷却,在完成一次操作或作战开始时部署的单位将进入冷却"; `Battle._deploy` initial, `battle.flags.startOpCooldown`); kits with an automatic cast of their own check `skill.opCooling`; a pending "next attack" never takes a second charge. PASSIVE skills are always on.
|
||||
|
||||
**SkillSpec** (authored per chess in `sim/content/kits/tierN.js`; values come from the chess's skill blackboard at its level — normal Lv4, elite Lv7 — so a spec is a *function of the blackboard*):
|
||||
```js
|
||||
|
||||
+1
-1
@@ -71,7 +71,7 @@
|
||||
- 作战中:海嗣、狼群、流形、支援装置开战时就在摆放的位置部署;医疗探机、诅咒娃娃开战时也在摆放的位置免费部署一次(持续 10 / 15 秒,和官方一样不需要先开技能),之后所属干员每次发动技能时再次在原位出现;所属干员被击倒、再部署回场时,技能给的那一个如果还没出现,会立刻出现。巫恋退场时诅咒娃娃随之撤退,赫默退场时已出现的医疗探机不受影响。医疗探机、诅咒娃娃、支援装置、海嗣没有摆放就不会出现;狼群、流形(战术家的援军)没有摆放时会在战术点出现。
|
||||
- **阻挡**看接触:干员阻挡中心距离约 0.7 格以内、与它接触的敌人(地面干员挡不住飞行和近地悬浮的敌人)。敌人卡在两名干员之间时,阻挡它的干员倒下、撤退或被晕眩后,另一名仍与它接触、还有空余阻挡数的干员会**立刻接替阻挡**;都没有空位时敌人才会走掉。迎面走来的敌人会停在干员格子前面。**阻挡了就一定能打到**:任何干员(包括站在近战位的远程干员和召唤物)总能攻击自己阻挡的敌人,不管它在不在攻击范围内、在干员哪一侧,并且优先攻击它(医疗干员除外:咒愈师以外的医疗挡住敌人时照常治疗队友,不会攻击它;「停止攻击」类技能期间也除外;技能原文另有限制的也按原文:普罗旺斯二技能开启时不以生命值高于 80% 的敌人为目标,寒檀二技能的冰凌随机落在攻击范围内的地块上)。
|
||||
- 开战时干员按**逐列从左到右、每列从上到下**的顺序部署(最左一列最先,与阿戈尔吞噬「更靠左和靠上」的顺序相同),召唤物在所有干员之后。被阻挡的敌人先打阻挡它的干员;没被阻挡的远程敌人先打嘲讽等级高的,同级时打最后部署的(召唤物、最右一列靠下的干员和刚再部署的干员更容易挨打)。隐匿的干员只会被它阻挡的敌人攻击,没被它挡住的敌人的溅射、爆炸、范围技能、留下的伤害区域(包括假想敌:蚀裂被击倒后喷出的毒雾)以及深池伙友卫队、扎罗的减攻速光环也落不到它身上(和官方一样;写明「无视无法选择」的效果如污染秽蚀照常能打到,寒霜的减攻速光环和“墓碑”这类地图效果照常生效);**迷彩**(如忍冬三技能期间击倒敌人后、寒芒克洛丝一技能)同样只会被它阻挡的敌人攻击,也显示为半透明,但躲不开溅射、爆炸和范围伤害(同时打范围内所有单位的普通攻击——如“斩胄之剑”“破胄之锤”“灵幛”——打不到它),也不算隐匿(不触发叙拉古等「隐匿时」效果)。叙拉古的隐匿按时(32 秒 + 每层 0.4 秒)结束;忍冬的迷彩按官方持续到她下一次开技能。**蒂比起飞**期间只挡飞行敌人,地面敌人不会选她为目标(普通攻击、溅射、技能范围、燃烧区域和要选中目标的减益都落不到她身上);飞行和悬浮敌人、写明「无视无法选择」的效果(如污染秽蚀)照常能打到她;地面敌人的光环和全场效果(如“墓碑”让全场攻击力、防御力减半)、她攻击敌人时招来的反制(如重装侦察兵的暴露)照常生效,起飞前已挂上的持续伤害也照常跳。
|
||||
- **技能自动释放**按官方「技能策略」:一般的手动技能在技能就绪、即将攻击 / 治疗且初始攻击范围内有敌人(治疗技能:有受伤的队友)时释放;**带独立技能范围**的技能(如德克萨斯「剑雨」、凛御银灰「御敌的锋锐」、锏「归于宁静」,不含「攻击范围扩大」类)在**技能范围内出现敌人**时就释放,不必先攻击;**重装干员**的手动技能在受到伤害时释放(例外:深巡、雷蛇的二技能,号角的二、三技能,灰毫的一、二技能按玩家反馈改为攻击范围内有敌人时就释放,余的二技能「厚礼上宾」改为周围两格(技能范围)内有敌人时就释放,这是本作有意与官方不同的地方;深巡一技能仍要受到伤害);执旗手 / 战术家 / 吟游者技能就绪即释放,解放者 / 阵法术师在初始攻击范围内有敌人时释放。**自动触发**的技能按其本身规则,例如古米「备用军粮」在身边(技能范围内)有受伤的队友时就会发动,下一次攻击改为治疗该队友(不用先接敌;她的二技能「食粮烹制」是手动技能,按重装规则在受到伤害时释放);塞雷娅「急救」在她即将攻击时、身边有生命不高于一半的队友才发动,这次攻击直接改为治疗;新约能天使二技能的护盾按官方给攻击范围内**仇恨最高**的队友(嘲讽等级高的优先,同级时给最后部署的),不一定是站在最前面挨打的那个。手动技能的自动释放有 3 秒冷却:开战部署后先等 3 秒,之后同一干员两次自动释放至少间隔 3 秒(可充能的技能不会同时放完)。
|
||||
- **技能自动释放**按官方「技能策略」:一般的手动技能在技能就绪、即将攻击 / 治疗且初始攻击范围内有敌人(治疗技能:有受伤的队友)时释放;**带独立技能范围**的技能(如德克萨斯「剑雨」、凛御银灰「御敌的锋锐」、锏「归于宁静」,不含「攻击范围扩大」类)在**技能范围内出现敌人**时就释放,不必先攻击;**开启后攻击范围比平时大**的手动技能(如莫斯提马「序时之匙」、银灰「真银斩」、史尔特尔「黄昏」、白面鸮「脑啡肽」)在**开启后的攻击范围内出现敌人**(治疗技能:有受伤的队友)时就释放,不必等敌人走进平时的攻击范围,这是本作按玩家反馈有意与官方不同的地方;**重装干员**的手动技能在受到伤害时释放(例外:深巡、雷蛇的二技能,号角的二、三技能,灰毫的一、二技能按玩家反馈改为攻击范围内有敌人时就释放,余的二技能「厚礼上宾」改为周围两格(技能范围)内有敌人时就释放,这是本作有意与官方不同的地方;深巡一技能仍要受到伤害);执旗手 / 战术家 / 吟游者技能就绪即释放,解放者 / 阵法术师在初始攻击范围内有敌人时释放。**自动触发**的技能按其本身规则,例如古米「备用军粮」在身边(技能范围内)有受伤的队友时就会发动,下一次攻击改为治疗该队友(不用先接敌;她的二技能「食粮烹制」是手动技能,按重装规则在受到伤害时释放);塞雷娅「急救」在她即将攻击时、身边有生命不高于一半的队友才发动,这次攻击直接改为治疗;新约能天使二技能的护盾按官方给攻击范围内**仇恨最高**的队友(嘲讽等级高的优先,同级时给最后部署的),不一定是站在最前面挨打的那个。手动技能的自动释放有 3 秒冷却:开战部署后先等 3 秒,之后同一干员两次自动释放至少间隔 3 秒(可充能的技能不会同时放完)。
|
||||
- **推开 / 拉拽**按官方「力度 − 重量」决定距离:例如野鬃二技能(中等力度)把重量 0 / 1 / 2 / 3 的敌人推开约 2.1 / 1.7 / 0.4 / 0.1 格,重量 4 以上推不动——轻型敌人反而推得更远。野鬃二技能沿她的朝向推开:正前方 45° 以内按上面的距离,身后、侧面或贴身的敌人只被轻推一下(约 0.4 格以内);琳琅诗怀雅三技能的金币则从她身边向外推开,落在她前方 2–4 格的范围(官方「范围2-4」)内的地面敌人和她阻挡的敌人身上。攻击速度最低为 20(沼泽、寒霜等减速叠满时也不会更慢)。
|
||||
- **元素损伤条**在单位自己的血条正下方:左边是元素图标,白条是剩余的元素值,只有真正爆发时才会耗尽;爆发后条变成元素的颜色、图标闪烁,在冷却期间慢慢回满(这段时间不会再积累元素损伤)。
|
||||
- **敌人**:远程敌人的射程按官方从干员的碰撞体积(半径 0.25 格)算起,比数据上的攻击范围半径远 0.25 格——例如萨卡兹枯朽战车(射程 2.2)能打到中心 2.45 格以内、站在低地的干员。没被阻挡的远程敌人每次攻击都会站定、播完攻击动作,两次攻击之间才继续前进。它的第一下攻击就是「秽蚀轰击」(在目标处留下半径 1.7、持续 10 秒的污染区:低地每秒 50、高台 25 点真实伤害,同名不叠加),被阻挡时普通攻击伤害翻倍。“萨科塔之翼”等血量第一次低于一半时会在原地小范围乱飞 5 秒(官方叫「恐惧」);叙拉古、妮芙等干员造成的恐惧会让敌人朝远离干员的方向逃跑。隐匿的敌人只有被阻挡(或被揭示)时才能被选为攻击目标,溅射、技能的圆形范围伤害也打不到没被挡住的隐匿敌人(和官方一样);阻挡解除后 3 秒内它仍然可以被选中(官方页面注明 0 秒或 1 秒的敌人按页面),之后才重新隐匿:深池逐火战士每次被击倒后先重生 1 秒,然后变成继续往前走的隐匿「余烬」(需要 5 次伤害击倒,护卫的「火灰」10 次),一般要用干员挡住它才能选中(挡住时它不再半透明;被阻挡时被击倒的,重生结束后约 2 秒内也能用远程或范围伤害补刀),10 秒内没打掉就满血站起来;敌人重生时身上的减速、恐惧等状态会被清空、技能冷却从头开始,被恐惧的逐火战士变成余烬后也能被挡住;转译基底·α 原始形态受到的伤害全部无效,受到第 4 次物理伤害、第 4 次法术伤害或被阻挡时花 2 秒变成寻仇者、特战术师或幽灵,之后才能被击倒。
|
||||
|
||||
+7
-2
@@ -800,7 +800,8 @@ or guard with a per-unit flag while dealing it. When the guard trips, the logged
|
||||
SP fills to cost → +1 charge (SP restarts) until charges are full (then SP stays full).
|
||||
- Triggers (`skill.trigger.rule` in data — the official 技能策略, PRTS 卫戍协议/帮助 §作战阶段 技能操作, resolved by
|
||||
`tools/build-data.mjs resolveTrigger`: charId rows by skill index; the class rows (重装 / 执旗手 / 战术家 / 吟游者 / 解放者 /
|
||||
阵法术师) for **every MANUAL skill** of the class; SKILL_RANGE for a MANUAL skill with a 技能范围 of its own; AUTO skills
|
||||
阵法术师) for **every MANUAL skill** of the class; SKILL_RANGE for a MANUAL skill with a 技能范围 of its own; ACTIVE_RANGE
|
||||
for a MANUAL skill on the basic strategy whose running attack range strictly contains the own range; AUTO skills
|
||||
take no row — they keep their own rule, DEFAULT or a kit override): `DEFAULT` — the basic strategy: ready **and** about
|
||||
to attack/heal **and** an enemy (heal skills: an injured ally) inside the **initial** range (`unit.baseRangeKeys`: its
|
||||
own grid + its permanent rangeExtend — "攻击范围扩大" modules/talents as persist never-expiring `rangeExtend` buffs; no
|
||||
@@ -811,7 +812,11 @@ or guard with a per-unit flag while dealing it. When the guard trips, the logged
|
||||
living enemy (stealthed, untargetable, flying included) on `trigger.customRangeGrid` (= the skill's rangeGrid), every
|
||||
tick, no attack needed; a kit may set `trigger.allies` (+ `hpAtMost`, default 1) for an injured, healable ally of the
|
||||
grid at or below that HP ratio instead (the AUTO heal skill 古米 S1: PRTS 备注 "此技能在存在生命值不满的可治疗角色时可
|
||||
触发…直至古米完成一次普通攻击的治疗" — her heal mode waits for its heal); `DEFAULT` with `trigger.allies` (+ `hpAtMost`,
|
||||
触发…直至古米完成一次普通攻击的治疗" — her heal mode waits for its heal); `ACTIVE_RANGE` — the owner's rule of 2026-10-05
|
||||
(a deliberate deviation): a MANUAL skill on the basic strategy whose attack range while it runs strictly contains the
|
||||
unit's own range checks the DEFAULT condition — a targetable enemy (or one it blocks), a heal skill an injured ally —
|
||||
on `trigger.customRangeGrid` (= that running range, grown by the unit's permanent rangeExtend unless the skill's
|
||||
`targeting.noRangeExtend`), every tick, no attack needed; `DEFAULT` with `trigger.allies` (+ `hpAtMost`,
|
||||
`grid`) = the basic rule **and** such an ally on the grid: the cast replaces the attack about to be made (塞雷娅 S1 "触发
|
||||
时会替换当次攻击", ≤ half HP); a cast whose ally condition fails before that attack is withdrawn, its charge returned;
|
||||
`TAKE_DAMAGE` — ready and just hit (重装: "不受技能范围影响,受到伤害时释放技能"; in the data every MANUAL 重装 skill but
|
||||
|
||||
@@ -17,16 +17,32 @@ const TEA_BOOM_RADIUS = 1.25;
|
||||
// ---------------------------------------------------------------------------------------------------------------
|
||||
// kits
|
||||
|
||||
/**
|
||||
* 沉沙 / 新硎 断刃 (PRTS 天赋): 「攻击力+80%,持有4个【断刃】 / 每次成功攻击后消耗1个【断刃】,攻击结束时若已耗尽【断刃】,则立刻
|
||||
* 切换为无断刃模式并失去攻击力加成」 (popup: the switch 「清空当次攻击间隔」, so it attacks again at once) / 「因坠落以外的原因死亡后…
|
||||
* 召唤自身剩余【断刃】数量的铜矛头 / 铁矛头(至少召唤1个)」. ONE layer of Atkup.atk / AtkUp.atk (沉沙 0.7 — its PRTS page repeats
|
||||
* 新硎's 80 %, the blackboard says 0.7 — / 新硎 0.8) from the spawn while it holds a blade (DeadSpawn.cnt = 4), removed when
|
||||
* an attack spends the last one; that attack's cooldown is then cleared (ai.js sets it after the 'attack' hook, so this
|
||||
* tick's 'tick' clears it and the next attack comes on the next tick). Unspent blades (cnt + cnt_add × spent, ≥ 1)
|
||||
* become 矛头 when it is killed (a leak is no death; the mode has no 坠落), at once and side by side (spawnChildren — the
|
||||
* 0.7 s random delay and the 1.0 square of the text are not modelled). Until 0.2.0 each attack stacked one more layer
|
||||
* and none was ever removed (GitHub #107: 新硎 1350 → 3510 ATK after two hits).
|
||||
*/
|
||||
function kitBlades(ab) {
|
||||
const cnt = T(ab, 'DeadSpawn.cnt') ?? 0, add = T(ab, 'DeadSpawn.cnt_add') ?? 0, atk = T(ab, 'Atkup.atk', 'AtkUp.atk') ?? 0;
|
||||
const key = ab.tS['DeadSpawn.enemy_key'];
|
||||
return [{
|
||||
spawn(b, e, a) { a.used = 0; },
|
||||
spawn(b, e, a) {
|
||||
a.used = 0;
|
||||
if (cnt > 0 && atk) b.addBuff(e, { key: 'ab:blade', mods: { atkPct: atk }, persist: true, visible: true });
|
||||
},
|
||||
attack(c, b, e, a) {
|
||||
if (a.used >= cnt) return;
|
||||
a.used++;
|
||||
b.addBuff(e, { key: 'ab:blade', refresh: 'stack', stacks: 1, maxStacks: Math.max(1, cnt), mods: { atkPct: atk }, persist: true, visible: true });
|
||||
if (++a.used < cnt) return;
|
||||
b.removeBuff(e, 'ab:blade'); // 无断刃模式
|
||||
a.clearCd = true;
|
||||
},
|
||||
tick(b, e, a) { if (a.clearCd) { a.clearCd = false; e.atkCd = 0; } },
|
||||
death(c, b, e, a) { if (c.reason === 'killed' && key) spawnChildren(b, e, key, Math.max(1, cnt + add * a.used)); },
|
||||
}];
|
||||
}
|
||||
@@ -110,7 +126,7 @@ export const TIMES_KITS = Object.freeze({
|
||||
enemy_1197_sfshu: kitDeathSpawn(), // 俗心 · death: 3 小说卷轴
|
||||
enemy_1197_sfshu_2: kitDeathSpawn(), // 雅气 · death: 3 诗画卷轴
|
||||
enemy_1199_sfjin: kitDeathSpawn(), // 身观 · death: 1 青铜镜 (taunt from data)
|
||||
enemy_1207_sfji: kitBlades, // 沉沙 · each attack spends a blade (+ATK); death: unspent blades → 铜矛头 (≥1)
|
||||
enemy_1207_sfji: kitBlades, // 沉沙 · +ATK while it holds a blade (4, one per attack); death: unspent blades → 铜矛头 (≥1)
|
||||
enemy_1207_sfji_2: kitBlades, // 新硎 · same (铁矛头)
|
||||
enemy_1209_sfden: kitInvisShield, // 清明 · veils nearby enemies (stealth) every 15 s; death: 铜灯盘
|
||||
enemy_1209_sfden_2: kitInvisShield, // 堂皇 · same (铁灯盘)
|
||||
|
||||
@@ -199,8 +199,10 @@ Each item is a mistake this project already made once. Tick every one for every
|
||||
- [ ] **5. Auto-cast trigger** — the data resolves it (`tools/build-data.mjs resolveTrigger`, `data/chess.json`
|
||||
`skills[].trigger`); check it, and change the data rule rather than hand-coding a trigger in the kit. The owner's
|
||||
rules (0.2.0): a skill whose attack range is larger than the normal one casts as soon as an enemy is inside the
|
||||
SKILL range (a deliberate deviation from the official 技能策略, like the 重装 exception; existing kits that predate
|
||||
the rule, such as 烛煌 S3 in `feedback1e-skillrange.test.js`, are not examples of it); an AUTO skill that acts on
|
||||
SKILL range (a deliberate deviation from the official 技能策略, like the 重装 exception: data `ACTIVE_RANGE` for a
|
||||
MANUAL skill on the basic strategy whose running range strictly contains the operator's own,
|
||||
`test/sim/feedback5-active-range.test.js`; 烛煌 S3 in `feedback1e-skillrange.test.js` keeps DEFAULT — its 4-11 does
|
||||
not contain her 3-1); an AUTO skill that acts on
|
||||
allies or itself fires at full SP (引星棘刺 S1, `kits_alt_t5.test.js` "… fires as soon as its SP is full, no enemy
|
||||
needed (GitHub #124)"); the 重装 exception list (`TRIGGER_DEVIATIONS`: 深巡 S2, 雷蛇 S2, 号角 S2 / S3, 灰毫 S1 / S2,
|
||||
余 S2; the 预备干员-重装 / Mechanist stand-ins: `STANDIN_TRIGGER_DEVIATIONS`, every skill), DESIGN §21.29 / §22.10,
|
||||
|
||||
@@ -11,6 +11,13 @@ import {
|
||||
/** 琳琅诗怀雅 S3's coin range (PRTS 备注 "前方范围2-4"; range_table "2-4", facing right). */
|
||||
const SWIRE2_COIN_GRID = Object.freeze([[1, 1], [0, 0], [0, 1], [0, 2], [-1, 1]]);
|
||||
|
||||
/**
|
||||
* 琳琅诗怀雅 S2 “见面礼”'s placement range: range_table "x-6" — her tile and the two tiles beyond it in each of the four
|
||||
* directions (symmetric: her facing does not matter). PRTS 备注 "香槟炸弹放置范围:x-6"; the client charpack (char_1033_swire2,
|
||||
* mode S2) gives its SpawnToken selector `_rangeId` "x-6". The skill's own rangeId (1-1) is her attack range, not this.
|
||||
*/
|
||||
const SWIRE2_BOMB_GRID = Object.freeze([[2, 0], [1, 0], [0, -2], [0, -1], [0, 0], [0, 1], [0, 2], [-1, 0], [-2, 0]]);
|
||||
|
||||
/** Merchant trait with a callback on every successful DP payment (琳琅诗怀雅 大买家). Same rules as professions.js. */
|
||||
function merchantInstall(onPay) {
|
||||
return (battle, unit) => {
|
||||
@@ -30,7 +37,8 @@ function merchantInstall(onPay) {
|
||||
}
|
||||
|
||||
export default {
|
||||
// ---- 3_04 琳琅诗怀雅 · 行商 — S2 “见面礼” (passive): each attack spends a coin to drop a champagne bomb in range;
|
||||
// ---- 3_04 琳琅诗怀雅 · 行商 — S2 “见面礼” (passive): with a coin and a free tile of range x-6 her attack's turn
|
||||
// throws a champagne bomb instead (onto an enemy's tile when one stands there; installS2);
|
||||
// 大买家: coin at skill start + coin & ATK stack per trait payment; 破财消灾: DP-paid revive (cost doubles)
|
||||
// S1 仗义疏财 (passive, 2 coins): a coin heals the most injured ally (< 70 % HP) of the 8 surrounding tiles for
|
||||
// attack@heal_scale × ATK — on her attack, or with no enemy to attack on her own attack timer (owner's decision
|
||||
@@ -118,6 +126,53 @@ export default {
|
||||
battle.on('attack', (ctx) => { if (ctx.attacker === unit) tryHeal(); }, { owner: unit, priority: -10 });
|
||||
battle.on('tick', () => { if (unit.deployed && unit.canAct && !unit.trait?.hadTarget) tryHeal(); }, { owner: unit });
|
||||
};
|
||||
/**
|
||||
* “见面礼” — 「消耗一枚金币在范围内一个可放置且可通行的地面放置香槟炸弹」. The client charpack (char_1033_swire2, mode S2)
|
||||
* makes her attack a priority composite: first the SpawnToken ability (animation Skill_2) whose trigger needs BOTH a
|
||||
* tile of its selector (range x-6; melee-buildable, walkable, low ground — the tile options of the selector) and her
|
||||
* coin buff (swire2_can_use_gold), else her normal attack (which needs a target). So a bomb takes her attack's turn,
|
||||
* enemies or not: with no enemy around she still spends her coins on the free tiles of x-6 (PRTS 备注 「否则随机放置香槟
|
||||
* 至可部署的地块」), and only a full x-6 (or no coin) lets her coins pile up to the cap. Tile (PRTS 备注 「放置香槟动画进行
|
||||
* 前若放置范围内存在敌人,则按攻击索敌规律放置香槟至其所在地块」; the selector's `_targetMotion` WALK): the ground enemies
|
||||
* standing on a free tile of x-6, in her attack's target order (blocked first, …, nearest the goal) — the first one's
|
||||
* tile; with none, a random free tile of x-6. A free tile: inside the field, nobody on it, no knocked-out operator's
|
||||
* tile (freeTile; an enemy on it does not count), walkable ground a melee unit may stand on (groundTile).
|
||||
* [ASSUMED] timing: the throw is instant and costs her attack one tick (PRTS 备注 「每次放置香槟时若正在攻击敌人,会短暂
|
||||
* 延长攻击抬手间隔」 — the composite clears its cooldown when the throw ends; the length of the Skill_2 animation is in
|
||||
* no table): `canAttack` holds her attack back while a throw is due and the 'tick' hook (after the attacks) throws
|
||||
* when her attack is ready. Until 0.2.0 every attack also dropped a bomb on her 1-1 range, at random.
|
||||
*/
|
||||
const bombTiles = (battle, unit) => {
|
||||
const out = [];
|
||||
for (const k of gridKeys(SWIRE2_BOMB_GRID, unit)) {
|
||||
const r = (k / COLS) | 0, c = k % COLS;
|
||||
if (freeTile(battle, r, c) && groundTile(battle, r, c)) out.push(k);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
// (`bombHold`: a refused spawn — a tile freeTile let through — never holds her attack back for longer than one cycle)
|
||||
const hasCoin = (battle, unit) => (unit.mem.coins ?? 0) >= coinCost && !(battle.time < (unit.mem.bombHold ?? -1));
|
||||
const throwDue = (battle, unit) => hasCoin(battle, unit) && bombTiles(battle, unit).length > 0;
|
||||
const installS2 = (battle, unit) => {
|
||||
const switchT = num(battle.tokenDef(tokenId, unit)?.skill?.bb?.duration_switch, 3);
|
||||
const ground = { ...unit.profile, canHitFly: false };
|
||||
battle.on('tick', () => {
|
||||
if (!alive(unit) || !unit.canAct || unit.atkCd > 1e-9 || unit.s.flags.disarm || !hasCoin(battle, unit)) return;
|
||||
const keys = bombTiles(battle, unit);
|
||||
if (!keys.length) return;
|
||||
const free = new Set(keys);
|
||||
let key = null;
|
||||
for (const e of enemiesOn(battle, unit, keys, 0, ground)) {
|
||||
const k = Math.round(e.y) * COLS + Math.round(e.x);
|
||||
if (!e.isFlying && free.has(k)) { key = k; break; }
|
||||
}
|
||||
if (key == null) key = battle.rng.pick(keys);
|
||||
const bomb = battle.spawnToken(unit, tokenId, (key / COLS) | 0, key % COLS, { untargetable: true, kit: bombKit(unit, switchT) });
|
||||
if (!bomb) { unit.mem.bombHold = battle.time + unit.s.interval; return; }
|
||||
unit.mem.coins -= coinCost;
|
||||
fx(battle, 'summon', bomb, { src: unit.id, token: tokenId, coins: unit.mem.coins });
|
||||
}, { owner: unit });
|
||||
};
|
||||
const installS3 = (battle, unit) => { // 千金一掷: "击倒敌人时获得一枚金币"
|
||||
battle.on('kill', (ctx) => {
|
||||
if (ctx.killer === unit && ctx.victim.side === 'enemy' && unit.skill?.active) addCoins(battle, unit, 1);
|
||||
@@ -171,35 +226,24 @@ export default {
|
||||
};
|
||||
},
|
||||
}),
|
||||
trait: { install: merchantInstall((battle, unit) => {
|
||||
// MER-Y "每次特性消耗费用时攻击力+4%,最多可以叠加5次" (any time, not only during the skill)
|
||||
if (modTal && num(modTal.atk) > 0) {
|
||||
battle.addBuff(unit, { key: 'trait:swire2_module', refresh: 'stack', stacks: 1, maxStacks: Math.max(1, num(modTal.max_stack_cnt, 5)), mods: { atkPct: num(modTal.atk) } });
|
||||
}
|
||||
if (!unit.skill?.active) return; // "技能期间"
|
||||
addCoins(battle, unit, num(t0.trait_sp, 1));
|
||||
battle.addBuff(unit, { key: 'talent:swire2_buyer', refresh: 'stack', stacks: 1, maxStacks: Math.max(1, num(t0.max_stack_cnt, 8)), mods: { atkPct: num(t0.atk) } });
|
||||
}) },
|
||||
trait: {
|
||||
// S2: a throw due takes her attack's turn (installS2)
|
||||
...(sel === S2 || sel == null ? { canAttack: (battle, unit) => !throwDue(battle, unit) } : {}),
|
||||
install: merchantInstall((battle, unit) => {
|
||||
// MER-Y "每次特性消耗费用时攻击力+4%,最多可以叠加5次" (any time, not only during the skill)
|
||||
if (modTal && num(modTal.atk) > 0) {
|
||||
battle.addBuff(unit, { key: 'trait:swire2_module', refresh: 'stack', stacks: 1, maxStacks: Math.max(1, num(modTal.max_stack_cnt, 5)), mods: { atkPct: num(modTal.atk) } });
|
||||
}
|
||||
if (!unit.skill?.active) return; // "技能期间"
|
||||
addCoins(battle, unit, num(t0.trait_sp, 1));
|
||||
battle.addBuff(unit, { key: 'talent:swire2_buyer', refresh: 'stack', stacks: 1, maxStacks: Math.max(1, num(t0.max_stack_cnt, 8)), mods: { atkPct: num(t0.atk) } });
|
||||
}),
|
||||
},
|
||||
install(battle, unit) {
|
||||
if (sel === S1) { installS1(battle, unit); return; }
|
||||
if (sel === S3) { installS3(battle, unit); return; }
|
||||
if (sel !== S2 && sel != null) return;
|
||||
const switchT = num(battle.tokenDef(tokenId, unit)?.skill?.bb?.duration_switch, 3);
|
||||
battle.on('attack', (ctx) => {
|
||||
if (ctx.attacker !== unit || !alive(unit) || (unit.mem.coins ?? 0) < coinCost) return;
|
||||
const tiles = [];
|
||||
for (const k of gridKeys(skillGrid ?? unit.rangeGrid, unit)) {
|
||||
const r = (k / COLS) | 0, c = k % COLS;
|
||||
// (never on the home tile of a dead operator: it could not redeploy until an enemy triggers the bomb)
|
||||
if (freeTile(battle, r, c) && groundTile(battle, r, c)) tiles.push([r, c]);
|
||||
}
|
||||
const tile = battle.rng.pick(tiles);
|
||||
if (!tile) return;
|
||||
const bomb = battle.spawnToken(unit, tokenId, tile[0], tile[1], { untargetable: true, kit: bombKit(unit, switchT) });
|
||||
if (!bomb) return;
|
||||
unit.mem.coins -= coinCost;
|
||||
fx(battle, 'summon', bomb, { src: unit.id, token: tokenId, coins: unit.mem.coins });
|
||||
}, { owner: unit, priority: -10 });
|
||||
installS2(battle, unit);
|
||||
},
|
||||
talents: [
|
||||
{ install(battle, unit) { // 大买家: "开启技能时获得1枚金币" (a passive starts at every deployment, S3 when cast)
|
||||
|
||||
@@ -116,6 +116,11 @@ export default {
|
||||
const dpGain = (battle, unit, n) => { if (n > 0) { battle.addDp(unit.ownerId, n); fx(battle, 'dp', unit, { n }); } };
|
||||
// S2: the pack's empowered next attack (armed by the cast; ×scale on its hits; a kill pays once)
|
||||
const installGift = (battle, unit) => {
|
||||
battle.on('tick', () => { // the cast: ready, the pack on the field, no unused gift on it (PRTS 备注)
|
||||
const sk = unit.skill, w = wolfOf(unit);
|
||||
if (!alive(unit) || !sk || !sk.ready || sk.active || !unit.canAct || unit.s.flags.silence || !w || w.mem.vigilGift) return;
|
||||
sk.activate('SP_FULL');
|
||||
}, { owner: unit });
|
||||
battle.on('beforeAttack', (ctx) => {
|
||||
const w = wolfOf(unit);
|
||||
if (!w || ctx.attacker !== w || !w.mem.vigilGift) return;
|
||||
@@ -201,8 +206,12 @@ export default {
|
||||
if (w) addShadow(battle, unit, w);
|
||||
},
|
||||
}),
|
||||
// (自动触发, PRTS 备注 「仅场上存在狼群,且狼群未获得此技能的充能时可触发技能」: no enemy needed — the kit casts it as soon
|
||||
// as it is ready while the pack stands and holds no unused gift (installGift); until 0.2.0 the data's DEFAULT made it
|
||||
// wait for 伺夜's own next attack, so it never fired with no enemy in his range)
|
||||
skchr_vigil_2: (s) => ({
|
||||
kind: 'instant',
|
||||
trigger: 'NEVER',
|
||||
onStart({ battle, unit }) {
|
||||
dpGain(battle, unit, num(s.bb.cost, 0));
|
||||
const w = wolfOf(unit);
|
||||
|
||||
@@ -60,8 +60,10 @@ function skadi2(bb, chess, def) {
|
||||
onStart({ battle, unit }) { unit.hp = unit.s.maxHp; battle.fx('heal', { x: unit.x, y: unit.y, id: unit.id }); },
|
||||
},
|
||||
// S2 同葬无光之愿 (toggle): 鼓舞 ATK / DEF = atk / def × her ATK / DEF on every other ally of her (+ 海嗣) range,
|
||||
// trait heal attack@atk_to_hp_recovery_ratio (trait pulse)
|
||||
skchr_skadi2_2: { kind: 'toggle' },
|
||||
// trait heal attack@atk_to_hp_recovery_ratio (trait pulse). 自动触发 with effects on her allies only (nothing to target):
|
||||
// on as soon as it is ready (SP_FULL, like 魔王 S1 往昔萦绕身旁); until 0.2.0 the data's DEFAULT left it off until an
|
||||
// enemy came into her (or a 海嗣's) range.
|
||||
skchr_skadi2_2: { kind: 'toggle', trigger: 'SP_FULL' },
|
||||
};
|
||||
return {
|
||||
skills,
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
// talents / traits read the resolved record, so a module choice ('none' ⇒ traitBase / talentsBase, module.active
|
||||
// false) is honoured. Per-skill triggers come from data (the official 技能策略: every MANUAL 重装 skill ⇒ TAKE_DAMAGE —
|
||||
// but the six of the owner's deliberate deviation, DESIGN §21.29 / tools/build-data.mjs TRIGGER_DEVIATIONS, which are
|
||||
// DEFAULT —, a MANUAL skill with its own 技能范围 ⇒ SKILL_RANGE, AUTO skills keep their own rule); the few spec rules are
|
||||
// documented at the skill (冲锋号令 AUTO ⇒ SP_FULL, 花香疗法 heal-type DEFAULT; the two 哨戒铁卫 S2s 深巡 行动能力剥夺 and
|
||||
// 雷蛇 反击电弧 state the DEFAULT their data carries since that deviation — GitHub issue #4, PR #12).
|
||||
// DEFAULT —, a MANUAL skill with its own 技能范围 ⇒ SKILL_RANGE, a MANUAL skill on the basic strategy whose running attack
|
||||
// range strictly contains the own one ⇒ ACTIVE_RANGE (the owner's rule, 2026-10-05), AUTO skills keep their own rule);
|
||||
// the few spec rules are documented at the skill (冲锋号令 AUTO ⇒ SP_FULL, 花香疗法 heal-type DEFAULT; the two 哨戒铁卫
|
||||
// S2s 深巡 行动能力剥夺 and 雷蛇 反击电弧 state the DEFAULT their data carries since that deviation — GitHub issue #4,
|
||||
// PR #12).
|
||||
// Tests: test/content/kits_alt_t1.test.js.
|
||||
//
|
||||
// fx kinds emitted (battle.fx(kind, {x, y, …})): aoe {radius, id, skill} · zone {radius, dur, id, skill} ·
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
// Lv7 elite blackboard, range, charges) — the loader picks the selected one. Talents / trait / install are shared: the
|
||||
// parts that belong to one skill only (琳琅诗怀雅 bombs, 菲莱 counters, 雪猎 special bullets…) check the selected skill id.
|
||||
// Triggers come from the data record of each skill (skills[i].trigger: tools/build-data.mjs resolveTrigger — the official
|
||||
// 技能策略 incl. SKILL_RANGE for a MANUAL skill's own 技能范围 and the class rows for every MANUAL skill), except
|
||||
// 技能策略 incl. SKILL_RANGE for a MANUAL skill's own 技能范围 and the class rows for every MANUAL skill; ACTIVE_RANGE, the
|
||||
// owner's rule of 2026-10-05, for a MANUAL basic-strategy skill whose running range strictly contains the own one), except
|
||||
// 薄绿 S1 (the 阵法术师 row SEARCH = "在初始攻击范围内存在敌人时" ⇒ the engine's DEFAULT for a phalanx, checked every
|
||||
// tick) and the kits' own automatic casts (雪猎 special bullets). Non-default modules: 能天使 MAR-Y (ASPD vs ground), 琳琅诗怀雅 MER-Y (ATK per payment),
|
||||
// 斯卡蒂 DRE-X (× vs blocked), 瑕光 GUA-X (heal × under 50 %), 伺夜 TAC-Y (×165 % trait, pack-blocked enemies taunt +1),
|
||||
|
||||
@@ -26,7 +26,9 @@
|
||||
// uses the engine's DEFAULT rule with `allies` / `hpAtMost` (about to attack + an ally of the skill area at ≤ half HP:
|
||||
// the heal replaces that attack). Every other
|
||||
// kit keeps the data rule (tools/build-data.mjs resolveTrigger, the official 技能策略: DEFAULT = about to attack + an
|
||||
// enemy in the INITIAL range; SKILL_RANGE for a MANUAL skill's own 技能范围; the class rows — 重装 TAKE_DAMAGE … — for
|
||||
// enemy in the INITIAL range; SKILL_RANGE for a MANUAL skill's own 技能范围; ACTIVE_RANGE for a MANUAL skill on the basic
|
||||
// strategy whose running attack range strictly contains the own one (the owner's rule, 2026-10-05); the class rows —
|
||||
// 重装 TAKE_DAMAGE … — for
|
||||
// every MANUAL skill; AUTO skills never take a class row).
|
||||
// - fx kinds emitted (battle.fx(kind, {x, y, id, …})): 'aoe' {r, skill}, 'healAoe' {r}, 'summon' {token}, 'anchor'
|
||||
// {fromX, fromY, r}, 'teleport', 'zone' {r, duration}, 'iceSpike' {r}, 'extraAttack', 'downed', 'revive' {r},
|
||||
|
||||
+18
-6
@@ -14,6 +14,10 @@
|
||||
// too), checked every tick, no attack needed. Kit option `trigger.allies` (+ `hpAtMost`, default 1): a healable,
|
||||
// injured ally of the grid whose HP ratio is at most that instead (an AUTO heal skill's own rule — 古米 S1 waits in
|
||||
// its heal mode until it has healed);
|
||||
// ACTIVE_RANGE — the owner's rule (2026-10-05, a deliberate deviation): a MANUAL skill on the basic strategy whose attack
|
||||
// range while it runs strictly contains the unit's own range checks the DEFAULT condition on that larger range
|
||||
// (trigger grid = the running range, grown by the unit's permanent rangeExtend unless the skill ignores 攻击距离), every
|
||||
// tick, no attack needed — an enemy the unit can target there (or one it blocks), a heal skill an injured ally;
|
||||
// TAKE_DAMAGE (ready + just took a hit: 重装 "不受技能范围影响,受到伤害时释放技能"), SP_FULL/ALWAYS (as soon as ready),
|
||||
// CUSTOM_RANGE (enemy inside the custom trigger grid), SEARCH (an enemy inside the INITIAL range, checked every tick
|
||||
// without waiting for an attack: "不受基础策略影响,在初始攻击范围内存在敌人时释放技能" — not any enemy on the field,
|
||||
@@ -44,7 +48,7 @@
|
||||
import { absoluteRangeKeys, canTargetEnemy } from './targeting.js';
|
||||
import { AUTO_OP_COOLDOWN, COLS, ROWS } from './constants.js';
|
||||
|
||||
const TICK_RULES = new Set(['SP_FULL', 'SEARCH', 'CUSTOM_RANGE', 'SKILL_RANGE', 'GDGLOW_SKILL_2']);
|
||||
const TICK_RULES = new Set(['SP_FULL', 'SEARCH', 'CUSTOM_RANGE', 'SKILL_RANGE', 'ACTIVE_RANGE', 'GDGLOW_SKILL_2']);
|
||||
/** True when a SkillSpec `targeting` changes the unit's range while the skill runs (Battle._refreshRange). */
|
||||
const changesRange = (tg) => !!(tg && (tg.rangeGrid || tg.rangeExtend || tg.noRangeExtend));
|
||||
/** Enemies that satisfy a content trigger range (any targetable enemy, flyers included). */
|
||||
@@ -325,15 +329,21 @@ export class SkillRuntime {
|
||||
/** Public form of the operation cooldown, for kits with their own automatic cast of a MANUAL skill. */
|
||||
get opCooling() { return this._opCooling(); }
|
||||
|
||||
/** Absolute tile keys of the trigger grid at the unit's current tile and direction (cached, with their Set). */
|
||||
/**
|
||||
* Absolute tile keys of the trigger grid at the unit's current tile and direction (cached, with their Set). ACTIVE_RANGE
|
||||
* grows it by the unit's permanent rangeExtend (the range the skill would run with — Battle._refreshRange) unless the
|
||||
* skill's range ignores 攻击距离 (targeting.noRangeExtend).
|
||||
*/
|
||||
_triggerKeys() {
|
||||
const u = this.unit;
|
||||
const tile = u.tileR * COLS + u.tileC;
|
||||
if (!this._trigKeys || this._trigTile !== tile || this._trigDir !== u.dir) {
|
||||
this._trigKeys = absoluteRangeKeys(this.triggerGrid, u.tileR, u.tileC, u.dir, 0);
|
||||
const ext = this.rule === 'ACTIVE_RANGE' && !this.spec.targeting?.noRangeExtend ? (u.s.baseRangeExtend || 0) : 0;
|
||||
if (!this._trigKeys || this._trigTile !== tile || this._trigDir !== u.dir || this._trigExt !== ext) {
|
||||
this._trigKeys = absoluteRangeKeys(this.triggerGrid, u.tileR, u.tileC, u.dir, ext);
|
||||
this._trigSet = new Set(this._trigKeys);
|
||||
this._trigTile = tile;
|
||||
this._trigDir = u.dir;
|
||||
this._trigExt = ext;
|
||||
}
|
||||
return this._trigKeys;
|
||||
}
|
||||
@@ -364,6 +374,7 @@ export class SkillRuntime {
|
||||
if (!this.triggerGrid) return this._defaultCondition();
|
||||
return b.anyEnemyInKeys(this._triggerKeys());
|
||||
}
|
||||
if (this.rule === 'ACTIVE_RANGE') return this._defaultCondition(this.triggerGrid ? this._triggerKeys() : null);
|
||||
// GDGLOW_SKILL_2 "全场存在可选目标时释放技能": a targetable enemy anywhere (heal skill: an ally that needs healing)
|
||||
if (this.rule === 'GDGLOW_SKILL_2') {
|
||||
if (this.healSkill) return b.injuredAlliesInKeys(ALL_TILES, u, !!u.profile?.heal?.elementHealRatio).length > 0;
|
||||
@@ -375,12 +386,13 @@ export class SkillRuntime {
|
||||
/**
|
||||
* DEFAULT rule condition: an enemy (or injured ally for heal skills) inside the initial range (baseRangeKeys: own
|
||||
* grid + permanent rangeExtend), or an enemy inside a content trigger range (addTriggerRange; not for heal skills).
|
||||
* `range` (ACTIVE_RANGE): those absolute tile keys instead of the initial range.
|
||||
*/
|
||||
_defaultCondition() {
|
||||
_defaultCondition(range = null) {
|
||||
const b = this.battle;
|
||||
const u = this.unit;
|
||||
if (b.rangeChanged(u)) b._refreshRange(u);
|
||||
const keys = u.baseRangeKeys || u.rangeKeys;
|
||||
const keys = range || u.baseRangeKeys || u.rangeKeys;
|
||||
if (keys) {
|
||||
if (this.healSkill) return b.injuredAlliesInKeys(keys, u).length > 0;
|
||||
if (b.enemiesInKeys(keys, u, u.profile).length > 0) return true;
|
||||
|
||||
@@ -290,22 +290,37 @@ for (const [key, n] of Object.entries(DEATH_SPAWN)) {
|
||||
}
|
||||
|
||||
for (const key of ['enemy_1207_sfji', 'enemy_1207_sfji_2']) {
|
||||
test(`${nm(key)}: each attack spends a blade (+ATK); unspent blades become 矛头 on death (at least 1)`, () => {
|
||||
// PRTS 天赋 "攻击力+X%,持有4个【断刃】 / 每次成功攻击后消耗1个【断刃】,攻击结束时若已耗尽【断刃】,则立刻切换为无断刃模式并失去攻击力
|
||||
// 加成" (popup: "清空当次攻击间隔" — it attacks again at once); GitHub #107: until 0.2.0 each attack stacked another layer
|
||||
test(`${nm(key)}: one ATK layer while it holds a blade, gone with the 4th attack (which is followed at once by the next); unspent blades become 矛头 on death (at least 1)`, () => {
|
||||
const per = tb(key, 'Atkup.atk') ?? tb(key, 'AtkUp.atk'), cnt = tb(key, 'DeadSpawn.cnt');
|
||||
const h = arena({ units: [{ chessId: 't_wall', row: 9, col: 5 }] });
|
||||
h.step();
|
||||
const e = put(h, key, [9, 5]);
|
||||
const base = e.s.atk;
|
||||
const base = e.base.atk;
|
||||
approx(e.s.atk, base * (1 + per), 1e-6, 'holding 4 blades: one layer from the spawn');
|
||||
h.runUntil(() => e.stats.attacks >= 2, 20);
|
||||
const per = tb(key, 'Atkup.atk') ?? tb(key, 'AtkUp.atk');
|
||||
approx(e.s.atk, base * (1 + 2 * per));
|
||||
killed(h, e, null);
|
||||
approx(e.s.atk, base * (1 + per), 1e-6, 'two blades spent: still one layer (never stacked)');
|
||||
h.runUntil(() => e.stats.attacks >= cnt, 20);
|
||||
approx(e.s.atk, base, 1e-6, 'the last blade spent: 无断刃模式, no bonus');
|
||||
const tLast = h.b.time;
|
||||
assert.ok(h.runUntil(() => e.stats.attacks >= cnt + 1, 0.2), 'the mode switch clears the attack interval: the next attack at once');
|
||||
assert.ok(h.b.time - tLast < e.s.interval / 2, `${h.b.time - tLast} s after the 4th attack`);
|
||||
const child = E[key].talents.bbStr['DeadSpawn.enemy_key'];
|
||||
assert.equal(alive(h, child).length, tb(key, 'DeadSpawn.cnt') + tb(key, 'DeadSpawn.cnt_add') * 2);
|
||||
const h2 = arena();
|
||||
killed(h, e, null);
|
||||
assert.equal(alive(h, child).length, 1, 'no blade left: still one 矛头');
|
||||
// killed after two attacks: the two unspent blades; untouched: all four
|
||||
const h2 = arena({ units: [{ chessId: 't_wall', row: 9, col: 5 }] });
|
||||
h2.step();
|
||||
const e2 = put(h2, key, [10, 7]);
|
||||
const e2 = put(h2, key, [9, 5]);
|
||||
h2.runUntil(() => e2.stats.attacks >= 2, 20);
|
||||
killed(h2, e2, null);
|
||||
assert.equal(alive(h2, child).length, tb(key, 'DeadSpawn.cnt'));
|
||||
assert.equal(alive(h2, child).length, cnt + tb(key, 'DeadSpawn.cnt_add') * 2);
|
||||
const h3 = arena();
|
||||
h3.step();
|
||||
const e3 = put(h3, key, [10, 7]);
|
||||
killed(h3, e3, null);
|
||||
assert.equal(alive(h3, child).length, cnt);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -352,16 +352,18 @@ test('2_12 砾 S1 影袭: at deployment DEF +def decaying to 0 over `duration` s
|
||||
}
|
||||
});
|
||||
|
||||
test('2_13 蒂比 S1 专业喷绘技巧: DEFAULT trigger, takes off (skill range, ATK +atk, blocks flyers), single shots; hits never set it off', () => {
|
||||
test('2_13 蒂比 S1 专业喷绘技巧: ACTIVE_RANGE trigger (an enemy in its 2-3 only), takes off (skill range, ATK +atk, blocks flyers), single shots; hits never set it off', () => {
|
||||
for (const id of both('chess_char_2_13')) {
|
||||
const bb = bbAlt(id);
|
||||
const h = run({ defs: { enemies: { e: dummy('e'), f: dummy('f', { motion: 'FLY' }) } }, units: [U(id, 9, 5, { carryState: READY })], enemies: [{ key: 'e', pos: [9, 6] }] });
|
||||
// (10,5) = [1,0]: inside S1's 2-3, outside her own 2-2 — the owner's rule of 2026-10-05 (data trigger ACTIVE_RANGE)
|
||||
const h = run({ defs: { enemies: { e: dummy('e'), f: dummy('f', { motion: 'FLY' }) } }, units: [U(id, 9, 5, { carryState: READY })], enemies: [{ key: 'e', pos: [10, 5] }] });
|
||||
const u = h.unit(id);
|
||||
usesAlt(u, id);
|
||||
h.step();
|
||||
const range0 = u.baseRangeKeys.length;
|
||||
assert.ok(!u.baseRangeKeys.includes(h.b.grid.key(10, 5)), 'the enemy is outside her own range');
|
||||
h.runUntil(() => u.skill.active, 3);
|
||||
assert.equal(started(h, u)[0].reason, 'DEFAULT');
|
||||
assert.equal(started(h, u)[0].reason, 'ACTIVE_RANGE');
|
||||
assert.equal(u.s.flags.liftoff, true, 'airborne (起飞)');
|
||||
assert.equal(u.ground, true, 'still a ground unit on her low tile');
|
||||
approx(u.s.atk, u.base.atk * (1 + bb.atk));
|
||||
|
||||
@@ -829,6 +829,32 @@ test('3_19 伺夜 S2 领袖的馈赠: +DP, the pack recovers HP, its next attack
|
||||
}
|
||||
});
|
||||
|
||||
test('3_19 伺夜 S2 领袖的馈赠 (自动触发): no enemy needed — cast at full SP while the pack stands and holds no unused gift (PRTS 备注), never without the pack', () => {
|
||||
for (const id of BOTH('chess_char_3_19_a')) {
|
||||
const b = SB(id, 'skchr_vigil_2');
|
||||
const h = makeBattle({ defs: { chess: noGarrison(id) }, timeLimit: 60, flags: { dpPerSec: 0 }, units: [U(id, 'skchr_vigil_2', 10, 3)] });
|
||||
const u = h.unit(id), p = h.b.getPlayer('p1');
|
||||
h.run(1);
|
||||
const w = u.trait.reinforcement;
|
||||
assert.ok(w && w.alive, 'the pack stands');
|
||||
const dp0 = p.dp;
|
||||
fill(u);
|
||||
assert.ok(h.runUntil(() => u.skill.activations === 1, 1), 'cast with nobody on the field');
|
||||
approx(p.dp, dp0 + b.cost, 1e-6, '+cost DP at once');
|
||||
assert.ok(w.mem.vigilGift, 'the pack holds the gift for its next attack');
|
||||
fill(u);
|
||||
h.run(3);
|
||||
assert.equal(u.skill.activations, 1, '"狼群未获得此技能的充能时可触发": no second cast while the gift is unused');
|
||||
// the gift spent (as by a bite), the pack gone: still no cast until a pack stands again
|
||||
w.mem.vigilGift = null;
|
||||
for (let i = 0; i < 10 && w.alive; i++) h.b.dealDamage(null, w, { amount: 1e9, type: 'true' }); // a wolf is lost per KO
|
||||
assert.ok(!u.trait.reinforcement?.alive, 'no pack on the field');
|
||||
h.step(2);
|
||||
assert.equal(u.skill.activations, 1, '"仅场上存在狼群…时可触发": no pack, no cast');
|
||||
done(h);
|
||||
}
|
||||
});
|
||||
|
||||
test('3_19 伺夜 精锐 module TAC-Y: ×165 % on pack-blocked enemies; "援军阻挡的敌人更容易受到我方的攻击" = those enemies taunt +1 (not the pack); TAC-X guard not applied', () => {
|
||||
const id = 'chess_char_3_19_b', mod = 'uniequip_003_vigil';
|
||||
const tb = ds.getChess(id, { moduleId: mod }).traitBb;
|
||||
|
||||
@@ -366,6 +366,23 @@ test('6_04 浊心斯卡蒂 S2 同葬无光之愿: toggle; 鼓舞 ATK and DEF (at
|
||||
}
|
||||
});
|
||||
|
||||
test('6_04 浊心斯卡蒂 S2 同葬无光之愿 (自动触发, effects on her allies only): on as soon as its SP is full — no enemy needed', () => {
|
||||
for (const id of both('chess_char_6_04')) {
|
||||
const sid = 'skchr_skadi2_2';
|
||||
const h = run({
|
||||
defs: { chess: { ally_a: plain('ally_a', { stats: { maxHp: 1e5, atk: 400, def: 100 } }) } },
|
||||
units: [U(id, sid, 10, 4, { carryState: READY }), { chessId: 'ally_a', row: 10, col: 5 }],
|
||||
});
|
||||
const u = h.unit(id), a = h.unit('ally_a');
|
||||
usesSkill(u, sid);
|
||||
assert.equal(u.skill.rule, 'SP_FULL');
|
||||
assert.ok(h.runUntil(() => u.skill.active, 2), 'on with nobody on the field (the data DEFAULT waited for an enemy in her range)');
|
||||
h.run(1.1);
|
||||
assert.ok(a.findBuff('inspire') && a.findBuff('inspire:def'), '鼓舞 on the ally beside her');
|
||||
done(h);
|
||||
}
|
||||
});
|
||||
|
||||
// =================================================================================================================
|
||||
// 6_05 异客
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.
|
||||
import { getDefaultSource } from '../../server/sim/simdata.js';
|
||||
import { effectiveProfile } from '../../server/sim/ai.js';
|
||||
import KITS from '../../server/sim/content/kits/tier3.js';
|
||||
import { COLS } from '../../server/sim/constants.js';
|
||||
|
||||
const ds = getDefaultSource();
|
||||
const D = (id) => ds.getChess(id);
|
||||
@@ -110,23 +111,38 @@ test('3_03 诗怀雅: 近距离作战指导 melee ATK aura, ×talent_scale durin
|
||||
done(h);
|
||||
});
|
||||
|
||||
test('3_04 琳琅诗怀雅: coins → champagne bomb (ATK% + 停顿), 大买家 coin/ATK per DP payment, 破财消灾 DP revive', () => {
|
||||
/** 琳琅诗怀雅 S2's placement range x-6 (range_table; PRTS 备注 "香槟炸弹放置范围:x-6") — symmetric, so facing does not matter. */
|
||||
const SWIRE_X6 = [[2, 0], [1, 0], [0, -2], [0, -1], [0, 0], [0, 1], [0, 2], [-1, 0], [-2, 0]];
|
||||
const TRAP = 'token_10031_swire2_gdtrap';
|
||||
const trapsOf = (h) => h.b.allyUnits.filter((t) => t.alive && t.defId === TRAP);
|
||||
const x6Keys = (r, c) => new Set(SWIRE_X6.map(([dr, dc]) => (r + dr) * COLS + c + dc));
|
||||
/** Flat stage where the only free placeable tile of x-6 around (9,5) is (9,6): the others are walkable 'R' road. */
|
||||
const ONE_TILE = { rows: { 9: '##ERRrrRrrSrrrrrrrS##', 10: '##hrrRrrrrfrrrrrrrf##', 11: '##hrrRrrrrfrrrrrrrf##' } };
|
||||
|
||||
test('3_04 琳琅诗怀雅: coins → champagne bombs on range x-6 with no enemy needed (ATK% + 停顿), 大买家 coin/ATK per DP payment, 破财消灾 DP revive', () => {
|
||||
const id = 'chess_char_3_04_a', bb = BB(id), t0 = TB(id, 0), t1 = TB(id, 1);
|
||||
const booms = [];
|
||||
const h = makeBattle({
|
||||
defs: { enemies: { enemy_w: enemyRec({ key: 'enemy_w', hp: 1e6, speed: 1, def: 0, atk: 0 }) } }, timeLimit: 60, hooks: ['damaged', 'deploy'], captureNoisy: true,
|
||||
units: [{ chessId: id, row: 9, col: 5 }], enemies: [{ key: 'enemy_w', route: 0 }],
|
||||
units: [{ chessId: id, row: 9, col: 5 }], enemies: [{ key: 'enemy_w', route: 0, time: 8 }],
|
||||
setup: (b) => b.on('damaged', (c) => { if (c.dmg?.tags?.includes('trap')) booms.push({ amount: c.amount, atk: c.source.s.atk, t: b.time }); }),
|
||||
});
|
||||
const u = h.unit(id);
|
||||
const x6 = x6Keys(9, 5);
|
||||
h.step();
|
||||
assert.equal(u.mem.coins, t0.sp, '开启技能 coin');
|
||||
// the 开启技能 coin (大买家) is thrown at once — her attack's turn, nobody on the field (client charpack: the S2 attack is
|
||||
// [SpawnToken if a free x-6 tile and a coin, else Attack]; PRTS 备注 "否则随机放置香槟至可部署的地块")
|
||||
assert.equal(trapsOf(h).length, t0.sp, 'the deployment coin became a bomb with no enemy around');
|
||||
assert.equal(u.mem.coins, 0);
|
||||
h.run(3.1);
|
||||
assert.equal(u.mem.coins, t0.sp + t0.trait_sp, 'coin from the first trait payment');
|
||||
assert.equal(u.findBuff('talent:swire2_buyer')?.stacks, 1);
|
||||
assert.equal(u.findBuff('talent:swire2_buyer')?.stacks, 1, 'first trait payment: an ATK stack');
|
||||
approx(u.s.atk, u.base.atk * (1 + t0.atk));
|
||||
assert.ok(h.runUntil(() => booms.length > 0, 20), 'bomb exploded');
|
||||
assert.ok(h.hooksOf('deploy').some((c) => c.unit.defId === 'token_10031_swire2_gdtrap'), 'bomb token placed');
|
||||
assert.equal(trapsOf(h).length, t0.sp + t0.trait_sp, '… and its coin another bomb');
|
||||
for (const t of trapsOf(h)) {
|
||||
assert.ok(x6.has(t.tileR * COLS + t.tileC), `bomb (${t.tileR},${t.tileC}) on range x-6`);
|
||||
assert.ok(h.b.grid.groundPassable(t.tileR, t.tileC) && h.b.grid.canStand(t.tileR, t.tileC), 'on walkable ground a melee unit may stand on');
|
||||
}
|
||||
assert.ok(h.runUntil(() => booms.length > 0, 30), 'bomb exploded');
|
||||
approx(booms[0].amount, booms[0].atk * bb.atk_scale, 1e-6, 'bomb damage');
|
||||
const e = h.enemy('enemy_w');
|
||||
assert.ok(e.findBuff('sluggish'), '停顿');
|
||||
@@ -846,33 +862,37 @@ test('3_02 断崖: 浮游刃 blades hit enemies blocked by the allies around her
|
||||
done(h);
|
||||
});
|
||||
|
||||
test('3_04 琳琅诗怀雅 精锐: MER-X drain, coin cap, armed bomb hits twice; bombs never land on a dead operator’s tile', () => {
|
||||
test('3_04 琳琅诗怀雅 精锐: MER-X drain; no enemy ⇒ coins fill every free tile of x-6, then pile up to the cap; armed bomb hits twice; never on a dead operator’s tile', () => {
|
||||
const gid = 'chess_char_3_04_b', bb = BB(gid), t0 = TB(gid, 0), tb = TR(gid);
|
||||
// drain + coin cap (no enemy: no attack spends a coin)
|
||||
const q = makeBattle({ units: [{ chessId: gid, row: 9, col: 5 }], timeLimit: 60, flags: { dpPerSec: 0 } });
|
||||
// drain; no enemy: every coin becomes a bomb on a free tile of x-6 until none is left, then the coins pile up to the cap
|
||||
const q = makeBattle({ units: [{ chessId: gid, row: 9, col: 5 }], timeLimit: 90, flags: { dpPerSec: 0 } });
|
||||
const s = q.unit(gid);
|
||||
q.step();
|
||||
q.b.getPlayer('p1').dp = 50;
|
||||
q.b.getPlayer('p1').dp = 90;
|
||||
q.run(3.1);
|
||||
approx(q.b.getPlayer('p1').dp, 50 - Math.abs(tb.cost), 1e-6, 'module: 2 DP per payment');
|
||||
q.run(tb.interval * (bb.sp + 1));
|
||||
approx(q.b.getPlayer('p1').dp, 90 - Math.abs(tb.cost), 1e-6, 'module: 2 DP per payment');
|
||||
// the flat field around (9,5): x-6 has 6 free placeable tiles (row 9 cols 3/4/6/7, (10,5), (11,5); rows 7/8 are no field)
|
||||
const free = [...x6Keys(9, 5)].filter((k) => { const r = (k / COLS) | 0, c = k % COLS; return !(r === 9 && c === 5) && q.b.grid.groundPassable(r, c) && q.b.grid.canStand(r, c); });
|
||||
assert.equal(free.length, 6);
|
||||
q.run(tb.interval * (free.length + bb.sp + 1));
|
||||
assert.deepEqual(trapsOf(q).map((t) => t.tileR * COLS + t.tileC).sort((a, b) => a - b), free.sort((a, b) => a - b), 'a bomb on every free tile of x-6');
|
||||
const paid = Math.floor((q.b.time + 1e-9) / tb.interval);
|
||||
assert.equal(s.mem.coins, bb.sp, 'coin cap = bb.sp');
|
||||
assert.equal(s.mem.coins, bb.sp, 'x-6 full: coin cap = bb.sp');
|
||||
assert.equal(s.findBuff('talent:swire2_buyer').stacks, Math.min(t0.max_stack_cnt, paid), 'ATK stack per payment (coins capped, stacks not)');
|
||||
done(q);
|
||||
|
||||
// a bomb that stayed duration_switch s on the field hits twice
|
||||
// a bomb that stayed duration_switch s on the field hits twice (only (9,6) is free: the walker comes to it after 3 s)
|
||||
const booms = [];
|
||||
const h = makeBattle({
|
||||
flat: ONE_TILE,
|
||||
defs: { enemies: { enemy_d: dummy('enemy_d'), enemy_w: enemyRec({ key: 'enemy_w', hp: 1e6, speed: 1, def: 0, atk: 0 }) } }, timeLimit: 60,
|
||||
units: [{ chessId: gid, row: 9, col: 5 }], enemies: [{ key: 'enemy_d', pos: [9, 5] }, { key: 'enemy_w', route: 0, time: 1 }],
|
||||
setup: (b) => b.on('damaged', (c) => { if (c.dmg?.tags?.includes('trap')) booms.push({ target: c.target.defId, amount: c.amount, atk: c.source.s.atk, t: b.time }); }),
|
||||
});
|
||||
const u = h.unit(gid);
|
||||
const switchT = ds.getToken('token_10031_swire2_gdtrap', gid).skill.bb.duration_switch;
|
||||
assert.ok(h.runUntil(() => h.b.allyUnits.some((t) => t.alive && t.defId === 'token_10031_swire2_gdtrap'), 5), 'bomb placed in front of her');
|
||||
const bomb = h.b.allyUnits.find((t) => t.alive && t.defId === 'token_10031_swire2_gdtrap');
|
||||
assert.deepEqual([bomb.tileR, bomb.tileC], [9, 6]);
|
||||
const switchT = ds.getToken(TRAP, gid).skill.bb.duration_switch;
|
||||
assert.ok(h.runUntil(() => trapsOf(h).length > 0, 5), 'bomb placed');
|
||||
const bomb = trapsOf(h)[0];
|
||||
assert.deepEqual([bomb.tileR, bomb.tileC], [9, 6], 'the one free tile of x-6');
|
||||
assert.ok(h.runUntil(() => booms.length > 0, 30), 'the walker triggered it');
|
||||
assert.ok(booms[0].t - bomb.deployedAt >= switchT);
|
||||
assert.equal(booms.length, 2, 'armed bomb: one extra hit');
|
||||
@@ -880,8 +900,9 @@ test('3_04 琳琅诗怀雅 精锐: MER-X drain, coin cap, armed bomb hits twice;
|
||||
assert.ok(h.enemy('enemy_w').findBuff('sluggish'));
|
||||
done(h);
|
||||
|
||||
// the tile in front belongs to a dead operator waiting to redeploy: no bomb there (no coin spent)
|
||||
// that one tile belongs to a dead operator waiting to redeploy: no bomb anywhere, no coin spent, and she attacks on
|
||||
const k = makeBattle({
|
||||
flat: ONE_TILE,
|
||||
defs: { enemies: { enemy_d: dummy('enemy_d') } }, timeLimit: 30,
|
||||
units: [{ chessId: gid, row: 9, col: 5 }, { chessId: 'chess_char_3_16_a', row: 9, col: 6 }], enemies: [{ key: 'enemy_d', pos: [9, 5], time: 0.5 }],
|
||||
});
|
||||
@@ -892,11 +913,36 @@ test('3_04 琳琅诗怀雅 精锐: MER-X drain, coin cap, armed bomb hits twice;
|
||||
const coins = v.mem.coins;
|
||||
k.run(5);
|
||||
assert.ok(v.stats.attacks >= 2, 'she kept attacking');
|
||||
assert.equal(k.b.allyUnits.filter((t) => t.defId === 'token_10031_swire2_gdtrap').length, 0, 'no bomb on the dead operator’s tile');
|
||||
assert.equal(k.b.allyUnits.filter((t) => t.defId === TRAP).length, 0, 'no bomb on the dead operator’s tile');
|
||||
assert.ok(v.mem.coins >= coins, 'no coin spent');
|
||||
done(k);
|
||||
});
|
||||
|
||||
test('3_04 琳琅诗怀雅 S2 见面礼: an enemy on a free tile of x-6 gets the bomb on its tile — ground only, in her attack target order; outside her 1-1 attack range too', () => {
|
||||
const id = 'chess_char_3_04_a';
|
||||
const bombAt = (enemies) => {
|
||||
const h = makeBattle({
|
||||
defs: { enemies: { enemy_d: dummy('enemy_d'), enemy_f: dummy('enemy_f', { motion: 'FLY' }) } }, timeLimit: 10, autoFinish: false,
|
||||
units: [{ chessId: id, row: 9, col: 5 }], enemies,
|
||||
});
|
||||
const u = h.unit(id);
|
||||
h.step();
|
||||
for (const t of trapsOf(h)) h.b.retreat(t, { reason: 'expired', permanent: true }); // the deployment coin's bomb
|
||||
h.step(2);
|
||||
u.mem.coins = 1;
|
||||
assert.ok(h.runUntil(() => trapsOf(h).length > 0, 2), 'a bomb');
|
||||
const t = trapsOf(h)[0];
|
||||
done(h);
|
||||
return [t.tileR, t.tileC];
|
||||
};
|
||||
// (9,7): two tiles ahead — x-6 but outside her attack range 1-1
|
||||
assert.deepEqual(bombAt([{ key: 'enemy_d', pos: [9, 7] }]), [9, 7]);
|
||||
// two ground enemies: the one nearer the goal (9,2) first (her attack target order: blocked → … → remaining distance)
|
||||
assert.deepEqual(bombAt([{ key: 'enemy_d', pos: [9, 7] }, { key: 'enemy_d', pos: [9, 4] }]), [9, 4]);
|
||||
// a flyer is no target of the selector (its `_targetMotion` WALK): the ground enemy farther from the goal gets it
|
||||
assert.deepEqual(bombAt([{ key: 'enemy_d', pos: [9, 7] }, { key: 'enemy_f', pos: [9, 4], route: 2 }]), [9, 7]);
|
||||
});
|
||||
|
||||
test('3_07 见行者: 惊爆射击 fires on an enemy inside the skill range only; 精锐 refund only on a ranged tile', () => {
|
||||
const id = 'chess_char_3_07_a', bb = BB(id);
|
||||
const h = makeBattle({
|
||||
|
||||
@@ -801,10 +801,13 @@ test('百炼嘉维尔 S2: drags unblocked enemies in front of her; T1 ATK/DEF +1
|
||||
u.hp = u.s.maxHp * 0.3;
|
||||
approx(h.b.heal(null, u, 100), 100 * t1.heal_scale_2);
|
||||
for (const e of h.b.enemies) h.b.dealDamage(null, e, { amount: 1e9, type: 'true' });
|
||||
h.run(0.3); // 战地巨斧 refreshes every 0.2 s: back to no extra blocked enemy before the cast
|
||||
const near = h.spawn('enemy_dummy', { pos: [9, 5] });
|
||||
const far = h.spawn('enemy_dummy', { pos: [9, 6] });
|
||||
u.skill.gainSp(1000);
|
||||
// S2's 2-5 strictly contains her 1-1: ACTIVE_RANGE (the owner's rule, 2026-10-05) casts it at once, no attack needed
|
||||
assert.ok(h.runUntil(() => u.skill.active, 3));
|
||||
assert.equal(h.hooksOf('skillStart').find((c) => c.unit === u)?.reason, 'ACTIVE_RANGE');
|
||||
approx(u.s.atk, u.base.atk * (1 + t0.atk + bb.atk));
|
||||
h.b.dealDamage(null, near, { amount: 1e9, type: 'true' });
|
||||
h.run(1.5);
|
||||
|
||||
@@ -125,8 +125,10 @@ test('琳琅诗怀雅: a 香槟炸弹 arms after its owner\'s module variant of
|
||||
chessId: SWIRE, lo, tokens, row: 9, col: 5, enemies: { enemy_d: dummy('enemy_d') },
|
||||
spawns: [{ key: 'enemy_d', pos: [9, 5] }, { key: 'enemy_d', pos: [9, 13] }],
|
||||
});
|
||||
for (const u of ops) { u.mem.coins = 5; u.player.dp = 99; }
|
||||
// the moment a bomb stands, an enemy steps on it (the bomb is < 1 tick old)
|
||||
// each threw its deployment coin's bomb in duel's first step (S2 needs no enemy); no other coin before the 3 s payment,
|
||||
// so every trap hit below is that bomb's
|
||||
for (const u of ops) { u.mem.coins = 0; u.player.dp = 99; }
|
||||
// the moment a bomb stands, an enemy steps on it (the bomb is a tick old)
|
||||
const bombs = [null, null];
|
||||
for (let i = 0; i < 30 * 10 && bombs.some((x) => !x); i++) {
|
||||
h.step();
|
||||
|
||||
+21
-2
@@ -467,8 +467,8 @@ test('chess: skills[] = every skill unlocked at the status, at the chess skill l
|
||||
assert.deepEqual(rules('chess_char_6_11_b'), ['MLYSS_WTRMAN', 'MLYSS_WTRMAN', 'MLYSS_WTRMAN']); // 缪尔赛思 (charId row −1)
|
||||
assert.deepEqual(rules('chess_char_1_08_a'), ['DEFAULT', 'SKILL_RANGE']); // 德克萨斯 S2 剑雨: 对周围所有敌人
|
||||
assert.deepEqual(chess.chess_char_1_08_a.skills[1].trigger.customRangeGrid, chess.chess_char_1_08_a.skills[1].rangeGrid);
|
||||
assert.deepEqual(rules('chess_char_4_22_a'), ['DEFAULT', 'DEFAULT', 'DEFAULT']); // 银灰: "攻击范围缩小 / 扩大" = attack range
|
||||
assert.deepEqual(rules('chess_char_3_18_a'), ['DEFAULT', 'SKILL_RANGE', 'DEFAULT']); // 忍冬: S2 对周围…, S3 攻击距离+1
|
||||
assert.deepEqual(rules('chess_char_4_22_a'), ['DEFAULT', 'DEFAULT', 'ACTIVE_RANGE']); // 银灰: "攻击范围缩小 / 扩大" = attack range
|
||||
assert.deepEqual(rules('chess_char_3_18_a'), ['DEFAULT', 'SKILL_RANGE', 'ACTIVE_RANGE']); // 忍冬: S2 对周围…, S3 攻击距离+1
|
||||
// the deliberate deviation from the 重装 row (DESIGN §21.29, the owner's decision; tools/build-data.mjs
|
||||
// TRIGGER_DEVIATIONS, per chess): six skills cast with an enemy in range, rawRule keeps the official TAKE_DAMAGE
|
||||
const raws = (id) => chess[id].skills.map((s) => s.trigger.rawRule);
|
||||
@@ -495,6 +495,25 @@ test('chess: skills[] = every skill unlocked at the status, at the chess skill l
|
||||
assert.deepEqual(raws(id), ['TAKE_DAMAGE', 'TAKE_DAMAGE', 'CUSTOM_RANGE_SEARCH_ENEMY']);
|
||||
assert.deepEqual(chess[id].skills[1].trigger.customRangeGrid, chess[id].skills[1].rangeGrid);
|
||||
}
|
||||
// the owner's rule of 2026-10-05 (a deliberate deviation): a MANUAL skill on the basic strategy whose running attack
|
||||
// range strictly contains the operator's own range is ACTIVE_RANGE on that range (rawRule keeps the official DEFAULT)
|
||||
const tiles = (g) => new Set((g || []).map(([r, c]) => `${r},${c}`));
|
||||
const wider = (a, b) => { const A = tiles(a), B = tiles(b); return A.size > B.size && [...B].every((k) => A.has(k)); };
|
||||
const active = Object.values(chess).flatMap((c) => (c.skills || []).filter((s) => s.trigger.rule === 'ACTIVE_RANGE').map((s) => [c, s]));
|
||||
for (const [c, s] of active) {
|
||||
assert.equal(s.skillType, 'MANUAL', `${c.chessId} ${s.skillId}`);
|
||||
assert.equal(s.trigger.rawRule, 'DEFAULT', `${c.chessId} ${s.skillId}: only the basic strategy`);
|
||||
assert.ok(wider(s.trigger.customRangeGrid, c.rangeGrid), `${c.chessId} ${s.skillId}: its running range strictly contains ${c.rangeId}`);
|
||||
if (s.rangeGrid) assert.deepEqual(s.trigger.customRangeGrid, s.rangeGrid, `${c.chessId} ${s.skillId}: the skill's own grid`);
|
||||
}
|
||||
assert.equal(active.length, 66, '33 skills, normal + elite');
|
||||
assert.equal(new Set(active.map(([c, s]) => `${c.baseId} ${s.skillId}`)).size, 33);
|
||||
const grown = (id, sid) => chess[id].skills.find((s) => s.skillId === sid).trigger;
|
||||
assert.deepEqual(grown('chess_char_5_07_a', 'skchr_surtr_3').customRangeGrid.length, chess.chess_char_5_07_a.rangeGrid.length + 2, '史尔特尔 S3 攻击距离+2: 1-1 grown by 2');
|
||||
assert.equal(grown('chess_char_5_03_a', 'skchr_blaze2_3').rule, 'DEFAULT', '烛煌 S3: 4-11 does not contain her 3-1');
|
||||
assert.equal(grown('chess_char_1_04_a', 'skchr_udflow_2').rule, 'DEFAULT', '深巡 S2: the §21.29 deviation stays');
|
||||
assert.equal(grown('chess_char_3_08_a', 'skchr_mint_1').rule, 'SEARCH', '薄绿 S1: its official 阵法术师 row');
|
||||
assert.equal(grown('chess_char_5_15_a', 'skchr_thorn2_3').rule, 'DEFAULT', '引星棘刺 S3: 被动效果:攻击范围扩大 is her own range');
|
||||
const deviated = Object.values(chess).flatMap((c) => (c.skills || []).filter((s) => s.trigger.rawRule === 'TAKE_DAMAGE' && s.trigger.rule !== 'TAKE_DAMAGE').map((s) => `${c.baseId} ${s.skillId}`));
|
||||
assert.equal(deviated.length, 14, 'exactly the six skills of §21.29 and 余 S2, normal + elite');
|
||||
assert.deepEqual([...new Set(deviated)].sort(), ['chess_char_1_04_a skchr_udflow_2', 'chess_char_1_20_a skchr_liskam_2', 'chess_char_2_18_a skchr_ashlok_2', 'chess_char_2_18_a skcom_atk_up[3]', 'chess_char_5_08_a skchr_horn_2', 'chess_char_5_08_a skchr_horn_3', 'chess_char_6_03_a skchr_yu_2']);
|
||||
|
||||
+471
-424
File diff suppressed because it is too large.
Load diff
+495
-489
File diff suppressed because it is too large.
Load diff
+172
-172
@@ -99,8 +99,8 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_8","factions":["TIMES","DOT","INVISIBLE"]},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":17,"bossPoolLeft":0,"virtualMs":106900},
|
||||
"rng": {"setup":25,"shop":207,"waves":0,"draft":10,"bots":8485,"meta":14},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":11,"bossPoolLeft":0,"virtualMs":106900},
|
||||
"rng": {"setup":25,"shop":207,"waves":0,"draft":10,"bots":8483,"meta":14},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
{"round":1,"ai_0":[1,27,4,0,0,1,2,"cc1bac8f",0,"sargonShip 0/2, soloShip 1/0",5,5,0,4]},
|
||||
@@ -118,27 +118,27 @@
|
||||
},
|
||||
{
|
||||
"round": 8,
|
||||
"ai_0": [1,27,11,0,0,4,8,"9642d3a4",62,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/31, soloShip 1/14, steadShip 0/6, swiftShip 0/8",19,19,0,60]
|
||||
"ai_0": [1,21,11,0,0,4,8,"9642d3a4",62,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/31, soloShip 1/14, steadShip 0/6, swiftShip 0/8",13,19,6,60]
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,27,12,0,0,4,8,"765a4a23",99,"arcaneShip 0/2, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 0/14, preciShip 0/12, sargonShip 0/8, siracusaShip 1/53, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/16",18,18,0,73]
|
||||
"ai_0": [1,21,12,0,0,4,8,"765a4a23",99,"arcaneShip 0/2, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 0/14, preciShip 0/12, sargonShip 0/8, siracusaShip 1/53, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/16",18,18,0,73]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,27,12,0,0,5,8,"44e95a01",112,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/3, preciShip 0/12, sargonShip 0/8, siracusaShip 2/69, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,87]
|
||||
"ai_0": [1,21,12,0,0,5,8,"44e95a01",112,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/3, preciShip 0/12, sargonShip 0/8, siracusaShip 2/69, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,87]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,27,12,0,0,5,8,"12000646",141,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/6, preciShip 0/12, sargonShip 0/8, siracusaShip 2/95, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,98]
|
||||
"ai_0": [1,21,12,0,0,5,8,"12000646",141,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/6, preciShip 0/12, sargonShip 0/8, siracusaShip 2/95, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",24,24,0,98]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,17,12,0,0,6,8,"d05cbec1",154,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/9, preciShip 0/12, sargonShip 0/8, siracusaShip 2/105, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",20,31,11,109]
|
||||
"ai_0": [1,11,12,0,0,6,8,"03cea672",154,"arcaneShip 0/2, deputShip 0/8, emptyShip 0/4, kazimierzShip 0/8, kjeragShip 0/14, miraShip 1/9, preciShip 0/12, sargonShip 0/8, siracusaShip 2/105, soloShip 1/16, steadShip 0/6, suntShip 1/2, swiftShip 1/22",16,31,15,109]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,17,12,0,0,6,8,"1cf42739",230,"arcaneShip 0/2, deputShip 2/12, emptyShip 1/8, kazimierzShip 0/16, kjeragShip 0/22, miraShip 1/13, preciShip 0/12, sargonShip 0/8, siracusaShip 1/129, soloShip 1/20, steadShip 0/6, suntShip 1/6, swiftShip 1/42",115,115,0,121]
|
||||
"ai_0": [1,11,12,0,0,6,8,"1cf42739",230,"arcaneShip 0/2, deputShip 2/12, emptyShip 1/8, kazimierzShip 0/16, kjeragShip 0/22, miraShip 1/13, preciShip 0/12, sargonShip 0/8, siracusaShip 1/129, soloShip 1/20, steadShip 0/6, suntShip 1/6, swiftShip 1/42",115,115,0,121]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -147,13 +147,13 @@
|
||||
"victory": true,
|
||||
"roundsPassed": 14,
|
||||
"eliminatedRound": null,
|
||||
"lp": 17,
|
||||
"lp": 11,
|
||||
"bandId": "band_ermengard",
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 0,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":290,"bossDamage":97500,"dmgDealt":1706085,"gold":131,"itemsEquipped":23,"kills":371,"leaks":11,"lpLost":10,"merges":5,"perfectRounds":12,"refreshes":15},
|
||||
"lineup": ["2_14_a@12,6","5_10_a@12,7[4_07_e_a+3_08_e_b]","5_20_b@11,5[6_09_e_a+5_02_e_b]","3_20_b@11,8[3_06_e_a+4_08_e_a]","6_11_a@10,3[4_12_e_a+5_02_e_b]","3_18_a@10,8[2_04_e_b+4_05_e_b]","6_19_a@9,4[4_04_e_a+4_10_e_a]","1_08_a@9,5[1_01_e_a+1_02_e_a]"],
|
||||
"stats": {"activatedLayers":290,"bossDamage":97500,"dmgDealt":1710191,"gold":131,"itemsEquipped":23,"kills":361,"leaks":21,"lpLost":16,"merges":5,"perfectRounds":11,"refreshes":15},
|
||||
"lineup": ["2_14_a@12,5","5_10_a@12,7[4_07_e_a+3_08_e_b]","5_20_b@11,5[6_09_e_a+5_02_e_b]","3_20_b@11,8[3_06_e_a+4_08_e_a]","6_11_a@10,3[4_12_e_a+5_02_e_b]","3_18_a@10,8[2_04_e_b+4_05_e_b]","6_19_a@9,4[4_04_e_a+4_10_e_a]","1_08_a@9,5[1_01_e_a+1_02_e_a]"],
|
||||
"bonds": ["arcaneShip 0/2","deputShip 1/14","emptyShip 1/10","kazimierzShip 0/16","kjeragShip 1/24","maniShip 1/2","miraShip 1/15","preciShip 0/12","sargonShip 0/8","siracusaShip 1/151","soloShip 1/22","steadShip 0/6","suntShip 1/8","swiftShip 1/44"]
|
||||
}
|
||||
}
|
||||
@@ -227,7 +227,7 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 0,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":268,"bossDamage":97500,"dmgDealt":2268247,"gold":140,"itemsEquipped":13,"kills":271,"leaks":4,"lpLost":4,"merges":5,"perfectRounds":11,"refreshes":18},
|
||||
"stats": {"activatedLayers":268,"bossDamage":97500,"dmgDealt":2262888,"gold":140,"itemsEquipped":13,"kills":270,"leaks":4,"lpLost":4,"merges":5,"perfectRounds":11,"refreshes":18},
|
||||
"lineup": ["1_17_b@12,5","4_14_b@11,4","3_11_a@11,5[1_05_e_a+3_08_e_a]","5_07_a@11,6[4_02_e_a+4_05_e_a]","4_10_a@10,3","1_02_b@10,4[4_12_e_a+4_06_e_a]","5_14_a@10,5[1_05_e_b+1_05_e_b]","4_04_a@10,6"],
|
||||
"bonds": ["arcaneShip 2/40","kazimierzShip 0/2","kjeragShip 1/13","lateranoShip 0/3","preciShip 2/58","raidShip 1/84","sargonShip 0/2","steadShip 0/8","suntShip 1/0","swiftShip 1/53","visiShip 1/20"]
|
||||
}
|
||||
@@ -243,8 +243,8 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_8","factions":["TIMES","DOT","INVISIBLE"]},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":14,"bossPoolLeft":0,"virtualMs":107800},
|
||||
"rng": {"setup":25,"shop":201,"waves":0,"draft":42,"bots":8380,"meta":2},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":9,"bossPoolLeft":0,"virtualMs":107800},
|
||||
"rng": {"setup":25,"shop":201,"waves":0,"draft":42,"bots":8376,"meta":2},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
{"round":1,"ai_0":[1,27,4,0,0,1,2,"cc1bac8f",0,"sargonShip 0/2, soloShip 1/0",5,5,0,4]},
|
||||
@@ -262,27 +262,27 @@
|
||||
},
|
||||
{
|
||||
"round": 8,
|
||||
"ai_0": [1,27,11,0,0,4,8,"e874f996",70,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/31, soloShip 1/7, steadShip 1/15, swiftShip 0/8",19,19,0,61]
|
||||
"ai_0": [1,24,11,0,0,4,8,"6960d5f9",68,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/29, soloShip 1/7, steadShip 1/15, swiftShip 0/8",16,19,3,61]
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,27,12,0,0,4,8,"ce7f2146",106,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/45, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
|
||||
"ai_0": [1,24,12,0,0,4,8,"ee973cc6",104,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/43, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,27,12,0,0,5,8,"d54ffbc1",122,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/18, preciShip 1/16, sargonShip 0/8, siracusaShip 1/49, soloShip 1/11, steadShip 0/15, swiftShip 0/8",24,24,0,86]
|
||||
"ai_0": [1,24,12,0,0,5,8,"b4c89cd7",130,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/23, preciShip 1/21, sargonShip 0/8, siracusaShip 1/47, soloShip 1/11, steadShip 0/15, swiftShip 0/8",24,24,0,86]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,24,12,0,2,5,8,"ab08ec3d",166,"arcaneShip 1/20, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/27, preciShip 1/23, sargonShip 0/8, siracusaShip 1/63, soloShip 1/13, steadShip 0/17, swiftShip 0/8",31,34,3,97]
|
||||
"ai_0": [1,19,12,0,2,5,8,"1d52aad9",174,"arcaneShip 1/20, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/32, preciShip 1/28, sargonShip 0/8, siracusaShip 1/61, soloShip 1/13, steadShip 0/17, swiftShip 0/8",29,34,5,97]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,14,14,0,0,6,8,"ebe4afd5",190,"arcaneShip 0/20, deputShip 1/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/34, preciShip 1/35, sargonShip 0/8, siracusaShip 1/67, soloShip 1/15, steadShip 0/17, swiftShip 1/15",21,31,10,111]
|
||||
"ai_0": [1,9,14,0,0,6,8,"4dd4e915",198,"arcaneShip 0/20, deputShip 1/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/39, preciShip 1/40, sargonShip 0/8, siracusaShip 1/65, soloShip 1/15, steadShip 0/17, swiftShip 1/15",9,31,22,111]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,14,12,0,2,6,8,"ae3d8af6",224,"arcaneShip 1/26, deputShip 0/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/34, preciShip 2/40, sargonShip 0/8, siracusaShip 1/79, soloShip 1/15, steadShip 0/17, swiftShip 1/20",115,115,0,126]
|
||||
"ai_0": [1,9,12,0,2,6,8,"42f17176",232,"arcaneShip 1/26, deputShip 0/14, emptyShip 1/10, kazimierzShip 0/8, kjeragShip 1/39, preciShip 2/45, sargonShip 0/8, siracusaShip 1/77, soloShip 1/15, steadShip 0/17, swiftShip 1/20",115,115,0,126]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -291,14 +291,14 @@
|
||||
"victory": true,
|
||||
"roundsPassed": 14,
|
||||
"eliminatedRound": null,
|
||||
"lp": 14,
|
||||
"lp": 9,
|
||||
"bandId": "band_ermengard",
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 0,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":262,"bossDamage":195000,"dmgDealt":1758810,"gold":140,"itemsEquipped":16,"kills":393,"leaks":13,"lpLost":13,"merges":3,"perfectRounds":11,"refreshes":15},
|
||||
"stats": {"activatedLayers":270,"bossDamage":195000,"dmgDealt":1657417,"gold":140,"itemsEquipped":16,"kills":378,"leaks":30,"lpLost":18,"merges":3,"perfectRounds":10,"refreshes":15},
|
||||
"lineup": ["6_12_a@12,5[5_01_e_a+5_02_e_a]","5_10_a@12,7[4_07_e_a+5_02_e_b]","4_14_a@11,8","3_11_a@10,3","5_14_a@9,4[3_08_e_a+3_11_e_a]","1_08_a@9,5[1_01_e_a+4_05_e_a]","6_02_a@9,6","4_10_a@9,8[4_08_e_a+4_10_e_b]"],
|
||||
"bonds": ["arcaneShip 1/30","deputShip 0/14","emptyShip 1/10","kazimierzShip 0/16","kjeragShip 1/46","preciShip 2/45","sargonShip 0/8","siracusaShip 1/83","soloShip 1/15","steadShip 0/21","swiftShip 1/33","visiShip 1/0"]
|
||||
"bonds": ["arcaneShip 1/30","deputShip 0/14","emptyShip 1/10","kazimierzShip 0/16","kjeragShip 1/51","preciShip 2/50","sargonShip 0/8","siracusaShip 1/81","soloShip 1/15","steadShip 0/21","swiftShip 1/33","visiShip 1/0"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -312,7 +312,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_10","factions":["ELEMENT","DOT","REFLECTION"]},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":8,"bossPoolLeft":0,"virtualMs":107800},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":7,"bossPoolLeft":0,"virtualMs":107800},
|
||||
"rng": {"setup":25,"shop":279,"waves":0,"draft":42,"bots":8378,"meta":87},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -341,23 +341,23 @@
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,19,13,0,2,4,8,"0aa5a1b4",62,"arcaneShip 1/18, kazimierzShip 1/2, kjeragShip 1/13, lateranoShip 0/3, preciShip 1/13, sargonShip 0/2, soloShip 1/0, steadShip 1/8, suntShip 1/0, swiftShip 1/8",28,32,4,75]
|
||||
"ai_0": [1,18,13,0,1,4,8,"426b1da9",62,"arcaneShip 1/18, kazimierzShip 1/2, kjeragShip 1/13, lateranoShip 0/3, preciShip 1/13, sargonShip 0/2, soloShip 1/0, steadShip 1/8, suntShip 1/0, swiftShip 1/8",27,32,5,75]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,19,14,0,1,5,8,"65d67e3b",72,"arcaneShip 1/24, kazimierzShip 1/4, kjeragShip 1/13, lateranoShip 0/3, preciShip 1/13, sargonShip 0/2, soloShip 1/0, steadShip 1/8, suntShip 1/0, swiftShip 1/10",30,30,0,88]
|
||||
"ai_0": [1,18,13,0,1,5,8,"65d67e3b",72,"arcaneShip 1/24, kazimierzShip 1/4, kjeragShip 1/13, lateranoShip 0/3, preciShip 1/13, sargonShip 0/2, soloShip 1/0, steadShip 1/8, suntShip 1/0, swiftShip 1/10",30,30,0,88]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,10,13,0,1,5,8,"0c556348",74,"arcaneShip 1/28, kazimierzShip 1/8, kjeragShip 1/13, lateranoShip 0/3, preciShip 2/17, sargonShip 0/2, soloShip 1/0, steadShip 1/8, suntShip 1/0, swiftShip 0/10",15,24,9,101]
|
||||
"ai_0": [1,9,13,0,1,5,8,"0c556348",74,"arcaneShip 1/28, kazimierzShip 1/8, kjeragShip 1/13, lateranoShip 0/3, preciShip 2/17, sargonShip 0/2, soloShip 1/0, steadShip 1/8, suntShip 1/0, swiftShip 0/10",15,24,9,101]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,8,13,0,2,6,8,"30f54d4c",162,"arcaneShip 2/34, kazimierzShip 1/36, kjeragShip 1/29, lateranoShip 0/3, preciShip 1/25, sargonShip 0/2, steadShip 1/8, suntShip 1/0, swiftShip 1/30",43,45,2,115]
|
||||
"ai_0": [1,7,13,0,2,6,8,"30f54d4c",162,"arcaneShip 2/34, kazimierzShip 1/36, kjeragShip 1/29, lateranoShip 0/3, preciShip 1/25, sargonShip 0/2, steadShip 1/8, suntShip 1/0, swiftShip 1/30",43,45,2,115]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,8,14,0,0,6,8,"09807249",200,"arcaneShip 1/40, kazimierzShip 1/48, kjeragShip 1/37, lateranoShip 0/3, preciShip 2/29, sargonShip 0/2, steadShip 1/8, suntShip 1/0, swiftShip 1/38",29,29,0,129]
|
||||
"ai_0": [1,7,14,0,0,6,8,"09807249",200,"arcaneShip 1/40, kazimierzShip 1/48, kjeragShip 1/37, lateranoShip 0/3, preciShip 2/29, sargonShip 0/2, steadShip 1/8, suntShip 1/0, swiftShip 1/38",29,29,0,129]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -366,12 +366,12 @@
|
||||
"victory": true,
|
||||
"roundsPassed": 14,
|
||||
"eliminatedRound": null,
|
||||
"lp": 8,
|
||||
"lp": 7,
|
||||
"bandId": "band_ducklord",
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 0,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":163,"bossDamage":195000,"dmgDealt":2277741,"gold":141,"itemsEquipped":11,"kills":270,"leaks":21,"lpLost":21,"merges":6,"perfectRounds":9,"refreshes":25},
|
||||
"stats": {"activatedLayers":163,"bossDamage":195000,"dmgDealt":2245026,"gold":141,"itemsEquipped":11,"kills":268,"leaks":22,"lpLost":22,"merges":6,"perfectRounds":9,"refreshes":25},
|
||||
"lineup": ["1_17_b@12,5","3_17_a@12,6","4_20_a@12,7","4_10_b@10,3","2_18_a@10,5[4_11_e_a+1_05_e_b]","1_19_b@10,7","6_17_a@10,8[3_07_e_a+3_04_e_a]","6_19_a@9,5[4_02_e_b+5_03_e_a]"],
|
||||
"bonds": ["arcaneShip 1/48","kazimierzShip 2/48","kjeragShip 0/37","lateranoShip 0/3","preciShip 1/29","sargonShip 0/2","soloShip 1/0","steadShip 0/8","suntShip 1/0","swiftShip 1/38"]
|
||||
}
|
||||
@@ -388,7 +388,7 @@
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m03","bossId":"boss_5","hiddenBossId":"boss_8","factions":["TIMES","DOT","INVISIBLE"]},
|
||||
"end": {"victory":false,"roundsPassed":11,"hiddenReached":false,"hiddenCleared":false,"reason":"eliminated","teamLp":null,"bossPoolLeft":null,"virtualMs":94500},
|
||||
"rng": {"setup":25,"shop":121,"waves":0,"draft":42,"bots":7382,"meta":1},
|
||||
"rng": {"setup":25,"shop":142,"waves":0,"draft":42,"bots":7385,"meta":1},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
{"round":1,"ai_0":[1,27,4,0,0,1,2,"cc1bac8f",0,"sargonShip 0/2, soloShip 1/0",5,5,0,4]},
|
||||
@@ -406,23 +406,23 @@
|
||||
},
|
||||
{
|
||||
"round": 8,
|
||||
"ai_0": [1,22,11,0,0,4,8,"0ccee9fb",70,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/31, soloShip 1/7, steadShip 1/15, swiftShip 0/8",14,19,5,61]
|
||||
"ai_0": [1,23,11,0,0,4,8,"214665a0",66,"deputShip 1/6, emptyShip 1/2, kazimierzShip 0/8, kjeragShip 1/9, preciShip 0/5, sargonShip 0/8, siracusaShip 1/27, soloShip 1/7, steadShip 1/15, swiftShip 0/8",15,19,4,61]
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,22,12,0,0,4,8,"8f39e18f",106,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/45, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
|
||||
"ai_0": [1,23,12,0,0,4,8,"5b26e714",102,"arcaneShip 1/10, deputShip 1/8, emptyShip 1/4, kazimierzShip 0/8, kjeragShip 1/16, preciShip 1/14, sargonShip 0/8, siracusaShip 1/41, soloShip 1/9, steadShip 0/15, swiftShip 0/8",34,34,0,75]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,12,12,0,0,5,8,"c0bb71d6",122,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/18, preciShip 1/16, sargonShip 0/8, siracusaShip 1/49, soloShip 1/11, steadShip 0/15, swiftShip 0/8",14,24,10,86]
|
||||
"ai_0": [1,13,12,0,0,5,8,"c2aed33a",128,"arcaneShip 1/12, deputShip 1/10, emptyShip 1/6, kazimierzShip 0/8, kjeragShip 1/23, preciShip 1/21, sargonShip 0/8, siracusaShip 1/45, soloShip 1/11, steadShip 0/15, swiftShip 0/8",11,24,13,86]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,2,12,0,0,5,8,"f8bd2a4d",162,"arcaneShip 1/18, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/27, preciShip 1/23, sargonShip 0/8, siracusaShip 1/61, soloShip 1/13, steadShip 0/17, swiftShip 0/8",15,34,19,98]
|
||||
"ai_0": [1,3,12,0,0,5,8,"08ebba3b",172,"arcaneShip 1/20, deputShip 1/12, emptyShip 1/8, kazimierzShip 0/8, kjeragShip 1/32, preciShip 1/28, sargonShip 0/8, siracusaShip 1/59, soloShip 1/13, steadShip 0/17, swiftShip 0/8",17,34,17,97]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/20, deputShip 0/14, emptyShip 0/10, kazimierzShip 0/8, kjeragShip 0/34, preciShip 0/30, sargonShip 0/8, siracusaShip 0/65, soloShip 0/15, steadShip 0/17, swiftShip 0/8",6,31,25,109]
|
||||
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/22, deputShip 0/14, emptyShip 0/10, kazimierzShip 0/8, kjeragShip 0/39, preciShip 0/35, sargonShip 0/8, siracusaShip 0/63, soloShip 0/15, steadShip 0/17, swiftShip 0/8",7,31,24,109]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -436,9 +436,9 @@
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 0,
|
||||
"reward": 255,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1615247,"gold":109,"itemsEquipped":12,"kills":225,"leaks":59,"lpLost":35,"merges":2,"perfectRounds":8,"refreshes":6},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1583711,"gold":109,"itemsEquipped":10,"kills":226,"leaks":58,"lpLost":34,"merges":2,"perfectRounds":8,"refreshes":9},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/20","deputShip 0/14","emptyShip 0/10","kazimierzShip 0/8","kjeragShip 0/34","preciShip 0/30","sargonShip 0/8","siracusaShip 0/65","soloShip 0/15","steadShip 0/17","swiftShip 0/8"]
|
||||
"bonds": ["arcaneShip 0/22","deputShip 0/14","emptyShip 0/10","kazimierzShip 0/8","kjeragShip 0/39","preciShip 0/35","sargonShip 0/8","siracusaShip 0/63","soloShip 0/15","steadShip 0/17","swiftShip 0/8"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -477,7 +477,7 @@
|
||||
},
|
||||
{
|
||||
"round": 8,
|
||||
"ai_0": [1,8,11,0,0,4,8,"1d3e40c9",24,"arcaneShip 1/6, kazimierzShip 1/2, kjeragShip 0/8, lateranoShip 0/3, preciShip 0/4, sargonShip 0/2, soloShip 1/0, steadShip 2/8, swiftShip 1/8",19,20,1,61]
|
||||
"ai_0": [1,8,11,0,0,4,8,"b9728d3c",24,"arcaneShip 1/6, kazimierzShip 1/2, kjeragShip 0/8, lateranoShip 0/3, preciShip 0/4, sargonShip 0/2, soloShip 1/0, steadShip 2/8, swiftShip 1/8",19,20,1,61]
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
@@ -495,7 +495,7 @@
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 0,
|
||||
"reward": 170,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":966904,"gold":74,"itemsEquipped":7,"kills":118,"leaks":37,"lpLost":31,"merges":2,"perfectRounds":3,"refreshes":4},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":950038,"gold":74,"itemsEquipped":7,"kills":118,"leaks":37,"lpLost":31,"merges":2,"perfectRounds":3,"refreshes":4},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/14","kazimierzShip 0/2","kjeragShip 0/16","lateranoShip 0/3","preciShip 0/13","sargonShip 0/2","steadShip 0/8","swiftShip 0/8"]
|
||||
}
|
||||
@@ -511,7 +511,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act2autochess_m04","bossId":"boss_3","hiddenBossId":"boss_8","factions":["FLY","TIMES","DOT"]},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":58,"bossPoolLeft":0,"virtualMs":119900},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":55,"bossPoolLeft":0,"virtualMs":119900},
|
||||
"rng": {"setup":25,"shop":449,"waves":0,"draft":40,"bots":21634,"meta":8},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -553,32 +553,32 @@
|
||||
{
|
||||
"round": 8,
|
||||
"ai_0": [1,45,13,0,0,4,8,"870d6315",68,"arcaneShip 2/14, preciShip 0/10, sargonShip 0/10, siracusaShip 1/28, skillfulShip 1/4, soloShip 1/6, suntShip 1/0, swiftShip 1/16",19,19,0,63],
|
||||
"ai_1": [1,28,12,0,0,4,8,"5e8420e4",53,"arcaneShip 1/10, kazimierzShip 1/6, lateranoShip 1/8, preciShip 1/19, sargonShip 0/10, soloShip 1/0, swiftShip 1/10",19,19,0,64]
|
||||
"ai_1": [1,28,12,0,0,4,8,"f830dd03",45,"arcaneShip 1/10, kazimierzShip 1/6, lateranoShip 1/0, preciShip 1/19, sargonShip 0/10, soloShip 1/0, swiftShip 1/10",19,19,0,64]
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,45,12,0,1,4,8,"b71d708f",86,"arcaneShip 2/22, preciShip 0/10, sargonShip 0/10, siracusaShip 1/34, skillfulShip 1/6, soloShip 1/6, suntShip 1/0, swiftShip 1/18",19,20,1,74],
|
||||
"ai_1": [1,28,12,0,1,4,8,"b6ef2d78",59,"arcaneShip 2/14, kazimierzShip 1/6, lateranoShip 0/8, preciShip 1/24, sargonShip 0/10, soloShip 1/0, steadShip 1/0, swiftShip 1/15",20,20,0,76]
|
||||
"ai_1": [1,28,12,0,1,4,8,"b6ef2d78",59,"arcaneShip 2/14, kazimierzShip 1/6, preciShip 1/24, sargonShip 0/10, soloShip 1/0, steadShip 1/0, swiftShip 1/15",20,20,0,76]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,45,13,0,0,5,8,"e786a445",98,"arcaneShip 2/26, preciShip 0/10, sargonShip 0/10, siracusaShip 1/38, skillfulShip 1/8, soloShip 1/6, suntShip 1/0, swiftShip 1/20",7,8,1,87],
|
||||
"ai_1": [1,28,13,0,0,5,8,"ed80e1d9",71,"arcaneShip 2/16, kazimierzShip 1/6, lateranoShip 0/8, preciShip 1/29, sargonShip 0/10, soloShip 1/0, steadShip 1/0, swiftShip 1/20",8,8,0,89]
|
||||
"ai_0": [1,45,13,0,0,5,8,"e786a445",98,"arcaneShip 2/26, preciShip 0/10, sargonShip 0/10, siracusaShip 1/38, skillfulShip 1/8, soloShip 1/6, suntShip 1/0, swiftShip 1/20",8,8,0,87],
|
||||
"ai_1": [1,28,13,0,0,5,8,"6b3add69",71,"arcaneShip 2/16, kazimierzShip 1/6, preciShip 1/29, sargonShip 0/10, soloShip 1/0, steadShip 1/0, swiftShip 1/20",7,8,1,89]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,45,12,0,2,5,8,"360613f3",118,"arcaneShip 2/34, miraShip 1/0, preciShip 0/10, sargonShip 0/10, siracusaShip 1/56, skillfulShip 0/10, soloShip 1/6, suntShip 1/0, swiftShip 1/22",23,23,0,99],
|
||||
"ai_1": [1,28,12,0,0,5,8,"78cc3a2e",131,"arcaneShip 2/28, kazimierzShip 1/22, kjeragShip 0/8, lateranoShip 0/8, preciShip 1/40, sargonShip 0/10, steadShip 1/0, suntShip 1/0, swiftShip 1/41",23,23,0,103]
|
||||
"ai_1": [1,28,12,0,0,5,8,"07be045d",135,"arcaneShip 2/28, kazimierzShip 1/24, kjeragShip 0/8, preciShip 1/40, sargonShip 0/10, steadShip 1/0, suntShip 1/0, swiftShip 1/43",23,23,0,104]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,45,14,0,0,6,8,"d434f9ef",168,"arcaneShip 2/46, miraShip 1/6, preciShip 0/10, sargonShip 0/10, siracusaShip 1/68, skillfulShip 1/18, soloShip 1/6, suntShip 1/0, swiftShip 1/24",105,105,0,113],
|
||||
"ai_1": [1,28,12,0,0,6,8,"57452d77",157,"arcaneShip 2/28, kazimierzShip 1/30, kjeragShip 0/8, lateranoShip 0/8, preciShip 1/45, sargonShip 0/10, steadShip 1/0, suntShip 1/0, swiftShip 1/54",105,105,0,114]
|
||||
"ai_1": [1,28,12,0,0,6,8,"e37fca4e",161,"arcaneShip 2/28, kazimierzShip 1/32, kjeragShip 0/8, preciShip 1/45, sargonShip 0/10, soloShip 1/0, suntShip 1/0, swiftShip 1/56",105,105,0,115]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,37,12,0,2,6,8,"5deeb03a",214,"arcaneShip 2/70, miraShip 1/12, preciShip 0/10, sargonShip 0/10, siracusaShip 1/98, skillfulShip 1/28, soloShip 1/6, suntShip 1/0, swiftShip 0/32",26,34,8,125],
|
||||
"ai_1": [1,21,12,0,0,6,8,"ecba4cc3",189,"arcaneShip 2/34, kazimierzShip 1/38, kjeragShip 0/8, lateranoShip 0/8, preciShip 1/50, sargonShip 0/10, steadShip 1/0, suntShip 1/0, swiftShip 1/67",27,34,7,125]
|
||||
"ai_1": [1,18,12,0,0,6,8,"41dae901",195,"arcaneShip 2/36, kazimierzShip 1/40, kjeragShip 0/8, preciShip 1/50, sargonShip 0/10, steadShip 1/0, suntShip 1/0, swiftShip 1/69",24,34,10,127]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -592,7 +592,7 @@
|
||||
"title": {"id":"comment_2","name":"不朽盟约","picId":"comment_icon_2","text":"激活的盟约层数总和最高"},
|
||||
"trophies": 4,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":250,"bossDamage":283411,"dmgDealt":2891237,"gold":139,"itemsEquipped":12,"kills":329,"leaks":10,"lpLost":8,"merges":5,"perfectRounds":10,"refreshes":23},
|
||||
"stats": {"activatedLayers":250,"bossDamage":287418,"dmgDealt":2928162,"gold":139,"itemsEquipped":12,"kills":331,"leaks":9,"lpLost":8,"merges":5,"perfectRounds":11,"refreshes":23},
|
||||
"lineup": ["3_19_b@11,7[2_04_e_b]","5_12_a@11,8","4_10_a@10,5[1_02_e_b+2_01_e_a]","6_06_a@9,4","1_08_b@9,5","6_16_a@9,7","5_20_a@9,8[3_05_e_a+3_02_e_b]","3_13_b@9,9"],
|
||||
"bonds": ["arcaneShip 2/86","miraShip 1/12","preciShip 0/10","sargonShip 0/10","siracusaShip 1/110","skillfulShip 1/36","soloShip 1/6","suntShip 1/0","swiftShip 0/32"]
|
||||
},
|
||||
@@ -601,14 +601,14 @@
|
||||
"victory": true,
|
||||
"roundsPassed": 14,
|
||||
"eliminatedRound": null,
|
||||
"lp": 21,
|
||||
"lp": 18,
|
||||
"bandId": "band_dusk",
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 4,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":199,"bossDamage":425339,"dmgDealt":3265243,"gold":137,"itemsEquipped":18,"kills":322,"leaks":9,"lpLost":7,"merges":5,"perfectRounds":11,"refreshes":13},
|
||||
"lineup": ["4_20_a@12,8[3_06_e_a]","1_17_b@11,7","4_02_b@11,8[4_08_e_a+4_03_e_b]","4_01_b@10,7[1_02_e_a+3_08_e_a]","6_17_a@10,8[4_06_e_a+1_05_e_a]","6_19_a@9,7[1_01_e_b+4_04_e_a]","4_14_a@9,8[3_02_e_a]","5_07_a@9,9"],
|
||||
"bonds": ["arcaneShip 2/34","kazimierzShip 1/38","kjeragShip 0/8","lateranoShip 0/8","preciShip 2/55","raidShip 1/0","sargonShip 0/10","suntShip 1/0","swiftShip 1/72"]
|
||||
"stats": {"activatedLayers":205,"bossDamage":421332,"dmgDealt":3168659,"gold":139,"itemsEquipped":16,"kills":317,"leaks":13,"lpLost":10,"merges":5,"perfectRounds":10,"refreshes":13},
|
||||
"lineup": ["4_20_a@12,8[4_03_e_b+3_06_e_a]","1_17_b@11,7","4_02_b@11,8[4_08_e_a]","4_01_b@10,7[1_02_e_a]","6_17_a@10,8[4_06_e_a+1_05_e_a]","6_19_a@9,7[3_08_e_a+1_01_e_b]","4_14_a@9,8","5_07_a@9,9"],
|
||||
"bonds": ["arcaneShip 2/36","kazimierzShip 1/40","kjeragShip 0/8","preciShip 2/55","raidShip 1/0","sargonShip 0/10","suntShip 1/0","swiftShip 1/74"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -669,27 +669,27 @@
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,25,12,0,2,4,8,"468d37f7",70,"kazimierzShip 1/19, kjeragShip 0/2, raidShip 1/28, skillfulShip 0/9, soloShip 1/3, steadShip 2/12, suntShip 1/0, swiftShip 1/8",23,23,0,73],
|
||||
"ai_1": [1,18,12,0,1,4,8,"f01fb873",35,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/24, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/0, soloShip 1/0, swiftShip 1/7",18,23,5,78]
|
||||
"ai_1": [1,19,12,0,1,4,8,"f01fb873",39,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/28, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/0, soloShip 1/0, swiftShip 1/7",17,23,6,78]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,23,14,0,1,5,8,"eb530a8d",82,"kazimierzShip 1/25, kjeragShip 0/2, raidShip 1/28, skillfulShip 0/9, soloShip 1/3, steadShip 2/12, suntShip 1/0, swiftShip 1/14",6,8,2,88],
|
||||
"ai_1": [1,14,13,0,0,5,8,"ad2dc598",57,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/37, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/2, soloShip 1/0, suntShip 1/0, swiftShip 1/14",4,8,4,91]
|
||||
"ai_1": [1,15,13,0,0,5,8,"ad2dc598",61,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/41, sargonShip 0/4, siracusaShip 1/4, skillfulShip 1/2, soloShip 1/0, suntShip 1/0, swiftShip 1/14",4,8,4,91]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,13,13,0,1,5,8,"cf13d02e",107,"kazimierzShip 1/33, kjeragShip 0/2, raidShip 1/33, skillfulShip 0/9, soloShip 1/3, steadShip 2/12, suntShip 1/0, swiftShip 1/26",10,27,17,100],
|
||||
"ai_1": [1,4,12,0,0,5,8,"60f9ee96",81,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/46, sargonShip 0/4, siracusaShip 1/10, skillfulShip 1/4, soloShip 1/0, suntShip 1/0, swiftShip 1/21",6,27,21,102]
|
||||
"ai_0": [1,13,13,0,1,5,8,"cf13d02e",107,"kazimierzShip 1/33, kjeragShip 0/2, raidShip 1/33, skillfulShip 0/9, soloShip 1/3, steadShip 2/12, suntShip 1/0, swiftShip 1/26",9,27,18,100],
|
||||
"ai_1": [1,5,12,0,0,5,8,"66c45cf0",83,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 1/50, sargonShip 0/4, siracusaShip 1/8, skillfulShip 1/4, soloShip 1/0, suntShip 1/0, swiftShip 1/21",6,27,21,102]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,3,13,0,0,6,8,"17862185",123,"kazimierzShip 1/39, kjeragShip 0/2, raidShip 1/34, skillfulShip 0/9, soloShip 1/3, steadShip 2/17, suntShip 1/0, swiftShip 1/30, visiShip 1/0",17,50,33,114],
|
||||
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 0/55, sargonShip 0/4, siracusaShip 0/10, skillfulShip 0/6, swiftShip 0/23",22,50,28,114]
|
||||
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 0/59, sargonShip 0/4, siracusaShip 0/8, skillfulShip 0/6, swiftShip 0/23",19,50,31,114]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"kazimierzShip 0/51, kjeragShip 0/2, miraShip 0/7, preciShip 0/8, raidShip 0/34, skillfulShip 0/9, soloShip 0/3, steadShip 0/17, swiftShip 0/38, yanShip 0/6",14,49,35,126],
|
||||
"ai_1": [0,0,0,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 0/55, sargonShip 0/4, siracusaShip 0/10, skillfulShip 0/6, swiftShip 0/23",null,null,null,114]
|
||||
"ai_1": [0,0,0,0,0,6,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/2, preciShip 0/59, sargonShip 0/4, siracusaShip 0/8, skillfulShip 0/6, swiftShip 0/23",null,null,null,114]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -703,7 +703,7 @@
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 3,
|
||||
"reward": 298,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2518112,"gold":126,"itemsEquipped":8,"kills":203,"leaks":87,"lpLost":32,"merges":4,"perfectRounds":9,"refreshes":13},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2550230,"gold":126,"itemsEquipped":8,"kills":204,"leaks":88,"lpLost":32,"merges":4,"perfectRounds":9,"refreshes":13},
|
||||
"lineup": [],
|
||||
"bonds": ["kazimierzShip 0/51","kjeragShip 0/2","miraShip 0/7","preciShip 0/8","raidShip 0/34","skillfulShip 0/9","soloShip 0/3","steadShip 0/17","swiftShip 0/38","yanShip 0/6"]
|
||||
},
|
||||
@@ -717,9 +717,9 @@
|
||||
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
|
||||
"trophies": 2,
|
||||
"reward": 255,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1382343,"gold":114,"itemsEquipped":11,"kills":164,"leaks":69,"lpLost":32,"merges":3,"perfectRounds":5,"refreshes":19},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1355731,"gold":114,"itemsEquipped":11,"kills":160,"leaks":73,"lpLost":31,"merges":3,"perfectRounds":5,"refreshes":19},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/2","kazimierzShip 0/2","preciShip 0/55","sargonShip 0/4","siracusaShip 0/10","skillfulShip 0/6","swiftShip 0/23"]
|
||||
"bonds": ["arcaneShip 0/2","kazimierzShip 0/2","preciShip 0/59","sargonShip 0/4","siracusaShip 0/8","skillfulShip 0/6","swiftShip 0/23"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -733,8 +733,8 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act2autochess_m03","bossId":"boss_4","hiddenBossId":"boss_9","factions":["FLY","TIMES","REFLECTION"]},
|
||||
"end": {"victory":false,"roundsPassed":11,"hiddenReached":false,"hiddenCleared":false,"reason":"eliminated","teamLp":null,"bossPoolLeft":null,"virtualMs":116600},
|
||||
"rng": {"setup":25,"shop":561,"waves":0,"draft":76,"bots":24785,"meta":19},
|
||||
"end": {"victory":false,"roundsPassed":11,"hiddenReached":false,"hiddenCleared":false,"reason":"eliminated","teamLp":null,"bossPoolLeft":null,"virtualMs":115700},
|
||||
"rng": {"setup":25,"shop":537,"waves":0,"draft":75,"bots":24773,"meta":19},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
{
|
||||
@@ -771,7 +771,7 @@
|
||||
"round": 6,
|
||||
"ai_0": [1,23,9,0,0,3,8,"4388934b",42,"deputShip 2/18, kazimierzShip 0/2, skillfulShip 1/8, soloShip 1/4, swiftShip 1/12",24,26,2,42],
|
||||
"ai_1": [1,45,9,0,0,3,8,"50fac57a",25,"deputShip 2/13, kazimierzShip 0/7, skillfulShip 1/4, soloShip 1/4, suntShip 1/4, swiftShip 0/21",26,26,0,41],
|
||||
"ai_2": [1,27,11,0,0,3,8,"973ac812",46,"deputShip 1/6, siracusaShip 1/20, soloShip 1/18, suntShip 1/2, yanShip 0/1",25,26,1,42]
|
||||
"ai_2": [1,27,11,0,0,3,8,"973ac812",46,"deputShip 1/6, siracusaShip 1/20, soloShip 1/18, suntShip 1/2, yanShip 0/1",26,26,0,42]
|
||||
},
|
||||
{
|
||||
"round": 7,
|
||||
@@ -787,43 +787,43 @@
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,3,12,0,0,4,8,"6d558be7",154,"deputShip 2/32, indomShip 1/4, kazimierzShip 0/2, kjeragShip 1/25, skillfulShip 1/51, soloShip 1/16, steadShip 1/22, suntShip 1/4, swiftShip 0/20",57,65,8,81],
|
||||
"ai_1": [1,24,12,0,0,4,8,"ad1959de",111,"deputShip 2/35, kazimierzShip 0/7, skillfulShip 1/22, soloShip 1/16, suntShip 1/16, swiftShip 0/21, victoriaShip 1/22",44,56,12,73],
|
||||
"ai_2": [1,10,12,0,0,4,8,"e0957cd2",127,"deputShip 0/10, miraShip 1/3, siracusaShip 2/78, soloShip 1/22, suntShip 1/6, swiftShip 1/18, yanShip 0/1",57,63,6,75]
|
||||
"ai_0": [1,8,12,0,6,4,8,"6d558be7",157,"deputShip 2/32, indomShip 1/4, kazimierzShip 0/2, kjeragShip 1/28, skillfulShip 1/51, soloShip 1/16, steadShip 1/22, suntShip 1/4, swiftShip 0/20",65,68,3,81],
|
||||
"ai_1": [1,24,12,0,1,4,8,"ad1959de",111,"deputShip 2/35, kazimierzShip 0/7, skillfulShip 1/22, soloShip 1/16, suntShip 1/16, swiftShip 0/21, victoriaShip 1/22",41,52,11,73],
|
||||
"ai_2": [1,7,12,0,0,4,8,"e0957cd2",127,"deputShip 0/10, miraShip 1/3, siracusaShip 2/78, soloShip 1/22, suntShip 1/6, swiftShip 1/18, yanShip 0/1",51,60,9,75]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,3,12,0,0,5,8,"f8b9abf3",197,"deputShip 2/36, indomShip 1/8, kazimierzShip 0/2, kjeragShip 1/35, skillfulShip 1/57, soloShip 1/20, steadShip 1/33, suntShip 1/8, swiftShip 0/20",18,18,0,92],
|
||||
"ai_1": [1,17,12,0,0,5,8,"6f5bb81b",124,"deputShip 2/40, indomShip 1/5, kazimierzShip 0/7, skillfulShip 1/26, soloShip 1/20, suntShip 0/16, swiftShip 0/21, victoriaShip 1/33",3,18,15,85],
|
||||
"ai_2": [1,3,12,0,2,5,8,"b6b17abc",137,"deputShip 0/10, miraShip 1/4, siracusaShip 2/82, soloShip 1/22, suntShip 1/6, swiftShip 1/23, yanShip 0/1",8,18,10,86]
|
||||
"ai_0": [1,8,18,0,0,5,8,"7365b613",207,"deputShip 2/36, indomShip 1/8, kazimierzShip 0/2, kjeragShip 1/41, miraShip 1/4, skillfulShip 1/57, soloShip 1/20, steadShip 1/33, suntShip 1/8, swiftShip 0/20",18,18,0,99],
|
||||
"ai_1": [1,15,13,0,0,5,8,"776e574d",124,"deputShip 2/40, indomShip 1/5, kazimierzShip 0/7, skillfulShip 1/26, soloShip 1/20, suntShip 0/16, swiftShip 0/21, victoriaShip 1/33",3,18,15,86],
|
||||
"ai_2": [0,0,12,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/5, siracusaShip 0/84, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",5,18,13,86]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [0,0,12,0,0,5,0,"811c9dc5",0,"deputShip 0/38, indomShip 0/10, kazimierzShip 0/2, kjeragShip 0/41, skillfulShip 0/65, soloShip 0/22, steadShip 0/42, suntShip 0/10, swiftShip 0/26",22,25,3,103],
|
||||
"ai_1": [1,7,12,0,0,5,8,"a9a4015c",177,"deputShip 2/45, indomShip 1/28, kazimierzShip 0/7, skillfulShip 1/30, soloShip 1/24, steadShip 1/8, suntShip 0/16, swiftShip 0/21, victoriaShip 1/42",7,25,18,98],
|
||||
"ai_2": [0,0,14,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/7, preciShip 0/5, siracusaShip 0/104, soloShip 0/22, suntShip 0/6, swiftShip 0/28, yanShip 0/1",9,25,16,100]
|
||||
"ai_0": [1,3,12,0,1,5,8,"d2be236f",254,"deputShip 2/40, indomShip 1/12, kazimierzShip 0/2, kjeragShip 1/51, miraShip 1/8, siracusaShip 0/6, skillfulShip 1/63, soloShip 1/24, steadShip 1/44, suntShip 1/12, swiftShip 0/26",20,25,5,110],
|
||||
"ai_1": [1,5,12,0,0,5,8,"3d8f81b8",150,"deputShip 1/42, indomShip 1/11, kazimierzShip 0/7, skillfulShip 1/28, soloShip 0/20, suntShip 0/16, swiftShip 0/21, victoriaShip 2/69, yanShip 0/5",7,25,18,98],
|
||||
"ai_2": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/5, siracusaShip 0/84, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",null,null,null,86]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/38, indomShip 0/10, kazimierzShip 0/2, kjeragShip 0/41, skillfulShip 0/65, soloShip 0/22, steadShip 0/42, suntShip 0/10, swiftShip 0/26",null,null,null,103],
|
||||
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"deputShip 0/48, indomShip 0/54, kazimierzShip 0/11, skillfulShip 0/32, soloShip 0/26, steadShip 0/8, suntShip 0/16, swiftShip 0/27, victoriaShip 0/49",4,57,53,111],
|
||||
"ai_2": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/7, preciShip 0/5, siracusaShip 0/104, soloShip 0/22, suntShip 0/6, swiftShip 0/28, yanShip 0/1",null,null,null,100]
|
||||
"ai_0": [0,0,13,0,0,6,0,"811c9dc5",0,"deputShip 0/44, indomShip 0/16, kazimierzShip 0/2, kjeragShip 0/62, miraShip 0/12, siracusaShip 0/6, skillfulShip 0/69, soloShip 0/28, steadShip 0/55, suntShip 0/16, swiftShip 0/26",16,57,41,124],
|
||||
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"deputShip 0/44, indomShip 0/19, kazimierzShip 0/7, skillfulShip 0/30, soloShip 0/20, suntShip 0/16, swiftShip 0/21, victoriaShip 0/102, yanShip 0/5",24,57,33,109],
|
||||
"ai_2": [0,0,0,0,0,5,0,"811c9dc5",0,"deputShip 0/10, miraShip 0/5, siracusaShip 0/84, soloShip 0/22, suntShip 0/6, swiftShip 0/23, yanShip 0/1",null,null,null,86]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
"ai_0": {
|
||||
"alive": false,
|
||||
"victory": false,
|
||||
"roundsPassed": 10,
|
||||
"eliminatedRound": 11,
|
||||
"roundsPassed": 11,
|
||||
"eliminatedRound": 12,
|
||||
"lp": 0,
|
||||
"bandId": "band_chiave",
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 2,
|
||||
"reward": 213,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":4040284,"gold":103,"itemsEquipped":14,"kills":258,"leaks":32,"lpLost":23,"merges":3,"perfectRounds":4,"refreshes":10},
|
||||
"reward": 255,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":4759668,"gold":124,"itemsEquipped":17,"kills":280,"leaks":70,"lpLost":30,"merges":3,"perfectRounds":4,"refreshes":14},
|
||||
"lineup": [],
|
||||
"bonds": ["deputShip 0/38","indomShip 0/10","kazimierzShip 0/2","kjeragShip 0/41","skillfulShip 0/65","soloShip 0/22","steadShip 0/42","suntShip 0/10","swiftShip 0/26"]
|
||||
"bonds": ["deputShip 0/44","indomShip 0/16","kazimierzShip 0/2","kjeragShip 0/62","miraShip 0/12","siracusaShip 0/6","skillfulShip 0/69","soloShip 0/28","steadShip 0/55","suntShip 0/16","swiftShip 0/26"]
|
||||
},
|
||||
"ai_1": {
|
||||
"alive": false,
|
||||
@@ -835,23 +835,23 @@
|
||||
"title": {"id":"comment_6","name":"挥金如土","picId":"comment_icon_6","text":"消耗资金最多"},
|
||||
"trophies": 2,
|
||||
"reward": 255,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1816653,"gold":111,"itemsEquipped":10,"kills":244,"leaks":113,"lpLost":48,"merges":3,"perfectRounds":5,"refreshes":17},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2690412,"gold":109,"itemsEquipped":9,"kills":258,"leaks":92,"lpLost":50,"merges":3,"perfectRounds":5,"refreshes":18},
|
||||
"lineup": [],
|
||||
"bonds": ["deputShip 0/48","indomShip 0/54","kazimierzShip 0/11","skillfulShip 0/32","soloShip 0/26","steadShip 0/8","suntShip 0/16","swiftShip 0/27","victoriaShip 0/49"]
|
||||
"bonds": ["deputShip 0/44","indomShip 0/19","kazimierzShip 0/7","skillfulShip 0/30","soloShip 0/20","suntShip 0/16","swiftShip 0/21","victoriaShip 0/102","yanShip 0/5"]
|
||||
},
|
||||
"ai_2": {
|
||||
"alive": false,
|
||||
"victory": false,
|
||||
"roundsPassed": 10,
|
||||
"eliminatedRound": 11,
|
||||
"roundsPassed": 9,
|
||||
"eliminatedRound": 10,
|
||||
"lp": 0,
|
||||
"bandId": "band_lmlee",
|
||||
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
|
||||
"trophies": 2,
|
||||
"reward": 213,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2018115,"gold":100,"itemsEquipped":7,"kills":214,"leaks":56,"lpLost":34,"merges":3,"perfectRounds":3,"refreshes":22},
|
||||
"reward": 191,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":1500871,"gold":86,"itemsEquipped":5,"kills":199,"leaks":45,"lpLost":28,"merges":2,"perfectRounds":4,"refreshes":14},
|
||||
"lineup": [],
|
||||
"bonds": ["deputShip 0/10","miraShip 0/7","preciShip 0/5","siracusaShip 0/104","soloShip 0/22","suntShip 0/6","swiftShip 0/28","yanShip 0/1"]
|
||||
"bonds": ["deputShip 0/10","miraShip 0/5","siracusaShip 0/84","soloShip 0/22","suntShip 0/6","swiftShip 0/23","yanShip 0/1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -865,7 +865,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m01","bossId":"boss_3","hiddenBossId":null,"factions":["TIMES","ELEMENT","REFLECTION"]},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":130,"bossPoolLeft":0,"virtualMs":133000},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":129,"bossPoolLeft":0,"virtualMs":133000},
|
||||
"rng": {"setup":16,"shop":893,"waves":0,"draft":25,"bots":35892,"meta":29},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -928,37 +928,37 @@
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,26,12,0,0,4,8,"fc454676",169,"deputShip 1/47, kjeragShip 0/2, preciShip 2/40, sargonShip 1/44, steadShip 1/38",30,30,0,74],
|
||||
"ai_1": [1,45,12,0,0,4,8,"13fccde5",83,"deputShip 2/48, emptyShip 1/4, preciShip 0/4, sargonShip 0/2, siracusaShip 1/31, steadShip 0/4",30,30,0,70],
|
||||
"ai_1": [1,44,12,0,0,4,8,"13fccde5",83,"deputShip 2/48, emptyShip 1/4, preciShip 0/4, sargonShip 0/2, siracusaShip 1/31, steadShip 0/4",26,30,4,70],
|
||||
"ai_2": [1,28,12,0,0,4,8,"6965081a",70,"sargonShip 0/8, siracusaShip 1/58, swiftShip 1/12, visiShip 1/0, yanShip 0/1",30,30,0,72],
|
||||
"ai_3": [1,31,13,0,0,4,8,"5f784848",153,"deputShip 1/16, emptyShip 1/12, kjeragShip 1/30, preciShip 1/72, siracusaShip 0/3, swiftShip 1/23, yanShip 0/1",30,30,0,76]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,26,12,0,0,5,8,"2b6a123a",243,"deputShip 1/53, kjeragShip 0/2, preciShip 2/72, sargonShip 1/70, steadShip 1/48",29,29,0,86],
|
||||
"ai_1": [1,45,12,0,0,5,8,"549957f7",105,"deputShip 2/58, emptyShip 1/8, preciShip 0/4, sargonShip 0/2, siracusaShip 1/39, steadShip 0/4",28,29,1,82],
|
||||
"ai_1": [1,44,12,0,0,5,8,"5bcc6998",105,"deputShip 2/58, emptyShip 1/8, preciShip 0/4, sargonShip 0/2, siracusaShip 1/39, steadShip 0/4",29,29,0,82],
|
||||
"ai_2": [1,28,12,0,0,5,8,"fe139ef2",72,"sargonShip 0/8, siracusaShip 2/60, swiftShip 1/12, visiShip 1/0, yanShip 0/1",29,29,0,83],
|
||||
"ai_3": [1,31,12,0,0,5,8,"9ce217c6",161,"deputShip 1/18, emptyShip 0/12, kjeragShip 2/32, preciShip 1/81, siracusaShip 0/3, swiftShip 1/30, yanShip 0/1",29,29,0,88]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,26,12,0,0,5,8,"5c1d4d08",291,"deputShip 1/55, kjeragShip 0/2, preciShip 1/88, sargonShip 1/90, steadShip 1/58",28,28,0,99],
|
||||
"ai_1": [1,45,12,0,0,5,8,"28ba083d",133,"deputShip 2/68, emptyShip 1/15, preciShip 0/4, sargonShip 0/2, siracusaShip 1/50, steadShip 0/4",13,28,15,94],
|
||||
"ai_2": [1,28,12,0,0,5,8,"8321f307",130,"emptyShip 1/0, sargonShip 0/8, siracusaShip 2/106, swiftShip 1/24, yanShip 0/1",28,28,0,95],
|
||||
"ai_3": [1,31,12,0,0,5,7,"5e2bfa81",195,"deputShip 0/18, emptyShip 0/12, kjeragShip 2/68, preciShip 1/92, siracusaShip 0/3, swiftShip 1/35, visiShip 1/0, yanShip 0/1",28,28,0,98]
|
||||
"ai_1": [1,44,12,0,0,5,8,"28ba083d",133,"deputShip 2/68, emptyShip 1/15, preciShip 0/4, sargonShip 0/2, siracusaShip 1/50, steadShip 0/4",13,28,15,94],
|
||||
"ai_2": [1,28,12,0,0,5,8,"8321f307",126,"emptyShip 1/0, sargonShip 0/8, siracusaShip 2/102, swiftShip 1/24, yanShip 0/1",28,28,0,95],
|
||||
"ai_3": [1,31,12,0,0,5,7,"5e2bfa81",193,"deputShip 0/18, emptyShip 0/12, kjeragShip 2/66, preciShip 1/92, siracusaShip 0/3, swiftShip 1/35, visiShip 1/0, yanShip 0/1",28,28,0,98]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,26,12,0,0,6,8,"934bb983",409,"deputShip 1/57, emptyShip 1/2, kjeragShip 0/2, preciShip 1/138, sargonShip 1/144, steadShip 1/68",46,46,0,111],
|
||||
"ai_1": [1,45,12,0,0,6,8,"f1340001",155,"deputShip 2/78, emptyShip 1/19, preciShip 0/4, sargonShip 0/2, siracusaShip 1/58, steadShip 0/4",20,46,26,104],
|
||||
"ai_2": [1,28,12,0,0,6,8,"696f5ca3",184,"emptyShip 1/0, sargonShip 0/8, siracusaShip 2/160, swiftShip 1/24, yanShip 0/1",46,46,0,106],
|
||||
"ai_3": [1,31,12,0,0,6,8,"2e3cd509",247,"deputShip 0/18, emptyShip 0/12, kjeragShip 2/108, preciShip 2/99, siracusaShip 0/3, swiftShip 1/40, visiShip 1/0, yanShip 0/1",46,46,0,110]
|
||||
"ai_1": [1,44,12,0,0,6,8,"d4b1958d",155,"deputShip 2/78, emptyShip 1/19, preciShip 0/4, sargonShip 0/2, siracusaShip 1/58, steadShip 0/4",20,46,26,104],
|
||||
"ai_2": [1,28,12,0,0,6,8,"696f5ca3",172,"emptyShip 1/0, sargonShip 0/8, siracusaShip 2/148, swiftShip 1/24, yanShip 0/1",46,46,0,106],
|
||||
"ai_3": [1,31,12,0,0,6,8,"2e3cd509",245,"deputShip 0/18, emptyShip 0/12, kjeragShip 2/106, preciShip 2/99, siracusaShip 0/3, swiftShip 1/40, visiShip 1/0, yanShip 0/1",46,46,0,110]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,26,12,0,0,6,8,"2df19066",463,"deputShip 1/59, emptyShip 1/4, kjeragShip 0/7, preciShip 2/156, sargonShip 1/166, steadShip 1/78",32,32,0,126],
|
||||
"ai_1": [1,45,12,0,2,6,8,"9346fb5a",177,"deputShip 1/86, emptyShip 1/21, preciShip 1/6, sargonShip 0/2, siracusaShip 1/64, steadShip 0/4",32,32,0,115],
|
||||
"ai_2": [1,28,12,0,0,6,8,"0236b2a3",260,"emptyShip 1/0, sargonShip 0/8, siracusaShip 2/236, swiftShip 1/24, yanShip 0/1",32,32,0,117],
|
||||
"ai_3": [1,31,12,0,0,6,7,"ceba29b5",265,"deputShip 0/18, emptyShip 0/12, kjeragShip 1/116, preciShip 2/104, siracusaShip 0/3, swiftShip 1/45, yanShip 0/1",32,32,0,124]
|
||||
"ai_1": [1,44,12,0,2,6,8,"9346fb5a",177,"deputShip 1/86, emptyShip 1/21, preciShip 1/6, sargonShip 0/2, siracusaShip 1/64, steadShip 0/4",32,32,0,115],
|
||||
"ai_2": [1,28,12,0,0,6,8,"0236b2a3",238,"emptyShip 1/0, sargonShip 0/8, siracusaShip 2/214, swiftShip 1/24, yanShip 0/1",32,32,0,117],
|
||||
"ai_3": [1,31,12,0,0,6,7,"ceba29b5",263,"deputShip 0/18, emptyShip 0/12, kjeragShip 1/114, preciShip 2/104, siracusaShip 0/3, swiftShip 1/45, yanShip 0/1",32,32,0,124]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
@@ -972,7 +972,7 @@
|
||||
"title": {"id":"comment_2","name":"不朽盟约","picId":"comment_icon_2","text":"激活的盟约层数总和最高"},
|
||||
"trophies": 3,
|
||||
"reward": 250,
|
||||
"stats": {"activatedLayers":485,"bossDamage":46721,"dmgDealt":1696544,"gold":140,"itemsEquipped":25,"kills":325,"leaks":0,"lpLost":0,"merges":5,"perfectRounds":13,"refreshes":21},
|
||||
"stats": {"activatedLayers":485,"bossDamage":46721,"dmgDealt":1702122,"gold":140,"itemsEquipped":25,"kills":327,"leaks":0,"lpLost":0,"merges":5,"perfectRounds":13,"refreshes":21},
|
||||
"lineup": ["6_08_a@11,6[3_03_e_a+3_02_e_a]","6_12_a@11,7[4_08_e_a+6_07_e_b]","2_14_b@10,3","2_17_b@10,4[4_02_e_b+5_01_e_a]","2_08_a@9,3[4_04_e_a+1_01_e_b]","6_06_a@9,4[3_08_e_a+3_01_e_b]","1_06_b@9,8","5_02_b@9,9[5_02_e_a+3_06_e_b]"],
|
||||
"bonds": ["deputShip 1/61","emptyShip 1/6","kjeragShip 0/7","preciShip 2/158","sargonShip 1/172","steadShip 1/88"]
|
||||
},
|
||||
@@ -981,12 +981,12 @@
|
||||
"victory": true,
|
||||
"roundsPassed": 14,
|
||||
"eliminatedRound": null,
|
||||
"lp": 45,
|
||||
"lp": 44,
|
||||
"bandId": "band_sarkazb",
|
||||
"title": {"id":"comment_3","name":"坚若磐石","picId":"comment_icon_3","text":"目标生命值损失最少"},
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 3,
|
||||
"reward": 250,
|
||||
"stats": {"activatedLayers":207,"bossDamage":12338,"dmgDealt":1294439,"gold":129,"itemsEquipped":20,"kills":240,"leaks":43,"lpLost":0,"merges":6,"perfectRounds":9,"refreshes":20},
|
||||
"stats": {"activatedLayers":207,"bossDamage":11652,"dmgDealt":1287691,"gold":129,"itemsEquipped":20,"kills":237,"leaks":46,"lpLost":1,"merges":6,"perfectRounds":9,"refreshes":20},
|
||||
"lineup": ["2_14_b@12,3","5_10_a@11,6[4_03_e_b+1_02_e_a]","6_01_a@11,7[3_05_e_a]","5_10_a@11,8[5_09_e_a+4_08_e_b]","6_14_a@10,3","4_16_a@10,8[4_11_e_a+4_04_e_b]","6_05_a@9,8[1_05_e_a+5_03_e_a]","2_16_a@9,9[5_02_e_a+4_05_e_b]"],
|
||||
"bonds": ["deputShip 1/96","emptyShip 1/23","preciShip 1/14","sargonShip 0/2","siracusaShip 1/74","steadShip 0/4"]
|
||||
},
|
||||
@@ -997,12 +997,12 @@
|
||||
"eliminatedRound": null,
|
||||
"lp": 28,
|
||||
"bandId": "band_mlyss",
|
||||
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
|
||||
"title": {"id":"comment_3","name":"坚若磐石","picId":"comment_icon_3","text":"目标生命值损失最少"},
|
||||
"trophies": 3,
|
||||
"reward": 250,
|
||||
"stats": {"activatedLayers":282,"bossDamage":72960,"dmgDealt":1633867,"gold":127,"itemsEquipped":20,"kills":283,"leaks":0,"lpLost":0,"merges":3,"perfectRounds":13,"refreshes":16},
|
||||
"stats": {"activatedLayers":260,"bossDamage":82751,"dmgDealt":1633721,"gold":127,"itemsEquipped":20,"kills":283,"leaks":0,"lpLost":0,"merges":3,"perfectRounds":13,"refreshes":16},
|
||||
"lineup": ["4_25_a@12,3","1_07_b@11,7[1_01_e_a+1_05_e_a]","5_20_a@11,8[3_02_e_a+2_01_e_b]","6_18_a@10,3[2_01_e_b+4_03_e_b]","4_10_a@10,7[4_03_e_b]","3_18_b@9,4[3_07_e_b+3_11_e_a]","6_05_a@9,8","2_16_b@9,9[5_01_e_a+4_02_e_a]"],
|
||||
"bonds": ["sargonShip 0/8","siracusaShip 2/258","swiftShip 1/24","yanShip 0/1"]
|
||||
"bonds": ["sargonShip 0/8","siracusaShip 2/236","swiftShip 1/24","yanShip 0/1"]
|
||||
},
|
||||
"ai_3": {
|
||||
"alive": true,
|
||||
@@ -1014,9 +1014,9 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 3,
|
||||
"reward": 250,
|
||||
"stats": {"activatedLayers":311,"bossDamage":152981,"dmgDealt":1749981,"gold":138,"itemsEquipped":36,"kills":284,"leaks":0,"lpLost":0,"merges":3,"perfectRounds":13,"refreshes":23},
|
||||
"stats": {"activatedLayers":309,"bossDamage":143876,"dmgDealt":1729660,"gold":138,"itemsEquipped":36,"kills":284,"leaks":0,"lpLost":0,"merges":3,"perfectRounds":13,"refreshes":23},
|
||||
"lineup": ["3_20_b@12,8[5_02_e_b+6_03_e_a]","6_14_a@11,3","4_13_b@11,6[5_02_e_b+4_07_e_a]","6_01_a@11,7[3_11_e_a+3_04_e_a]","4_14_a@11,8[4_03_e_a+1_02_e_a]","4_22_a@10,8[4_04_e_b+4_02_e_a]","3_11_b@9,8[4_09_e_a+3_07_e_a]","5_14_a@9,9[4_06_e_b+2_01_e_b]"],
|
||||
"bonds": ["deputShip 1/20","emptyShip 0/12","kjeragShip 1/120","preciShip 2/117","siracusaShip 0/3","swiftShip 1/54","yanShip 0/1"]
|
||||
"bonds": ["deputShip 1/20","emptyShip 0/12","kjeragShip 1/118","preciShip 2/117","siracusaShip 0/3","swiftShip 1/54","yanShip 0/1"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1030,7 +1030,7 @@
|
||||
"combat": "client",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act2autochess_m01","bossId":"boss_1","hiddenBossId":"boss_8","factions":["DOT","INVISIBLE","REFLECTION"]},
|
||||
"end": {"victory":false,"roundsPassed":11,"hiddenReached":false,"hiddenCleared":false,"reason":"eliminated","teamLp":null,"bossPoolLeft":null,"virtualMs":117800},
|
||||
"end": {"victory":false,"roundsPassed":11,"hiddenReached":false,"hiddenCleared":false,"reason":"eliminated","teamLp":null,"bossPoolLeft":null,"virtualMs":119300},
|
||||
"rng": {"setup":25,"shop":460,"waves":0,"draft":65,"bots":18743,"meta":57},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
@@ -1064,7 +1064,7 @@
|
||||
},
|
||||
{
|
||||
"round": 5,
|
||||
"ai_0": [1,35,9,0,0,3,8,"e59cd7fb",8,"arcaneShip 0/8, kazimierzShip 0/4, preciShip 0/8, swiftShip 1/8",5,17,12,32],
|
||||
"ai_0": [1,35,9,0,0,3,8,"17121de7",8,"arcaneShip 0/8, kazimierzShip 0/4, preciShip 0/8, swiftShip 1/8",5,17,12,32],
|
||||
"ai_1": [1,16,9,0,0,3,8,"0a827c34",8,"arcaneShip 1/2, kazimierzShip 0/5, kjeragShip 0/2, preciShip 0/2, sargonShip 0/4, soloShip 1/0, steadShip 0/2, swiftShip 1/6",5,17,12,30],
|
||||
"ai_2": [1,21,11,0,0,3,8,"26900631",22,"deputShip 1/10, kazimierzShip 0/4, kjeragShip 0/10, skillfulShip 0/2, soloShip 1/4, steadShip 0/4, swiftShip 1/8, victoriaShip 0/10, yanShip 0/4",10,17,7,32],
|
||||
"ai_3": [1,16,9,0,0,3,8,"2cd3b560",5,"arcaneShip 1/4, preciShip 0/2, sargonShip 0/2, siracusaShip 1/0, soloShip 1/1",2,17,15,33]
|
||||
@@ -1072,50 +1072,50 @@
|
||||
{
|
||||
"round": 6,
|
||||
"ai_0": [1,35,9,0,0,3,8,"844b219a",33,"arcaneShip 0/8, kazimierzShip 0/4, kjeragShip 0/5, preciShip 2/20, suntShip 1/0, swiftShip 1/13",14,14,0,41],
|
||||
"ai_1": [1,16,9,0,1,3,8,"3e9da7ea",26,"arcaneShip 1/2, kazimierzShip 1/11, kjeragShip 0/2, preciShip 0/2, sargonShip 0/4, siracusaShip 0/6, soloShip 1/0, steadShip 0/2, swiftShip 1/13",11,14,3,40],
|
||||
"ai_1": [1,16,9,0,1,3,8,"3e9da7ea",26,"arcaneShip 1/2, kazimierzShip 1/11, kjeragShip 0/2, preciShip 0/2, sargonShip 0/4, siracusaShip 0/6, soloShip 1/0, steadShip 0/2, swiftShip 1/13",10,14,4,40],
|
||||
"ai_2": [1,21,9,0,0,3,8,"524a7cff",51,"deputShip 1/12, egirShip 0/2, kazimierzShip 0/4, kjeragShip 0/12, raidShip 0/2, skillfulShip 0/4, soloShip 1/6, steadShip 2/18, swiftShip 1/15, victoriaShip 0/10, yanShip 0/4",14,14,0,41],
|
||||
"ai_3": [1,16,10,0,0,3,8,"ae19c686",28,"arcaneShip 2/9, deputShip 1/2, preciShip 0/2, sargonShip 0/2, siracusaShip 1/11, soloShip 1/6",8,14,6,45]
|
||||
},
|
||||
{
|
||||
"round": 7,
|
||||
"ai_0": [1,25,10,0,0,4,8,"fa19dc02",65,"arcaneShip 0/8, kazimierzShip 1/14, kjeragShip 0/5, preciShip 2/27, suntShip 1/0, swiftShip 1/24",7,21,14,52],
|
||||
"ai_1": [1,6,11,0,0,4,8,"bad83463",33,"arcaneShip 2/2, kazimierzShip 1/18, kjeragShip 0/2, preciShip 0/2, sargonShip 0/8, siracusaShip 0/6, steadShip 0/2, swiftShip 1/13",5,21,16,51],
|
||||
"ai_2": [1,18,10,0,2,4,8,"3c8cf7f7",81,"deputShip 1/16, egirShip 0/4, kazimierzShip 0/4, kjeragShip 0/12, raidShip 0/4, skillfulShip 0/4, soloShip 1/10, steadShip 2/36, swiftShip 1/19, victoriaShip 0/12, yanShip 0/4",18,21,3,51],
|
||||
"ai_0": [1,25,10,0,0,4,8,"fa19dc02",65,"arcaneShip 0/8, kazimierzShip 1/14, kjeragShip 0/5, preciShip 2/27, suntShip 1/0, swiftShip 1/24",8,21,13,52],
|
||||
"ai_1": [1,6,11,0,0,4,8,"8016e17e",33,"arcaneShip 2/2, kazimierzShip 1/18, kjeragShip 0/2, preciShip 0/2, sargonShip 0/8, siracusaShip 0/6, steadShip 0/2, swiftShip 1/13",4,21,17,51],
|
||||
"ai_2": [1,21,10,0,2,4,8,"4889cc01",78,"deputShip 1/16, egirShip 0/4, kazimierzShip 0/4, kjeragShip 0/12, raidShip 0/4, skillfulShip 0/6, soloShip 1/8, steadShip 2/33, swiftShip 1/21, victoriaShip 0/12, yanShip 0/4",21,21,0,51],
|
||||
"ai_3": [1,6,11,0,0,4,8,"7ba63894",45,"arcaneShip 2/14, deputShip 1/4, preciShip 0/2, sargonShip 0/2, siracusaShip 1/19, soloShip 1/8",2,21,19,56]
|
||||
},
|
||||
{
|
||||
"round": 8,
|
||||
"ai_0": [1,18,11,0,0,4,8,"78106ce5",96,"arcaneShip 2/11, kazimierzShip 1/22, kjeragShip 0/5, preciShip 2/34, suntShip 1/0, swiftShip 1/29",2,9,7,63],
|
||||
"ai_0": [1,19,11,0,0,4,8,"78106ce5",93,"arcaneShip 2/8, kazimierzShip 1/22, kjeragShip 0/5, preciShip 2/34, suntShip 1/0, swiftShip 1/29",3,9,6,63],
|
||||
"ai_1": [0,0,11,0,0,4,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/25, kjeragShip 0/7, preciShip 0/2, sargonShip 0/8, siracusaShip 0/12, skillfulShip 0/5, steadShip 0/2, swiftShip 0/19",0,9,9,62],
|
||||
"ai_2": [1,15,13,0,0,4,8,"eff86771",116,"deputShip 1/20, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/12, lateranoShip 0/2, raidShip 0/6, skillfulShip 0/4, soloShip 1/14, steadShip 2/49, swiftShip 1/33, victoriaShip 0/14, yanShip 0/4",6,9,3,64],
|
||||
"ai_2": [1,18,13,0,0,4,8,"eff86771",113,"deputShip 1/20, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/12, lateranoShip 0/2, raidShip 0/6, skillfulShip 0/6, soloShip 1/12, steadShip 2/46, swiftShip 1/35, victoriaShip 0/14, yanShip 0/4",6,9,3,64],
|
||||
"ai_3": [0,0,12,0,0,4,0,"811c9dc5",0,"arcaneShip 0/18, deputShip 0/6, miraShip 0/4, preciShip 0/4, sargonShip 0/2, siracusaShip 0/31, skillfulShip 0/2, soloShip 0/10",2,9,7,68]
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,18,12,0,1,4,8,"a359f7ee",124,"arcaneShip 1/11, indomShip 1/2, kazimierzShip 1/34, kjeragShip 0/5, preciShip 2/43, suntShip 1/0, swiftShip 1/34",6,19,13,76],
|
||||
"ai_0": [1,18,12,0,1,4,8,"a359f7ee",121,"arcaneShip 1/8, indomShip 1/2, kazimierzShip 1/34, kjeragShip 0/5, preciShip 2/43, suntShip 1/0, swiftShip 1/34",6,19,13,76],
|
||||
"ai_1": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/25, kjeragShip 0/7, preciShip 0/2, sargonShip 0/8, siracusaShip 0/12, skillfulShip 0/5, steadShip 0/2, swiftShip 0/19",null,null,null,62],
|
||||
"ai_2": [1,15,12,0,1,4,8,"8df12b45",146,"deputShip 0/22, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/12, lateranoShip 0/2, preciShip 0/2, raidShip 0/6, skillfulShip 1/6, soloShip 1/14, steadShip 1/54, suntShip 1/0, swiftShip 1/47, victoriaShip 1/25, yanShip 0/13",19,19,0,76],
|
||||
"ai_2": [1,18,12,0,1,4,8,"8df12b45",145,"deputShip 0/22, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/12, lateranoShip 0/2, preciShip 0/2, raidShip 0/6, skillfulShip 1/8, soloShip 1/12, steadShip 1/51, suntShip 1/0, swiftShip 1/49, victoriaShip 1/25, yanShip 0/13",19,19,0,76],
|
||||
"ai_3": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/18, deputShip 0/6, miraShip 0/4, preciShip 0/4, sargonShip 0/2, siracusaShip 0/31, skillfulShip 0/2, soloShip 0/10",null,null,null,68]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,18,13,0,0,5,8,"1c690635",148,"arcaneShip 1/11, indomShip 1/4, kazimierzShip 1/42, kjeragShip 0/5, preciShip 2/52, suntShip 1/0, swiftShip 1/39",16,25,9,88],
|
||||
"ai_0": [1,18,13,0,0,5,8,"1c690635",145,"arcaneShip 1/8, indomShip 1/4, kazimierzShip 1/42, kjeragShip 0/5, preciShip 2/52, suntShip 1/0, swiftShip 1/39",17,25,8,88],
|
||||
"ai_1": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/25, kjeragShip 0/7, preciShip 0/2, sargonShip 0/8, siracusaShip 0/12, skillfulShip 0/5, steadShip 0/2, swiftShip 0/19",null,null,null,62],
|
||||
"ai_2": [1,15,13,0,0,5,8,"0e4a12ab",176,"deputShip 0/24, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/12, lateranoShip 0/4, preciShip 0/2, raidShip 0/6, skillfulShip 1/10, soloShip 1/14, steadShip 1/60, suntShip 1/0, swiftShip 1/61, victoriaShip 1/31, yanShip 0/15",25,25,0,89],
|
||||
"ai_2": [1,18,13,0,0,5,8,"0e4a12ab",175,"deputShip 0/24, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/12, lateranoShip 0/4, preciShip 0/2, raidShip 0/6, skillfulShip 1/12, soloShip 1/12, steadShip 1/57, suntShip 1/0, swiftShip 1/63, victoriaShip 1/31, yanShip 0/15",25,25,0,89],
|
||||
"ai_3": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/18, deputShip 0/6, miraShip 0/4, preciShip 0/4, sargonShip 0/2, siracusaShip 0/31, skillfulShip 0/2, soloShip 0/10",null,null,null,68]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,8,12,0,1,5,8,"88de4e65",216,"arcaneShip 1/11, indomShip 0/4, kazimierzShip 1/68, kjeragShip 0/5, preciShip 2/74, raidShip 1/12, suntShip 1/0, swiftShip 1/51",13,25,12,100],
|
||||
"ai_0": [1,8,12,0,1,5,8,"88de4e65",205,"arcaneShip 1/8, indomShip 0/4, kazimierzShip 1/64, kjeragShip 0/5, preciShip 2/70, raidShip 1/12, suntShip 1/0, swiftShip 1/51",13,25,12,100],
|
||||
"ai_1": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/25, kjeragShip 0/7, preciShip 0/2, sargonShip 0/8, siracusaShip 0/12, skillfulShip 0/5, steadShip 0/2, swiftShip 0/19",null,null,null,62],
|
||||
"ai_2": [1,5,12,0,0,5,8,"052cd291",171,"deputShip 0/24, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/16, lateranoShip 0/4, preciShip 0/4, raidShip 0/6, skillfulShip 1/12, soloShip 1/14, steadShip 0/62, suntShip 1/0, swiftShip 1/75, victoriaShip 1/37, yanShip 1/33",4,25,21,100],
|
||||
"ai_2": [1,8,12,0,0,5,8,"81827b1b",175,"deputShip 0/24, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/14, lateranoShip 0/4, preciShip 0/4, raidShip 0/6, skillfulShip 1/16, soloShip 1/12, steadShip 0/59, suntShip 1/0, swiftShip 1/77, victoriaShip 1/35, yanShip 1/35",4,25,21,100],
|
||||
"ai_3": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/18, deputShip 0/6, miraShip 0/4, preciShip 0/4, sargonShip 0/2, siracusaShip 0/31, skillfulShip 0/2, soloShip 0/10",null,null,null,68]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [0,0,13,0,0,6,0,"811c9dc5",0,"arcaneShip 0/11, indomShip 0/4, kazimierzShip 0/84, kjeragShip 0/5, preciShip 0/83, raidShip 0/24, swiftShip 0/56",14,47,33,114],
|
||||
"ai_0": [0,0,13,0,0,6,0,"811c9dc5",0,"arcaneShip 0/8, indomShip 0/4, kazimierzShip 0/80, kjeragShip 0/5, preciShip 0/79, raidShip 0/24, swiftShip 0/56",9,47,38,114],
|
||||
"ai_1": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/2, kazimierzShip 0/25, kjeragShip 0/7, preciShip 0/2, sargonShip 0/8, siracusaShip 0/12, skillfulShip 0/5, steadShip 0/2, swiftShip 0/19",null,null,null,62],
|
||||
"ai_2": [0,0,12,0,0,6,0,"811c9dc5",0,"deputShip 0/26, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/18, lateranoShip 0/4, preciShip 0/6, raidShip 0/6, skillfulShip 0/14, soloShip 0/14, steadShip 0/62, swiftShip 0/89, victoriaShip 0/45, yanShip 0/35",10,47,37,113],
|
||||
"ai_2": [0,0,12,0,0,6,0,"811c9dc5",0,"deputShip 0/26, egirShip 0/6, kazimierzShip 0/4, kjeragShip 0/16, lateranoShip 0/4, preciShip 0/6, raidShip 0/6, skillfulShip 0/18, soloShip 0/12, steadShip 0/59, swiftShip 0/91, victoriaShip 0/43, yanShip 0/37",10,47,37,113],
|
||||
"ai_3": [0,0,0,0,0,4,0,"811c9dc5",0,"arcaneShip 0/18, deputShip 0/6, miraShip 0/4, preciShip 0/4, sargonShip 0/2, siracusaShip 0/31, skillfulShip 0/2, soloShip 0/10",null,null,null,68]
|
||||
}
|
||||
],
|
||||
@@ -1130,9 +1130,9 @@
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 2,
|
||||
"reward": 255,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2971324,"gold":114,"itemsEquipped":8,"kills":109,"leaks":100,"lpLost":47,"merges":5,"perfectRounds":5,"refreshes":9},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2923937,"gold":114,"itemsEquipped":8,"kills":107,"leaks":102,"lpLost":47,"merges":5,"perfectRounds":5,"refreshes":9},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/11","indomShip 0/4","kazimierzShip 0/84","kjeragShip 0/5","preciShip 0/83","raidShip 0/24","swiftShip 0/56"]
|
||||
"bonds": ["arcaneShip 0/8","indomShip 0/4","kazimierzShip 0/80","kjeragShip 0/5","preciShip 0/79","raidShip 0/24","swiftShip 0/56"]
|
||||
},
|
||||
"ai_1": {
|
||||
"alive": false,
|
||||
@@ -1144,7 +1144,7 @@
|
||||
"title": null,
|
||||
"trophies": 1,
|
||||
"reward": 149,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":650327,"gold":62,"itemsEquipped":3,"kills":57,"leaks":41,"lpLost":29,"merges":1,"perfectRounds":3,"refreshes":5},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":649468,"gold":62,"itemsEquipped":3,"kills":55,"leaks":43,"lpLost":29,"merges":1,"perfectRounds":3,"refreshes":5},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/2","kazimierzShip 0/25","kjeragShip 0/7","preciShip 0/2","sargonShip 0/8","siracusaShip 0/12","skillfulShip 0/5","steadShip 0/2","swiftShip 0/19"]
|
||||
},
|
||||
@@ -1158,9 +1158,9 @@
|
||||
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
|
||||
"trophies": 2,
|
||||
"reward": 255,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":4175013,"gold":113,"itemsEquipped":11,"kills":170,"leaks":75,"lpLost":33,"merges":3,"perfectRounds":5,"refreshes":9},
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":4317948,"gold":113,"itemsEquipped":11,"kills":172,"leaks":72,"lpLost":30,"merges":3,"perfectRounds":6,"refreshes":9},
|
||||
"lineup": [],
|
||||
"bonds": ["deputShip 0/26","egirShip 0/6","kazimierzShip 0/4","kjeragShip 0/18","lateranoShip 0/4","preciShip 0/6","raidShip 0/6","skillfulShip 0/14","soloShip 0/14","steadShip 0/62","swiftShip 0/89","victoriaShip 0/45","yanShip 0/35"]
|
||||
"bonds": ["deputShip 0/26","egirShip 0/6","kazimierzShip 0/4","kjeragShip 0/16","lateranoShip 0/4","preciShip 0/6","raidShip 0/6","skillfulShip 0/18","soloShip 0/12","steadShip 0/59","swiftShip 0/91","victoriaShip 0/43","yanShip 0/37"]
|
||||
},
|
||||
"ai_3": {
|
||||
"alive": false,
|
||||
@@ -1188,8 +1188,8 @@
|
||||
"combat": "server",
|
||||
"boost": null,
|
||||
"setup": {"stageId":"act1autochess_m01","bossId":"boss_1","hiddenBossId":"boss_9","factions":["FLY","DOT","REFLECTION"]},
|
||||
"end": {"victory":true,"roundsPassed":14,"hiddenReached":false,"hiddenCleared":false,"reason":"victory","teamLp":6,"bossPoolLeft":0,"virtualMs":121400},
|
||||
"rng": {"setup":25,"shop":448,"waves":0,"draft":34,"bots":18063,"meta":84},
|
||||
"end": {"victory":false,"roundsPassed":12,"hiddenReached":false,"hiddenCleared":false,"reason":"eliminated","teamLp":null,"bossPoolLeft":null,"virtualMs":115150},
|
||||
"rng": {"setup":25,"shop":411,"waves":0,"draft":34,"bots":17567,"meta":104},
|
||||
"errors": {"engine":0,"logged":0,"sim":0,"dispatcher":0},
|
||||
"rounds": [
|
||||
{
|
||||
@@ -1224,68 +1224,68 @@
|
||||
},
|
||||
{
|
||||
"round": 7,
|
||||
"ai_0": [1,19,13,0,0,4,8,"bfa893e9",43,"arcaneShip 0/2, kjeragShip 0/2, preciShip 1/2, siracusaShip 1/24, soloShip 1/11, steadShip 0/2, swiftShip 1/6",13,27,14,52],
|
||||
"ai_0": [1,19,13,0,0,4,8,"28ba7985",39,"arcaneShip 0/2, kjeragShip 0/2, preciShip 1/2, siracusaShip 1/20, soloShip 1/11, steadShip 0/2, swiftShip 1/6",11,27,16,52],
|
||||
"ai_1": [1,18,11,0,1,4,8,"eac0b2d5",6,"arcaneShip 0/2, kjeragShip 0/4, preciShip 1/2, siracusaShip 1/0, soloShip 1/0, steadShip 2/4",16,27,11,51]
|
||||
},
|
||||
{
|
||||
"round": 8,
|
||||
"ai_0": [1,19,11,0,0,4,8,"7c223b06",66,"arcaneShip 1/6, emptyShip 1/0, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/36, soloShip 1/11, steadShip 0/2, swiftShip 1/6",23,23,0,64],
|
||||
"ai_0": [1,19,11,0,0,4,8,"7c223b06",60,"arcaneShip 1/6, emptyShip 1/0, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/30, soloShip 1/11, steadShip 0/2, swiftShip 1/6",23,23,0,64],
|
||||
"ai_1": [1,17,12,0,0,4,8,"2243ec88",26,"arcaneShip 1/8, indomShip 1/1, kjeragShip 0/4, preciShip 0/2, siracusaShip 1/10, soloShip 1/0, steadShip 2/7",18,23,5,61]
|
||||
},
|
||||
{
|
||||
"round": 9,
|
||||
"ai_0": [1,19,12,0,1,4,8,"6dfc43a6",78,"arcaneShip 2/12, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/42, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",16,16,0,77],
|
||||
"ai_1": [1,17,12,0,0,4,8,"bbe510e7",82,"arcaneShip 1/16, indomShip 1/10, kjeragShip 0/8, preciShip 1/22, siracusaShip 1/20, soloShip 1/0, steadShip 1/14, victoriaShip 0/8, visiShip 0/8",15,15,0,74]
|
||||
"ai_0": [1,19,12,0,1,4,8,"588666d3",72,"arcaneShip 1/12, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 2/7, siracusaShip 1/36, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",16,16,0,78],
|
||||
"ai_1": [1,17,12,0,0,4,8,"0f3cf873",67,"arcaneShip 1/14, indomShip 1/10, kjeragShip 0/4, preciShip 0/2, siracusaShip 1/32, soloShip 1/0, steadShip 1/11, victoriaShip 0/8, visiShip 0/8",14,15,1,73]
|
||||
},
|
||||
{
|
||||
"round": 10,
|
||||
"ai_0": [1,18,13,0,0,5,8,"e24edc84",82,"arcaneShip 2/14, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/44, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",23,24,1,89],
|
||||
"ai_1": [1,17,12,0,0,5,8,"f2b57087",100,"arcaneShip 1/16, indomShip 1/12, kjeragShip 0/8, miraShip 0/3, preciShip 1/35, siracusaShip 1/20, soloShip 1/0, steadShip 1/17, suntShip 1/0, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",23,23,0,86]
|
||||
"ai_0": [1,17,13,0,0,5,8,"bb29d023",80,"arcaneShip 1/16, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 2/7, siracusaShip 1/40, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",22,24,2,91],
|
||||
"ai_1": [1,16,12,0,0,5,8,"34e3de0f",83,"arcaneShip 1/14, indomShip 1/20, kjeragShip 0/8, preciShip 0/2, siracusaShip 1/32, soloShip 1/0, steadShip 1/17, suntShip 1/0, victoriaShip 0/8, visiShip 0/8",22,23,1,85]
|
||||
},
|
||||
{
|
||||
"round": 11,
|
||||
"ai_0": [1,17,12,0,0,5,8,"65c25a4f",94,"arcaneShip 2/20, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/7, siracusaShip 1/50, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",22,23,1,101],
|
||||
"ai_1": [1,13,12,0,0,5,8,"b5188f04",124,"arcaneShip 2/26, indomShip 1/14, kazimierzShip 0/8, kjeragShip 0/16, miraShip 0/3, preciShip 1/54, siracusaShip 1/30, soloShip 1/0, steadShip 0/17, suntShip 1/0, swiftShip 0/8, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",19,23,4,99]
|
||||
"ai_0": [1,17,12,0,0,5,8,"f0ff6294",86,"arcaneShip 1/22, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/7, siracusaShip 2/46, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 0/6, victoriaShip 0/8, visiShip 0/8",23,23,0,104],
|
||||
"ai_1": [1,16,12,0,0,5,8,"f020d91c",137,"arcaneShip 1/20, indomShip 1/40, kjeragShip 0/8, preciShip 0/2, siracusaShip 1/58, soloShip 1/0, steadShip 1/19, suntShip 1/0, victoriaShip 0/8, visiShip 0/8",17,23,6,97]
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,7,12,0,0,5,8,"b6fcbbbb",106,"arcaneShip 2/26, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/9, siracusaShip 1/54, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",23,46,23,114],
|
||||
"ai_1": [1,3,12,0,0,6,8,"f5a033f5",153,"arcaneShip 2/26, indomShip 0/14, kazimierzShip 0/8, kjeragShip 0/16, miraShip 0/3, preciShip 1/78, siracusaShip 1/30, soloShip 1/0, steadShip 1/19, suntShip 1/0, swiftShip 0/8, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",27,46,19,111]
|
||||
"ai_0": [1,7,12,0,0,6,8,"09ffe6d0",86,"arcaneShip 1/22, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 2/7, siracusaShip 1/46, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 0/6, victoriaShip 0/8, visiShip 0/8",35,47,12,116],
|
||||
"ai_1": [1,6,12,0,0,6,8,"d9bd3d27",160,"arcaneShip 1/20, indomShip 1/60, kjeragShip 0/8, preciShip 0/2, siracusaShip 1/58, soloShip 1/0, steadShip 1/22, suntShip 1/0, victoriaShip 0/8, visiShip 0/8",17,46,29,109]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
"ai_0": [1,7,12,0,0,6,8,"3d99f43b",110,"arcaneShip 2/28, emptyShip 1/0, indomShip 0/8, kjeragShip 0/7, preciShip 1/11, siracusaShip 1/54, soloShip 1/11, steadShip 0/2, suntShip 1/0, swiftShip 1/6, victoriaShip 0/8, visiShip 0/8",14,39,25,124],
|
||||
"ai_1": [1,3,12,0,0,6,8,"e9f74be3",189,"arcaneShip 2/34, indomShip 0/14, kazimierzShip 0/8, kjeragShip 0/16, miraShip 0/3, preciShip 1/92, siracusaShip 1/44, soloShip 1/0, steadShip 1/19, suntShip 1/0, swiftShip 0/8, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",39,39,0,124]
|
||||
"ai_0": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/36, indomShip 0/8, kjeragShip 0/7, miraShip 0/3, preciShip 0/9, siracusaShip 0/58, soloShip 0/11, steadShip 0/2, swiftShip 0/6, victoriaShip 0/8, visiShip 0/8, yanShip 0/6",21,39,18,127],
|
||||
"ai_1": [0,0,12,0,0,6,0,"811c9dc5",0,"arcaneShip 0/26, indomShip 0/60, kjeragShip 0/8, miraShip 0/4, preciShip 0/2, siracusaShip 0/84, steadShip 0/23, victoriaShip 0/8, visiShip 0/8",19,39,20,120]
|
||||
}
|
||||
],
|
||||
"players": {
|
||||
"ai_0": {
|
||||
"alive": true,
|
||||
"victory": true,
|
||||
"roundsPassed": 14,
|
||||
"eliminatedRound": null,
|
||||
"lp": 4,
|
||||
"alive": false,
|
||||
"victory": false,
|
||||
"roundsPassed": 12,
|
||||
"eliminatedRound": 13,
|
||||
"lp": 0,
|
||||
"bandId": "band_doberm",
|
||||
"title": {"id":"comment_3","name":"坚若磐石","picId":"comment_icon_3","text":"目标生命值损失最少"},
|
||||
"trophies": 4,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":122,"bossDamage":108916,"dmgDealt":2898036,"gold":136,"itemsEquipped":15,"kills":232,"leaks":65,"lpLost":23,"merges":4,"perfectRounds":7,"refreshes":18},
|
||||
"lineup": ["5_10_a@11,3[5_02_e_a+1_02_e_b]","3_10_b@11,6","6_12_a@11,7[3_06_e_a+1_05_e_b]","1_17_a@10,3","4_10_a@10,7[1_02_e_b+1_05_e_b]","1_08_b@10,8[3_11_e_a+4_04_e_b]","4_02_a@9,8","5_14_a@9,9[4_10_e_a+4_05_e_a]"],
|
||||
"bonds": ["arcaneShip 2/34","emptyShip 1/0","indomShip 0/8","kjeragShip 0/7","miraShip 1/0","preciShip 1/11","siracusaShip 1/60","soloShip 1/11","steadShip 0/2","suntShip 1/0","swiftShip 1/6","victoriaShip 0/8","visiShip 0/8"]
|
||||
"title": {"id":"comment_4","name":"精英云集","picId":"comment_icon_4","text":"晋升精锐次数最多"},
|
||||
"trophies": 3,
|
||||
"reward": 280,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":3037907,"gold":127,"itemsEquipped":14,"kills":238,"leaks":49,"lpLost":33,"merges":3,"perfectRounds":8,"refreshes":17},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/36","indomShip 0/8","kjeragShip 0/7","miraShip 0/3","preciShip 0/9","siracusaShip 0/58","soloShip 0/11","steadShip 0/2","swiftShip 0/6","victoriaShip 0/8","visiShip 0/8","yanShip 0/6"]
|
||||
},
|
||||
"ai_1": {
|
||||
"alive": true,
|
||||
"victory": true,
|
||||
"roundsPassed": 14,
|
||||
"eliminatedRound": null,
|
||||
"lp": 2,
|
||||
"alive": false,
|
||||
"victory": false,
|
||||
"roundsPassed": 12,
|
||||
"eliminatedRound": 13,
|
||||
"lp": 0,
|
||||
"bandId": "band_malkie",
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 4,
|
||||
"reward": 400,
|
||||
"stats": {"activatedLayers":200,"bossDamage":566084,"dmgDealt":4442196,"gold":137,"itemsEquipped":22,"kills":254,"leaks":39,"lpLost":25,"merges":4,"perfectRounds":9,"refreshes":19},
|
||||
"lineup": ["5_23_a@11,3","1_17_a@11,6[5_07_e_a+1_02_e_b]","5_12_a@11,7[3_01_e_a+5_09_e_a]","5_02_a@10,3[3_06_e_a+4_08_e_b]","4_10_a@10,7[1_01_e_a+1_05_e_b]","2_16_b@10,8[3_11_e_a+3_08_e_b]","6_03_a@9,8[5_03_e_b]","1_08_b@9,9"],
|
||||
"bonds": ["arcaneShip 2/42","indomShip 0/14","kazimierzShip 0/8","kjeragShip 0/16","miraShip 0/3","preciShip 1/92","siracusaShip 1/54","soloShip 1/0","steadShip 0/19","suntShip 1/0","swiftShip 0/8","victoriaShip 0/8","visiShip 0/8","yanShip 1/12"]
|
||||
"title": {"id":"comment_5","name":"万事俱备","picId":"comment_icon_5","text":"装备配发数量最多"},
|
||||
"trophies": 3,
|
||||
"reward": 280,
|
||||
"stats": {"activatedLayers":0,"bossDamage":0,"dmgDealt":2410241,"gold":120,"itemsEquipped":16,"kills":196,"leaks":73,"lpLost":32,"merges":2,"perfectRounds":6,"refreshes":18},
|
||||
"lineup": [],
|
||||
"bonds": ["arcaneShip 0/26","indomShip 0/60","kjeragShip 0/8","miraShip 0/4","preciShip 0/2","siracusaShip 0/84","steadShip 0/23","victoriaShip 0/8","visiShip 0/8"]
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1349,7 +1349,7 @@
|
||||
},
|
||||
{
|
||||
"round": 12,
|
||||
"ai_0": [1,399,14,0,0,6,8,"108fc4b5",2194,"arcaneShip 1/328, deputShip 0/300, egirShip 0/300, emptyShip 0/300, indomShip 1/308, investShip 0/300, kazimierzShip 0/308, kjeragShip 0/300, lateranoShip 0/300, maniShip 0/300, miraShip 0/300, preciShip 0/302, raidShip 0/300, sargonShip 0/300, siracusaShip 1/326, skillfulShip 1/309, soloShip 1/307, steadShip 0/300, suntShip 1/300, swiftShip 1/316, victoriaShip 0/300, visiShip 0/300, yanShip 0/300",114,114,0,111]
|
||||
"ai_0": [1,399,14,0,0,6,8,"63f60b1e",2194,"arcaneShip 1/328, deputShip 0/300, egirShip 0/300, emptyShip 0/300, indomShip 1/308, investShip 0/300, kazimierzShip 0/308, kjeragShip 0/300, lateranoShip 0/300, maniShip 0/300, miraShip 0/300, preciShip 0/302, raidShip 0/300, sargonShip 0/300, siracusaShip 1/326, skillfulShip 1/309, soloShip 1/307, steadShip 0/300, suntShip 1/300, swiftShip 1/316, victoriaShip 0/300, visiShip 0/300, yanShip 0/300",115,115,0,111]
|
||||
},
|
||||
{
|
||||
"round": 13,
|
||||
@@ -1367,7 +1367,7 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 0,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":2269,"bossDamage":1145000,"dmgDealt":3025009,"gold":176,"itemsEquipped":26,"kills":365,"leaks":1,"lpLost":1,"merges":5,"perfectRounds":12,"refreshes":34},
|
||||
"stats": {"activatedLayers":2269,"bossDamage":1145000,"dmgDealt":3047851,"gold":176,"itemsEquipped":26,"kills":366,"leaks":1,"lpLost":1,"merges":5,"perfectRounds":12,"refreshes":34},
|
||||
"lineup": ["4_02_b@12,7[3_08_e_a+6_03_e_a]","6_01_a@12,8[3_03_e_a+3_02_e_a]","6_16_a@11,5[1_05_e_b+1_02_e_b]","3_18_a@11,8[4_11_e_a+4_05_e_b]","4_10_a@10,4[4_07_e_a+3_03_e_b]","6_05_a@10,5[1_02_e_a]","4_01_b@10,6[4_06_e_a+4_05_e_a]","1_08_b@9,9[4_10_e_a]"],
|
||||
"bonds": ["arcaneShip 2/389","deputShip 0/300","egirShip 0/300","emptyShip 0/300","indomShip 0/308","investShip 0/300","kazimierzShip 0/308","kjeragShip 0/300","lateranoShip 1/310","maniShip 0/300","miraShip 0/300","preciShip 1/302","raidShip 0/300","sargonShip 0/300","siracusaShip 1/345","skillfulShip 0/335","soloShip 1/307","steadShip 0/300","suntShip 1/300","swiftShip 1/316","victoriaShip 0/300","visiShip 0/300","yanShip 0/300"]
|
||||
}
|
||||
@@ -1464,7 +1464,7 @@
|
||||
"title": {"id":"comment_2","name":"不朽盟约","picId":"comment_icon_2","text":"激活的盟约层数总和最高"},
|
||||
"trophies": 8,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":3054,"bossDamage":2348544,"dmgDealt":11081151,"gold":156,"itemsEquipped":15,"kills":288,"leaks":8,"lpLost":0,"merges":6,"perfectRounds":12,"refreshes":28},
|
||||
"stats": {"activatedLayers":3054,"bossDamage":2388329,"dmgDealt":11201551,"gold":156,"itemsEquipped":15,"kills":287,"leaks":8,"lpLost":0,"merges":6,"perfectRounds":12,"refreshes":28},
|
||||
"lineup": ["4_09_b@11,5","4_14_a@11,8","5_07_a@10,4[1_01_e_a]","2_18_a@10,5","1_19_b@10,8[4_04_e_b+1_02_e_b]","3_09_a@9,7[2_01_e_a+3_08_e_a]","4_20_a@9,8","3_05_a@9,9[4_07_e_a+5_02_e_a]"],
|
||||
"bonds": ["arcaneShip 1/333","deputShip 0/304","egirShip 1/369","emptyShip 0/300","indomShip 0/300","investShip 0/300","kazimierzShip 1/333","kjeragShip 0/302","lateranoShip 0/300","maniShip 0/300","miraShip 0/300","preciShip 1/364","raidShip 1/376","sargonShip 0/300","siracusaShip 0/300","skillfulShip 0/300","soloShip 1/304","steadShip 1/340","suntShip 1/300","swiftShip 1/335","victoriaShip 0/300","visiShip 0/300","yanShip 0/300"]
|
||||
},
|
||||
@@ -1478,7 +1478,7 @@
|
||||
"title": {"id":"comment_1","name":"卫戍之星","picId":"comment_icon_1","text":"对敌方领袖造成伤害最高(仅胜利时)"},
|
||||
"trophies": 8,
|
||||
"reward": 425,
|
||||
"stats": {"activatedLayers":2623,"bossDamage":4589976,"dmgDealt":19161995,"gold":197,"itemsEquipped":35,"kills":283,"leaks":1,"lpLost":0,"merges":6,"perfectRounds":12,"refreshes":35},
|
||||
"stats": {"activatedLayers":2623,"bossDamage":4551311,"dmgDealt":18984249,"gold":197,"itemsEquipped":35,"kills":283,"leaks":1,"lpLost":0,"merges":6,"perfectRounds":12,"refreshes":35},
|
||||
"lineup": ["1_13_b@11,5[4_06_e_b+4_09_e_a]","6_11_a@11,8[3_08_e_a+5_01_e_a]","6_08_a@10,3[1_05_e_b+2_01_e_b]","3_16_b@10,4[3_10_e_b+2_03_e_b]","4_01_a@10,7[3_01_e_a+6_09_e_a]","4_07_b@10,8[3_10_e_a+5_09_e_a]","6_01_a@9,8[3_05_e_b+3_02_e_b]","1_06_b@9,9[3_11_e_a+2_03_e_b]"],
|
||||
"bonds": ["arcaneShip 0/302","deputShip 1/328","egirShip 0/300","emptyShip 0/300","indomShip 1/322","investShip 0/300","kazimierzShip 0/300","kjeragShip 0/300","lateranoShip 1/304","maniShip 1/304","miraShip 0/300","preciShip 1/323","raidShip 0/300","sargonShip 0/300","siracusaShip 0/300","skillfulShip 0/304","soloShip 0/322","steadShip 1/390","suntShip 1/312","swiftShip 0/300","victoriaShip 1/340","visiShip 0/306","yanShip 0/310"]
|
||||
}
|
||||
|
||||
+811
-761
File diff suppressed because it is too large.
Load diff
@@ -91,7 +91,7 @@ describe('#8 深池逐火: a knock-out is a walking 隐匿 ember that a blocker
|
||||
round: 3, wave, units: [
|
||||
chess(1, 'chess_char_4_23_b', 9, 8), // 百炼嘉维尔 blocks the lower lane
|
||||
chess(2, 'chess_char_4_20_b', 10, 4), // 远牙
|
||||
chess(3, 'chess_char_4_02_b', 11, 4), // 莫斯提马
|
||||
chess(3, 'chess_char_4_02_b', 11, 3), // 莫斯提马 (since 0.2.0 her S3 casts on its 3-15: at (11,4) it was spent early)
|
||||
chess(4, 'chess_char_4_17_b', 12, 6), // 星熊 blocks the upper lane's way down
|
||||
],
|
||||
});
|
||||
@@ -286,7 +286,7 @@ describe('#5 转译基底·α: damage is cancelled until its form change; only t
|
||||
round: 4, wave, spawns, units: [
|
||||
chess(1, 'chess_char_4_23_b', 9, 3), // 百炼嘉维尔 near the goal
|
||||
chess(2, 'chess_char_6_01_b', 10, 4), // 蕾缪安 (physical)
|
||||
chess(3, 'chess_char_4_02_b', 11, 4), // 莫斯提马 (arts)
|
||||
chess(3, 'chess_char_4_02_b', 10, 3), // 莫斯提马 (arts; her S3 casts on its 3-15 since 0.2.0: at (11,4) her arts landed 4 hits first)
|
||||
],
|
||||
});
|
||||
let tr = null, phaseAt = null, kind = null, diedAt = null, formAt = null, maxBefore = null, firstFormLoss = null, earlyAttack = false;
|
||||
|
||||
@@ -10,7 +10,9 @@
|
||||
// 缩短) uses the official grid (skill rangeId, or the base grid grown by ability_range_forward_extend) while it runs —
|
||||
// with every module of the loadout: a module's 攻击距离 widens it too, except where the skill's range ignores 攻击距离
|
||||
// (信仰搅拌机 S3 with SPT-Y, PRTS 备注 "此技能的攻击范围不受'攻击距离'属性影响") — and the DEFAULT trigger still reads the
|
||||
// initial range (PRTS 卫戍协议/帮助 "技能就绪,且即将进行普通攻击"). A skill grid that only selects targets (荒芜拉普兰德
|
||||
// initial range (PRTS 卫戍协议/帮助 "技能就绪,且即将进行普通攻击"), except where the owner's rule of 2026-10-05 makes it
|
||||
// ACTIVE_RANGE (a running range that strictly contains the own one; not 烛煌's 4-11 vs 3-1 —
|
||||
// test/sim/feedback5-active-range.test.js). A skill grid that only selects targets (荒芜拉普兰德
|
||||
// S1: no rangeId, no 攻击范围 text) leaves the card on the unit's own range.
|
||||
|
||||
import { test } from 'node:test';
|
||||
@@ -48,7 +50,7 @@ test('data: 烛煌 S3 众恶的焚场 is the default skill (index 2), skill rang
|
||||
assert.equal(c.skill.index, 2);
|
||||
assert.equal(c.rangeId, '3-1');
|
||||
assert.equal(c.skill.rangeId, '4-11');
|
||||
assert.equal(c.skill.trigger.rule, 'DEFAULT', 'an attack-range change keeps the basic strategy (§20.2)');
|
||||
assert.equal(c.skill.trigger.rule, 'DEFAULT', 'an attack-range change keeps the basic strategy (§20.2); 4-11 does not contain 3-1, so no ACTIVE_RANGE');
|
||||
}
|
||||
assert.equal(C[BLAZE].skill.bb['attack@trigger_time'], 18);
|
||||
assert.equal(C.chess_char_5_03_b.skill.bb['attack@trigger_time'], 21);
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
// test/sim/feedback5-active-range.test.js — the owner's rule of 2026-10-05 (a deliberate deviation, like DESIGN §21.29):
|
||||
// a MANUAL skill on the basic strategy whose attack range while it runs strictly contains the operator's own range casts
|
||||
// as soon as an enemy (a heal skill: an injured ally) is inside that larger range — trigger ACTIVE_RANGE, resolved by
|
||||
// tools/build-data.mjs resolveTrigger (customRangeGrid = the running range) and checked every tick by server/sim/skills.js.
|
||||
// Community report: 「有的干员开技能后的攻击范围比平时攻击范围大,但是怪走到平时的攻击范围内才会开技能」.
|
||||
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { makeBattle, chessRec, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
import { getDefaultSource } from '../../server/sim/simdata.js';
|
||||
import { absoluteRangeKeys } from '../../server/sim/targeting.js';
|
||||
import { COLS } from '../../server/sim/constants.js';
|
||||
|
||||
const ds = getDefaultSource();
|
||||
const BASE = [[0, 0], [0, 1]]; // 1-1
|
||||
const WIDE = [[0, 0], [0, 1], [0, 2], [0, 3], [1, 1], [-1, 1]]; // strictly contains 1-1
|
||||
const op = (o = {}) => chessRec({
|
||||
id: 't_op', rangeGrid: BASE, ...o,
|
||||
skill: { spCost: 1, initSp: 1, duration: 5, trigger: { rule: 'ACTIVE_RANGE', rawRule: 'DEFAULT', customRangeGrid: WIDE }, ...(o.skill || {}) },
|
||||
});
|
||||
const dummy = (key, o = {}) => enemyRec({ key, hp: 1e7, speed: 0, ...o });
|
||||
const arena = (o = {}) => makeBattle({
|
||||
defs: { chess: { t_op: op(o.chess), t_ally: chessRec({ id: 't_ally', skill: null, stats: { maxHp: 1e4 } }) }, enemies: { e: dummy('e'), f: dummy('f', { motion: 'FLY' }) } },
|
||||
units: [{ chessId: 't_op', row: 10, col: 4, dir: 'RIGHT' }, ...(o.units || [])], enemies: o.enemies || [],
|
||||
hooks: ['skillStart', 'attack'], captureNoisy: true, autoFinish: false, timeLimit: 30, seed: 3, content: 'generic',
|
||||
});
|
||||
const casts = (h, u) => h.hooksOf('skillStart').filter((c) => c.unit === u);
|
||||
const done = (h) => { assert.deepEqual(h.b.errors.map((e) => `${e.label} ${e.message}`), []); checkInvariants(h.b); };
|
||||
|
||||
test('ACTIVE_RANGE: an enemy inside the running range only casts the skill at once (no attack); nobody, or an enemy outside it, does not', () => {
|
||||
// (10,7) = [0,3]: the running range only — out of reach of the 1-1 attack
|
||||
const h = arena({ enemies: [{ key: 'e', pos: [10, 7] }] });
|
||||
const u = h.unit('t_op');
|
||||
assert.equal(u.skill.rule, 'ACTIVE_RANGE');
|
||||
assert.ok(h.runUntil(() => casts(h, u).length > 0, 2), 'cast');
|
||||
assert.equal(casts(h, u)[0].reason, 'ACTIVE_RANGE');
|
||||
assert.equal(h.hooksOf('attack').filter((c) => c.attacker === u).length, 0, 'before any attack (DEFAULT would wait for one)');
|
||||
done(h);
|
||||
const none = arena();
|
||||
none.run(5);
|
||||
assert.equal(casts(none, none.unit('t_op')).length, 0, 'no enemy: no cast');
|
||||
done(none);
|
||||
const far = arena({ enemies: [{ key: 'e', pos: [10, 8] }] }); // [0,4]: outside the running range too
|
||||
far.run(5);
|
||||
assert.equal(casts(far, far.unit('t_op')).length, 0, 'an enemy outside the running range: no cast');
|
||||
done(far);
|
||||
});
|
||||
|
||||
test('ACTIVE_RANGE: the DEFAULT condition on the larger range — no flyer for a ground-only unit; the permanent 攻击距离 grows it', () => {
|
||||
const fly = arena({ enemies: [{ key: 'f', pos: [10, 7], route: 2 }] });
|
||||
fly.run(5);
|
||||
assert.equal(casts(fly, fly.unit('t_op')).length, 0, 'a melee unit cannot target the flyer: no cast');
|
||||
done(fly);
|
||||
// [0,4] is in the running range grown by a permanent rangeExtend +1 (modules / talents "攻击距离+1": baseRangeExtend)
|
||||
const ext = arena({ enemies: [{ key: 'e', pos: [10, 8] }] });
|
||||
const u = ext.unit('t_op');
|
||||
ext.step();
|
||||
ext.b.addBuff(u, { key: 'test:range', mods: { rangeExtend: 1 }, persist: true });
|
||||
assert.ok(ext.runUntil(() => casts(ext, u).length > 0, 2), 'cast on the grown range');
|
||||
done(ext);
|
||||
});
|
||||
|
||||
test('ACTIVE_RANGE heal skill: an injured ally inside the running range only casts it; a healthy one does not', () => {
|
||||
const medic = { profession: 'MEDIC', subProfessionId: 'physician', rangeGrid: BASE, skill: { trigger: { rule: 'ACTIVE_RANGE', rawRule: 'DEFAULT', customRangeGrid: WIDE } } };
|
||||
const h = arena({ chess: medic, units: [{ chessId: 't_ally', row: 10, col: 7 }] });
|
||||
const u = h.unit('t_op'), a = h.unit('t_ally');
|
||||
h.run(3);
|
||||
assert.equal(casts(h, u).length, 0, 'nobody to heal: no cast');
|
||||
a.hp = a.s.maxHp / 2;
|
||||
assert.ok(h.runUntil(() => casts(h, u).length > 0, 2), 'an injured ally at [0,3]: cast');
|
||||
done(h);
|
||||
});
|
||||
|
||||
test('real data: 莫斯提马 S3 序时之匙 (3-15 over her 3-6) casts on its running range; 白面鸮 S2 脑啡肽 (y-7 over y-2, a heal) resolves to it too', () => {
|
||||
const MOST = 'chess_char_4_02_a', PLOSIS = 'chess_char_4_21_a';
|
||||
const d = ds.getChess(MOST);
|
||||
assert.equal(d.skill.trigger.rule, 'ACTIVE_RANGE');
|
||||
assert.equal(ds.getChess(PLOSIS).skill.trigger.rule, 'ACTIVE_RANGE');
|
||||
// an enemy on a field tile of 3-15 that 3-6 lacks (she stands at (10,3) facing right)
|
||||
const base = new Set(absoluteRangeKeys(d.rangeGrid, 10, 3, 'RIGHT', 0));
|
||||
const k = absoluteRangeKeys(d.skill.trigger.grid, 10, 3, 'RIGHT', 0).find((x) => !base.has(x) && ((x / COLS) | 0) >= 9 && ((x / COLS) | 0) <= 12);
|
||||
assert.ok(k != null);
|
||||
const h = makeBattle({
|
||||
defs: { enemies: { e: dummy('e') } }, units: [{ chessId: MOST, row: 10, col: 3, dir: 'RIGHT' }],
|
||||
enemies: [{ key: 'e', pos: [(k / COLS) | 0, k % COLS] }], hooks: ['skillStart'], autoFinish: false, timeLimit: 30,
|
||||
});
|
||||
const u = h.unit(MOST);
|
||||
h.step();
|
||||
u.skill.gainSp(1000);
|
||||
assert.ok(h.runUntil(() => u.skill.active, 2), '莫斯提马 S3 cast');
|
||||
assert.equal(casts(h, u)[0].reason, 'ACTIVE_RANGE');
|
||||
done(h);
|
||||
});
|
||||
@@ -1,7 +1,8 @@
|
||||
// test/sim/playtest6-skills.test.js — user playtest #6, workstream WE (skill triggers and buffs), with the real data and kits.
|
||||
// #15 "技能范围比攻击范围大的技能在敌人进入技能范围时不触发": PRTS 卫戍协议/帮助 §作战阶段 技能操作 — "携带拥有技能范围的技能
|
||||
// (非攻击距离增加)的干员:不通过普通攻击/治疗触发技能,仅在技能范围内存在敌人(无视其不可选中)时释放技能" (SKILL_RANGE);
|
||||
// an attack-range change keeps the basic strategy; the class rows (重装 "不受技能范围影响,受到伤害时释放技能" …) cover every
|
||||
// an attack-range change keeps the basic strategy (since 0.2.0 ACTIVE_RANGE when the running range strictly contains
|
||||
// the own one — the owner's rule of 2026-10-05); the class rows (重装 "不受技能范围影响,受到伤害时释放技能" …) cover every
|
||||
// MANUAL skill of the class; "自动操作具有3s冷却"; GDGLOW_SKILL_2 "全场存在可选目标时释放技能".
|
||||
// #16 "古米的治疗队友的技能在身边队友受伤时并没触发,古米接敌之后才触发": 备用军粮 is 自动触发 (no 技能策略); PRTS 备注 "此技能
|
||||
// 在存在生命值不满的可治疗角色时可触发;技能触发后古米将切换至治疗模式…直至古米完成一次普通攻击的治疗". Audit: 塞雷娅
|
||||
@@ -87,20 +88,21 @@ test('#15 audit: every MANUAL chess skill with its own 技能范围 casts with a
|
||||
assert.ok(n >= 20, `${n} SKILL_RANGE skills`);
|
||||
});
|
||||
|
||||
test('#15 an attack-range change ("攻击范围扩大") keeps the basic strategy: 银灰 S3 waits for an enemy in his initial range', () => {
|
||||
test('#15 an attack-range change ("攻击范围扩大") is officially the basic strategy; by the owner\'s rule of 2026-10-05 银灰 S3 (3-7 strictly containing his 3-12) casts on an enemy inside the expanded range (ACTIVE_RANGE)', () => {
|
||||
const id = 'chess_char_4_22_a';
|
||||
const h = run({ defs: { enemies: { enemy_d: dummy('enemy_d') }, chess: noGarrison(id) }, units: [{ chessId: id, row: 10, col: 3 }] });
|
||||
const u = h.unit(id);
|
||||
assert.equal(u.skill.id, 'skchr_svrash_3');
|
||||
assert.equal(u.skill.rule, 'DEFAULT');
|
||||
assert.equal(u.skill.rule, 'ACTIVE_RANGE');
|
||||
assert.equal(skillOf(id, 'skchr_svrash_3').trigger.rawRule, 'DEFAULT', 'the official strategy: the basic one (PRTS "非攻击距离增加")');
|
||||
h.step();
|
||||
fill(u);
|
||||
const far = absoluteRangeKeys(u.def.skill.rangeGrid, 10, 3, u.dir, 0).find((k) => !u.rangeKeySet.has(k) && Math.floor(k / COLS) === 10);
|
||||
h.spawn('enemy_d', { pos: [10, far % COLS] });
|
||||
h.run(1);
|
||||
assert.equal(u.skill.activations, 0, 'an enemy only in the expanded range: no cast (PRTS "非攻击距离增加")');
|
||||
h.spawn('enemy_d', { pos: [10, 4] });
|
||||
assert.ok(h.runUntil(() => u.skill.activations === 1, 3), 'an enemy in the initial range: cast before the attack');
|
||||
// a field tile of the expanded range outside his own (his row has none: 3-7 and 3-12 share it)
|
||||
const far = absoluteRangeKeys(u.def.skill.rangeGrid, 10, 3, u.dir, 0).find((k) => !u.rangeKeySet.has(k) && Math.floor(k / COLS) >= 9 && Math.floor(k / COLS) <= 12);
|
||||
assert.ok(far != null);
|
||||
h.spawn('enemy_d', { pos: [Math.floor(far / COLS), far % COLS] });
|
||||
assert.ok(h.runUntil(() => u.skill.activations === 1, 3), 'an enemy only in the expanded range: cast, no attack needed');
|
||||
assert.equal(starts(h, u)[0].reason, 'ACTIVE_RANGE');
|
||||
done(h);
|
||||
});
|
||||
|
||||
|
||||
+50
-8
@@ -38,6 +38,7 @@ import { isDeepStrictEqual } from 'node:util';
|
||||
import { Grid, DEPLOY_REFUSED_TILES } from '../server/sim/grid.js';
|
||||
import { bandBondIds } from '../shared/bandBonds.js';
|
||||
import { statusKey, composeUnitRecord, standInRecord, unitForm } from '../shared/standIn.js';
|
||||
import { extendedGrid } from '../shared/loadoutRecord.js';
|
||||
|
||||
// ===== CLI & IO ==================================================================================
|
||||
|
||||
@@ -473,6 +474,26 @@ const STANDIN_TRIGGER_DEVIATIONS = Object.freeze({
|
||||
char_610_acfend: { skchr_acfend_1: 'DEFAULT', skchr_acfend_2: 'DEFAULT', skchr_acfend_3: 'DEFAULT' }, // Mechanist S1 结构稳定 / S2 不变性原理 / S3 应力倒置
|
||||
});
|
||||
|
||||
/**
|
||||
* The attack range a MANUAL skill gives while it runs, when its text changes the attack range (ATTACK_RANGE_CHANGE): its
|
||||
* own rangeId grid, else the operator's range grown by `ability_range_forward_extend` ("攻击距离+N": 空弦 S3, 史尔特尔
|
||||
* S2 / S3, 异客 S2 — the kits' targeting.rangeExtend, extendedGrid as Battle._refreshRange); null for any other skill and
|
||||
* for "被动效果:攻击范围扩大" (引星棘刺 S3: her own range while she carries it — shared/loadoutRecord.js attackRangeGrid).
|
||||
*/
|
||||
function activeAttackGrid(skill, baseGrid) {
|
||||
const desc = skill.desc || '';
|
||||
if (!ATTACK_RANGE_CHANGE.test(desc) || /被动效果:攻击范围扩大/.test(desc)) return null;
|
||||
if (skill.rangeGrid?.length) return skill.rangeGrid.map((p) => p.slice());
|
||||
const n = Math.round(Number(skill.bb?.ability_range_forward_extend) || 0);
|
||||
return n > 0 && baseGrid?.length ? extendedGrid(baseGrid, n) : null;
|
||||
}
|
||||
|
||||
/** True when grid `a` holds every tile of grid `b` and at least one more (`[dRow, dCol]` pairs, facing RIGHT). */
|
||||
function strictlyContains(a, b) {
|
||||
const sa = new Set(a.map(([r, c]) => `${r},${c}`)), sb = new Set(b.map(([r, c]) => `${r},${c}`));
|
||||
return sa.size > sb.size && [...sb].every((k) => sa.has(k));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the auto-cast rule of a skill record (PRTS 卫戍协议/帮助 §作战阶段 技能操作 — the official skill strategies;
|
||||
* DESIGN §5.6):
|
||||
@@ -488,13 +509,20 @@ const STANDIN_TRIGGER_DEVIATIONS = Object.freeze({
|
||||
* - else DEFAULT (the basic strategy: ready + about to attack / heal);
|
||||
* - last, the deliberate deviations (TRIGGER_DEVIATIONS, per chess and skill; STANDIN_TRIGGER_DEVIATIONS, per stand-in
|
||||
* unit and skill): `rule` from the table, `rawRule` the official row (a SKILL_RANGE deviation takes the skill's own
|
||||
* range as `customRangeGrid`).
|
||||
* @param {object} skill record from buildSkill (skillId, skillType, desc, rangeGrid)
|
||||
* @param {{operator?: boolean, chessId?: string, unitCharId?: string}} opts operator = a chess (the 技能范围 strategy is
|
||||
* written for 干员; summons keep DEFAULT); chessId = the chess's NORMAL id (TRIGGER_DEVIATIONS key); unitCharId = the
|
||||
* character of a backups.json unit form (STANDIN_TRIGGER_DEVIATIONS key)
|
||||
* range as `customRangeGrid`);
|
||||
* - and the owner's rule of 2026-10-05, a deliberate deviation like §21.29 (community report 「有的干员开技能后的攻击范围比
|
||||
* 平时攻击范围大,但是怪走到平时的攻击范围内才会开技能」): an operator's MANUAL skill left on the basic strategy (DEFAULT,
|
||||
* no deviation of the table) whose attack range while it runs (activeAttackGrid) strictly contains the operator's own
|
||||
* range casts as soon as an enemy — a heal skill: an injured ally — is inside that larger range: ACTIVE_RANGE,
|
||||
* `customRangeGrid` = the running range, `rawRule` the official row. Other rows keep their rule (TAKE_DAMAGE waits for a
|
||||
* hit, SEARCH reads the initial range by its official row, CUSTOM_RANGE / SP_FULL / … have their own).
|
||||
* @param {object} skill record from buildSkill (skillId, skillType, desc, rangeGrid, bb)
|
||||
* @param {{operator?: boolean, chessId?: string, unitCharId?: string, baseGrid?: number[][]|null}} opts operator = a
|
||||
* chess (the 技能范围 strategy is written for 干员; summons keep DEFAULT); chessId = the chess's NORMAL id
|
||||
* (TRIGGER_DEVIATIONS key); unitCharId = the character of a backups.json unit form (STANDIN_TRIGGER_DEVIATIONS key);
|
||||
* baseGrid = the operator's own range at that status (ACTIVE_RANGE)
|
||||
*/
|
||||
function resolveTrigger(ctx, char, charId, skillIdx, skill, { operator = false, chessId = null, unitCharId = null } = {}) {
|
||||
function resolveTrigger(ctx, char, charId, skillIdx, skill, { operator = false, chessId = null, unitCharId = null, baseGrid = null } = {}) {
|
||||
const rows = Object.values(ctx.ac.skillTriggerDataList || {});
|
||||
const manual = skill.skillType === 'MANUAL';
|
||||
const pick =
|
||||
@@ -514,6 +542,10 @@ function resolveTrigger(ctx, char, charId, skillIdx, skill, { operator = false,
|
||||
}
|
||||
if (deviation) return { rule: deviation, rawRule, customRangeGrid: null };
|
||||
const rule = TRIGGER_RENAME[rawRule] || rawRule;
|
||||
if (rule === 'DEFAULT' && operator && manual && baseGrid?.length) {
|
||||
const active = activeAttackGrid(skill, baseGrid);
|
||||
if (active && strictlyContains(active, baseGrid)) return { rule: 'ACTIVE_RANGE', rawRule, customRangeGrid: active };
|
||||
}
|
||||
let customRangeGrid = null;
|
||||
if (rawRule === 'CUSTOM_RANGE_SEARCH_ENEMY') {
|
||||
const rid = ctx.ac.skillRangeDict?.[skill.skillId];
|
||||
@@ -886,7 +918,7 @@ function buildChess(ctx) {
|
||||
if (!se?.skillId || (i !== sIdx && !unlocked(se.unlockCond, phase, level))) return;
|
||||
const s = buildSkill(ctx, se.skillId, skillLevel, null, `chess ${chessId}`);
|
||||
if (!s) return;
|
||||
s.trigger = resolveTrigger(ctx, char, shop.charId, i, s, { operator: true, chessId: baseId });
|
||||
s.trigger = resolveTrigger(ctx, char, shop.charId, i, s, { operator: true, chessId: baseId, baseGrid: rec.rangeGrid });
|
||||
s.index = i;
|
||||
s.overrideTokenKey = se.overrideTokenKey || null;
|
||||
skillRecs.push(s);
|
||||
@@ -1080,7 +1112,7 @@ function buildUnitForm(ctx, charId, status, { chessId = null, skillIndex = null
|
||||
if (!se?.skillId || (i !== skillIndex && !unlocked(se.unlockCond, phase, level))) return;
|
||||
const s = buildSkill(ctx, se.skillId, skillLevel, null, label);
|
||||
if (!s) return;
|
||||
s.trigger = resolveTrigger(ctx, char, charId, i, s, { operator: true, chessId, unitCharId: chessId ? null : charId });
|
||||
s.trigger = resolveTrigger(ctx, char, charId, i, s, { operator: true, chessId, unitCharId: chessId ? null : charId, baseGrid: rangeGrid(ctx, rangeId) });
|
||||
s.index = i;
|
||||
s.overrideTokenKey = se.overrideTokenKey || null;
|
||||
skills.push(s);
|
||||
@@ -3406,6 +3438,16 @@ function validateAll(f) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// the owner's ACTIVE_RANGE rule (2026-10-05): a MANUAL skill of the basic strategy whose running range strictly contains
|
||||
// the record's own range, and no other
|
||||
for (const c of Object.values(chess)) {
|
||||
for (const s of c.skills || []) {
|
||||
if (s.trigger?.rule !== 'ACTIVE_RANGE') continue;
|
||||
if (s.skillType !== 'MANUAL' || s.trigger.rawRule !== 'DEFAULT' || !c.rangeGrid?.length || !strictlyContains(s.trigger.customRangeGrid || [], c.rangeGrid)) {
|
||||
err(`chess ${c.chessId} ${s.skillId}: ACTIVE_RANGE needs a MANUAL basic-strategy skill whose customRangeGrid strictly contains the record's range`);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 补位 / 自选 (data/backups.json, DATA.md §18): a PRESET chess is its own backup; every NORMAL chess (both forms)
|
||||
// composes into its stand-in (shared/standIn.js standInRecord) with the chess's skill and module; every DIY slot is a
|
||||
// DIY chess and every prototype pick of its tier has a form for both slot statuses; derived bonds exist
|
||||
|
||||
Reference in new issue
Block a user