0.2.3: add Clementia and Shu/Ulpianus modules (#437)
Regenerate roster-019, roster-038 and diy-059 through diy-140 for added and regrouped loadouts; other golden families unchanged.
This commit is contained in:
1 parent
62eb113419
commit
2e122873f0
21 files changed
+2940
-2312
No files matched your search
+1
-1
@@ -1 +1 @@
|
||||
{"version":1,"hash":"bfdfd5e7efd9","generator":"tools/fetch-assets.mjs","stats":{"files":10643,"bytes":574449900,"chars":209,"charsWithBack":206,"enemies":252,"enemiesWithSpine":251,"tokens":58,"tokensWithSpine":13,"spineModels":671,"bonds":23,"items":59,"bands":40,"skills":522,"modules":131,"ui":602,"sfxUnits":483,"voiceChars":191,"voiceJpChars":191},"chars":{"char_003_kalts":{"avatar":"/assets/char/avatar/char_003_kalts.png","avatarE2":"/assets/char/avatar/char_003_kalts_2.png","portrait":"/assets/char/portrait/char_003_kalts_1.png","portraitE2":"/assets/char/portrait/char_003_kalts_2.png","spine":{"front":{"skel":"/assets/spine/op/char_003_kalts/front/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/front/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/front/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Die":1,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":-227.579,"y":-138.244,"width":532.04,"height":551.479}},"back":{"skel":"/assets/spine/op/char_003_kalts/back/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/back/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/back/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":410.785,"y":-2.26,"width":531.785,"height":416.492}}}},"char_010_chen":{"avatar":"/assets/char/avatar/char_010_chen.png","avatarE2":"/assets/char/avatar/char_010_chen_2.png","portrait":"/assets/char/portrait/char_010_chen_1.png","portraitE2":"/assets/char/portrait/char_010_chen_2.png","spine":{"front":{"skel":"/assets/spine/op/char_010_chen/front/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/front/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/front/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill_2","end":null,"index":1,"idle":null},"2":{"begin":null,"loop":"Skill_3","end":null,"index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Die":1,"Idle":2,"Skill":1,"Skill_2":1.167,"Skill_3":2.933,"Skill_End":0.6,"Skill_End_2":0.6,"Skill_End_3":0.3,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467],"Skill_2":[0.467],"Skill_3":[0.6,0.8,1,1.2,1.4,1.6,1.8,2,2.2,2.833,2.933]},"bounds":{"x":-322.335,"y":-109.274,"width":663.549,"height":524.806}},"back":{"skel":"/assets/spine/op/char_010_chen/back/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/back/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/back/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill","end":"Skill_End","index":1,"idle":null},"2":{"begin":null,"loop":"Skill","end":"Skill_End","index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Idle":2,"Skill":1,"Skill_End":0.6,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467]},"bounds":{"x":-173.082,"y":-13.829,"width":315.887,"height":404.623}}}},"char_017_huang":{"avatar":"/assets/char/avatar/char_017_huang.png","avatarE2":"/assets/char/avatar/char_017_huang_2.png","portrait":"/assets/char/portrait/char_017_huang_1.png","portraitE2":"/assets/char/portrait/char_017_huang_2.png","spine":{"front":{"skel":"/assets/spine/op/char_017_huang/frontLine truncated
|
||||
{"version":1,"hash":"997b60350583","generator":"tools/fetch-assets.mjs","stats":{"files":10688,"bytes":578013623,"chars":210,"charsWithBack":207,"enemies":252,"enemiesWithSpine":251,"tokens":58,"tokensWithSpine":13,"spineModels":673,"bonds":23,"items":59,"bands":40,"skills":525,"modules":131,"ui":602,"sfxUnits":484,"voiceChars":192,"voiceJpChars":192},"chars":{"char_003_kalts":{"avatar":"/assets/char/avatar/char_003_kalts.png","avatarE2":"/assets/char/avatar/char_003_kalts_2.png","portrait":"/assets/char/portrait/char_003_kalts_1.png","portraitE2":"/assets/char/portrait/char_003_kalts_2.png","spine":{"front":{"skel":"/assets/spine/op/char_003_kalts/front/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/front/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/front/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Die":1,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":-227.579,"y":-138.244,"width":532.04,"height":551.479}},"back":{"skel":"/assets/spine/op/char_003_kalts/back/char_003_kalts.skel","atlas":"/assets/spine/op/char_003_kalts/back/char_003_kalts.atlas","textures":["/assets/spine/op/char_003_kalts/back/char_003_kalts.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":0,"idle":null},"1":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":1,"idle":null},"2":{"begin":null,"loop":"Attack","end":null,"via":"attack","index":2,"idle":null}}},"animations":{"Attack":1,"Default":0,"Idle":9,"Start":1},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433]},"bounds":{"x":410.785,"y":-2.26,"width":531.785,"height":416.492}}}},"char_010_chen":{"avatar":"/assets/char/avatar/char_010_chen.png","avatarE2":"/assets/char/avatar/char_010_chen_2.png","portrait":"/assets/char/portrait/char_010_chen_1.png","portraitE2":"/assets/char/portrait/char_010_chen_2.png","spine":{"front":{"skel":"/assets/spine/op/char_010_chen/front/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/front/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/front/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":"Die","move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill_2","end":null,"index":1,"idle":null},"2":{"begin":null,"loop":"Skill_3","end":null,"index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Die":1,"Idle":2,"Skill":1,"Skill_2":1.167,"Skill_3":2.933,"Skill_End":0.6,"Skill_End_2":0.6,"Skill_End_3":0.3,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467],"Skill_2":[0.467],"Skill_3":[0.6,0.8,1,1.2,1.4,1.6,1.8,2,2.2,2.833,2.933]},"bounds":{"x":-322.335,"y":-109.274,"width":663.549,"height":524.806}},"back":{"skel":"/assets/spine/op/char_010_chen/back/char_010_chen.skel","atlas":"/assets/spine/op/char_010_chen/back/char_010_chen.atlas","textures":["/assets/spine/op/char_010_chen/back/char_010_chen.png"],"pma":false,"anims":{"idle":"Idle","deploy":"Start","attack":{"begin":null,"loop":"Attack","end":null},"attackDown":null,"skill":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"die":null,"move":null,"stun":null,"skills":{"0":{"begin":null,"loop":"Skill","end":"Skill_End","index":0,"idle":null},"1":{"begin":null,"loop":"Skill","end":"Skill_End","index":1,"idle":null},"2":{"begin":null,"loop":"Skill","end":"Skill_End","index":2,"idle":null}}},"animations":{"Attack":1.5,"Attack_End":0.6,"Attack_Pre":0.6,"Default":0,"Idle":2,"Skill":1,"Skill_End":0.6,"Start":0.833},"events":["OnAttack","OnStart"],"hits":{"Attack":[0.433,1],"Skill":[0.467]},"bounds":{"x":-173.082,"y":-13.829,"width":315.887,"height":404.623}}}},"char_017_huang":{"avatar":"/assets/char/avatar/char_017_huang.png","avatarE2":"/assets/char/avatar/char_017_huang_2.png","portrait":"/assets/char/portrait/char_017_huang_1.png","portraitE2":"/assets/char/portrait/char_017_huang_2.png","spine":{"front":{"skel":"/assets/spine/op/char_017_huang/frontLine truncated
|
||||
+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":422,"def":140,"res":0,"cost":12,"blockCnt":1,"bat":1,"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":"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}],"potDown":{"0":{"stats.cost":15},"1":{"stats.respawnTime":80},"2":{"stats.cost":14},"3":{"stats.atk":399},"4":{"stats.cost":13}}},"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"Line 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":422,"def":140,"res":0,"cost":12,"blockCnt":1,"bat":1,"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":"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}],"potDown":{"0":{"stats.cost":15},"1":{"stats.respawnTime":80},"2":{"stats.cost":14},"3":{"stats.atk":399},"4":{"stats.cost":13}}},"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"Line truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":1,"lang":"en","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (en)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"tools/i18n/fallback-remake.json (the remake), tools/i18n/fallback-pr70.json (PR #70 by @YuriRestia), public/i18n/en.json","coverage":{"bands":{"texts":186,"translated":186,"official":186,"pct":100},"bonds":{"texts":138,"translated":138,"official":138,"pct":100},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":679,"official":679,"pct":100},"config":{"texts":110,"translated":110,"official":103,"pct":100},"effects":{"texts":1083,"translated":1083,"official":1083,"pct":100},"emotes":{"texts":41,"translated":41,"official":3,"pct":100},"enemies":{"texts":1734,"translated":1734,"official":1734,"pct":100},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":582,"official":570,"pct":100},"modules":{"texts":2482,"translated":2437,"official":2419,"pct":98.2},"operators":{"texts":873,"translated":851,"official":843,"pct":97.5},"skills":{"texts":5646,"translated":5439,"official":5439,"pct":96.3},"stages":{"texts":1124,"translated":1124,"official":1122,"pct":100},"talents":{"texts":5963,"translated":5687,"official":5679,"pct":95.4},"tokens":{"texts":456,"translated":456,"official":455,"pct":100},"traits":{"texts":1870,"translated":1854,"official":1854,"pct":99.1}},"totals":{"texts":23794,"translated":23228,"official":23134,"pct":97.6}},"names":{"\"炎佑\"":"Yan's Protection","Dor-1号失败品":"Dor-1 Failure","Dor-α号失败品":"Dor-α Failure","Dor-β号复制体":"Dor-β Replica","M3茧甲":"M3 Cocoon Shell","W·悬赏":"W/Bounty","“变形者集群”":"'Damazti Cluster'","“墓碑”":"'Gravestone'","“墓碑”·悬赏":"'Gravestone'/Bounty","“复仇者”":"'Hateful Avenger'","“复仇者”·悬赏":"'Hateful Avenger'/Bounty","“小自在”":"'Freeling'","“巨大的丑东西”":"'The Big Ugly Thing'","“巨大的丑东西”·悬赏":"'The Big Ugly Thing'/Bounty","“帝国的甲胄”":"'Armor of the Empire'","“庞贝”":"'Pompeii'","“庞贝”·悬赏":"'Pompeii'/Bounty","“斩胄之剑”":"'Armor Cleaver'","“灵幛”":"Sudaram","“独轮车玩具”":"'Unicycle Toy'","“破胄之锤”":"'Armor Crusher'","“碎铳之簧”":"'Gunshatter'","“神秘顾客”":"'Mystery Customer'","“耀阳”":"'Blazing Sun'","“自在”":"'Free'","“自在”·悬赏":"'Free'/Bounty","“萨科塔之眼”":"'Eyes of the Sankta'","“萨科塔之眼”·悬赏":"'Eyes of the Sankta'/Bounty","“萨科塔之翼”":"'Wings of the Sankta'","“萨科塔昂首”":"'Pride of the Sankta'","“萨米的意志”":"'Samivilinn,' the Resolution of the Very North","“裂管之音”/“断弦之音”":"'Echoes of Cracked Pipe'/'Echoes of Broken Strings'","“越长尘”":"'Sand Voyager'","“遗弃者”":"'Forsaken One'","“遗弃者”·悬赏":"'Forsaken One'/Bounty","“邪魔的利刃”":"'Demon's Blade'","“邪魔的利刃”·悬赏":"'Demon's Blade'/Bounty","“鼠王”·悬赏":"'Rat King'/Bounty","不屈":"Resilient","不屈弹射器":"Tough Launcher","不祥幻影":"Ominous Apparition","不稳定要素":"Unstable Element","业余竞演者":"Amateur Performer","业务指标":"Work Quota","临时收音师":"Audio Technician","主角阵营角色":"Hero's Sidekick","乌尔比安":"Ulpianus","乌顶巨角卢鲁":"Blackhorn Rhuul","九流之缘":"Streetwise Ties","人事部文档":"HR File","人才盲盒":"Talent Blind Box","仇白":"Qiubai","从不混淆的方向":"Undeviating Course","令":"Ling","以己之长":"Personal Power","伊内丝":"Ines","伊利昂的木驮兽":"Wooden Burdenbeast of Ilion","伊奥莱塔·罗素":"Ioleta Russell","伊芙利特":"Ifrit","休眠子裔":"Dormant Heir","休谟斯":"Humus","休露丝":"Sciurus","众志合一":"Wills As One","优等生":"Top Student","传奇重犯":"Infamous Recidivist","伪装服":"Disguise Outfit","伺夜":"Vigil","余":"Yu","佩佩":"Pepe","俗心":"Vernacularism","保护目标(冻结状态)":"Protection Objective (Frozen)","信仰搅拌机":"Sankta Miksaparato","信标":"Transmitter","假想敌:再生":"OpFor: Rebirth","假想敌:弦":"OpFor: String","假想敌:淤困":"OpFor: Quagmire","假想敌:管":"OpFor: Pipe","假想敌:胄":"OpFor: Armor","假想敌:蚀裂":"OpFor: Fissure","假想敌:铳":"OpFor: Gun","假想敌:镜膜":"OpFor: Mirror","假想敌:骨刺":"OpFor: Bonespur","假想敌:黑云":"OpFor: BlackCloud","假日威龙陈":"Ch'en the Holungday","傀影":"Phantom","催泪瓦斯":"Teargas Can","元核孽生者":"Nucleic Maleficent","元核孽生者·悬赏":"Nucleic Maleficient/Bounty","克莱门莎":"Clementia","冒失的小弟":"Careless Underling","军用猎狗":"Military Hound","冰爆源石虫":Line truncated
|
||||
{"version":1,"lang":"en","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (en)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"tools/i18n/fallback-remake.json (the remake), tools/i18n/fallback-pr70.json (PR #70 by @YuriRestia), public/i18n/en.json","coverage":{"bands":{"texts":186,"translated":186,"official":186,"pct":100},"bonds":{"texts":138,"translated":138,"official":138,"pct":100},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":679,"official":679,"pct":100},"config":{"texts":110,"translated":110,"official":103,"pct":100},"effects":{"texts":1083,"translated":1083,"official":1083,"pct":100},"emotes":{"texts":41,"translated":41,"official":3,"pct":100},"enemies":{"texts":1734,"translated":1734,"official":1734,"pct":100},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":582,"official":570,"pct":100},"modules":{"texts":2498,"translated":2449,"official":2431,"pct":98},"operators":{"texts":876,"translated":854,"official":846,"pct":97.5},"skills":{"texts":5673,"translated":5439,"official":5439,"pct":95.9},"stages":{"texts":1124,"translated":1124,"official":1122,"pct":100},"talents":{"texts":5996,"translated":5688,"official":5680,"pct":94.9},"tokens":{"texts":458,"translated":458,"official":457,"pct":100},"traits":{"texts":1876,"translated":1860,"official":1860,"pct":99.1}},"totals":{"texts":23881,"translated":23252,"official":23158,"pct":97.4}},"names":{"\"炎佑\"":"Yan's Protection","Dor-1号失败品":"Dor-1 Failure","Dor-α号失败品":"Dor-α Failure","Dor-β号复制体":"Dor-β Replica","M3茧甲":"M3 Cocoon Shell","W·悬赏":"W/Bounty","“变形者集群”":"'Damazti Cluster'","“墓碑”":"'Gravestone'","“墓碑”·悬赏":"'Gravestone'/Bounty","“复仇者”":"'Hateful Avenger'","“复仇者”·悬赏":"'Hateful Avenger'/Bounty","“小自在”":"'Freeling'","“巨大的丑东西”":"'The Big Ugly Thing'","“巨大的丑东西”·悬赏":"'The Big Ugly Thing'/Bounty","“帝国的甲胄”":"'Armor of the Empire'","“庞贝”":"'Pompeii'","“庞贝”·悬赏":"'Pompeii'/Bounty","“斩胄之剑”":"'Armor Cleaver'","“灵幛”":"Sudaram","“独轮车玩具”":"'Unicycle Toy'","“破胄之锤”":"'Armor Crusher'","“碎铳之簧”":"'Gunshatter'","“神秘顾客”":"'Mystery Customer'","“耀阳”":"'Blazing Sun'","“自在”":"'Free'","“自在”·悬赏":"'Free'/Bounty","“萨科塔之眼”":"'Eyes of the Sankta'","“萨科塔之眼”·悬赏":"'Eyes of the Sankta'/Bounty","“萨科塔之翼”":"'Wings of the Sankta'","“萨科塔昂首”":"'Pride of the Sankta'","“萨米的意志”":"'Samivilinn,' the Resolution of the Very North","“裂管之音”/“断弦之音”":"'Echoes of Cracked Pipe'/'Echoes of Broken Strings'","“越长尘”":"'Sand Voyager'","“遗弃者”":"'Forsaken One'","“遗弃者”·悬赏":"'Forsaken One'/Bounty","“邪魔的利刃”":"'Demon's Blade'","“邪魔的利刃”·悬赏":"'Demon's Blade'/Bounty","“鼠王”·悬赏":"'Rat King'/Bounty","不屈":"Resilient","不屈弹射器":"Tough Launcher","不祥幻影":"Ominous Apparition","不稳定要素":"Unstable Element","业余竞演者":"Amateur Performer","业务指标":"Work Quota","临时收音师":"Audio Technician","主角阵营角色":"Hero's Sidekick","乌尔比安":"Ulpianus","乌顶巨角卢鲁":"Blackhorn Rhuul","九流之缘":"Streetwise Ties","人事部文档":"HR File","人才盲盒":"Talent Blind Box","仇白":"Qiubai","从不混淆的方向":"Undeviating Course","令":"Ling","以己之长":"Personal Power","伊内丝":"Ines","伊利昂的木驮兽":"Wooden Burdenbeast of Ilion","伊奥莱塔·罗素":"Ioleta Russell","伊芙利特":"Ifrit","休眠子裔":"Dormant Heir","休谟斯":"Humus","休露丝":"Sciurus","众志合一":"Wills As One","优等生":"Top Student","传奇重犯":"Infamous Recidivist","伪装服":"Disguise Outfit","伺夜":"Vigil","余":"Yu","佩佩":"Pepe","俗心":"Vernacularism","保护目标(冻结状态)":"Protection Objective (Frozen)","信仰搅拌机":"Sankta Miksaparato","信标":"Transmitter","假想敌:再生":"OpFor: Rebirth","假想敌:弦":"OpFor: String","假想敌:淤困":"OpFor: Quagmire","假想敌:管":"OpFor: Pipe","假想敌:胄":"OpFor: Armor","假想敌:蚀裂":"OpFor: Fissure","假想敌:铳":"OpFor: Gun","假想敌:镜膜":"OpFor: Mirror","假想敌:骨刺":"OpFor: Bonespur","假想敌:黑云":"OpFor: BlackCloud","假日威龙陈":"Ch'en the Holungday","傀影":"Phantom","催泪瓦斯":"Teargas Can","元核孽生者":"Nucleic Maleficent","元核孽生者·悬赏":"Nucleic Maleficient/Bounty","克莱门莎":"Clementia","冒失的小弟":"Careless Underling","军用猎狗":"Military Hound","冰爆源石虫":"ILine truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":1,"lang":"ja","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (jp)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"public/i18n/ja.json (the pack's UI strings)","coverage":{"bands":{"texts":186,"translated":186,"official":186,"pct":100},"bonds":{"texts":138,"translated":138,"official":138,"pct":100},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":679,"official":679,"pct":100},"config":{"texts":110,"translated":103,"official":103,"pct":93.6},"effects":{"texts":1083,"translated":1083,"official":1083,"pct":100},"emotes":{"texts":41,"translated":41,"official":3,"pct":100},"enemies":{"texts":1734,"translated":1734,"official":1734,"pct":100},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":570,"official":570,"pct":97.9},"modules":{"texts":2482,"translated":2419,"official":2419,"pct":97.5},"operators":{"texts":873,"translated":843,"official":843,"pct":96.6},"skills":{"texts":5646,"translated":5439,"official":5439,"pct":96.3},"stages":{"texts":1124,"translated":1111,"official":1111,"pct":98.8},"talents":{"texts":5963,"translated":5675,"official":5675,"pct":95.2},"tokens":{"texts":456,"translated":455,"official":455,"pct":99.8},"traits":{"texts":1870,"translated":1854,"official":1854,"pct":99.1}},"totals":{"texts":23794,"translated":23157,"official":23119,"pct":97.3}},"names":{"\"炎佑\"":"「炎祐」","Dor-1号失败品":"Dor-1号失敗作","Dor-α号失败品":"Dor-α号失敗作","Dor-β号复制体":"Dor-β号複製体","M3茧甲":"M3コクーンアーマー","W·悬赏":"懸賞・W","“变形者集群”":"「変形者」","“墓碑”":"「墓碑」","“墓碑”·悬赏":"懸賞・「墓碑」","“复仇者”":"Vendetta","“复仇者”·悬赏":"懸賞・「ヴェンデッタ」","“小自在”":"「小自在」","“巨大的丑东西”":"「ビッグアグリー」","“巨大的丑东西”·悬赏":"懸賞・「ビッグアグリー」","“帝国的甲胄”":"「帝国の甲冑」","“庞贝”":"「ポンペイ」","“庞贝”·悬赏":"懸賞・Pompeii","“斩胄之剑”":"「甲冑断つ剣」","“灵幛”":"「霊骸布」","“独轮车玩具”":"「一輪車のおもちゃ」","“破胄之锤”":"「甲冑割る槌」","“碎铳之簧”":"「機銃砕く輪」","“神秘顾客”":"「謎の客人」","“耀阳”":"「ブレイジング・サン」","“自在”":"「ジザイ」","“自在”·悬赏":"懸賞・「ジザイ」","“萨科塔之眼”":"「サンクタの眼」","“萨科塔之眼”·悬赏":"懸賞・「サンクタの眼」","“萨科塔之翼”":"「サンクタの翼」","“萨科塔昂首”":"「サンクタの仰け反り」","“萨米的意志”":"「サーミの意志」","“裂管之音”/“断弦之音”":"「断絃の音」/「裂管の音」","“越长尘”":"「長塵」","“遗弃者”":"「見棄てし者」","“遗弃者”·悬赏":"懸賞・「見棄てし者」","“邪魔的利刃”":"「悪魔の利刃」","“邪魔的利刃”·悬赏":"懸賞・「悪魔の利刃」","“鼠王”·悬赏":"懸賞・「鼠王」","不屈":"不屈","不屈弹射器":"不屈の射出装置","不祥幻影":"不祥の幻影","不稳定要素":"不安定要素","业余竞演者":"一般参加の競演者","业务指标":"業務ノルマ","临时收音师":"臨時録音技師","主角阵营角色":"主役側の脇役","乌尔比安":"ウルピアヌス","乌顶巨角卢鲁":"黒き大角のルル","九流之缘":"人たらし","人事部文档":"人事部の書類","人才盲盒":"人材抽選","仇白":"チューバイ","从不混淆的方向":"混同せぬ方向","令":"リィン","以己之长":"持ち味を活かして","伊内丝":"イネス","伊利昂的木驮兽":"イリオスの木駄獣","伊奥莱塔·罗素":"イオレッタ・ラッセル","伊芙利特":"イフリータ","休眠子裔":"眠れる眷属","休谟斯":"ヒューマス","休露丝":"スキウース","众志合一":"一致団結","优等生":"優等生","传奇重犯":"伝説の凶悪犯","伪装服":"迷彩ヘルメット","伺夜":"ヴィジェル","余":"ユー","佩佩":"ペペ","俗心":"俗心","保护目标(冻结状态)":"防衛ライン(凍結状態)","信仰搅拌机":"サンクタ・ミキサー","信标":"ビーコン","假想敌:再生":"仮想敵:再生","假想敌:弦":"仮想敵:絃","假想敌:淤困":"仮想敵:泥濘","假想敌:管":"仮想敵:管","假想敌:胄":"仮想敵:冑","假想敌:蚀裂":"仮想敵:蝕裂","假想敌:铳":"仮想敵:銃","假想敌:镜膜":"仮想敵:鏡膜","假想敌:骨刺":"仮想敵:骨棘","假想敌:黑云":"仮想敵:黒雲","假日威龙陈":"遊龍チェン","傀影":"Line truncated
|
||||
{"version":1,"lang":"ja","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (jp)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"public/i18n/ja.json (the pack's UI strings)","coverage":{"bands":{"texts":186,"translated":186,"official":186,"pct":100},"bonds":{"texts":138,"translated":138,"official":138,"pct":100},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":679,"official":679,"pct":100},"config":{"texts":110,"translated":103,"official":103,"pct":93.6},"effects":{"texts":1083,"translated":1083,"official":1083,"pct":100},"emotes":{"texts":41,"translated":41,"official":3,"pct":100},"enemies":{"texts":1734,"translated":1734,"official":1734,"pct":100},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":570,"official":570,"pct":97.9},"modules":{"texts":2498,"translated":2431,"official":2431,"pct":97.3},"operators":{"texts":876,"translated":846,"official":846,"pct":96.6},"skills":{"texts":5673,"translated":5439,"official":5439,"pct":95.9},"stages":{"texts":1124,"translated":1111,"official":1111,"pct":98.8},"talents":{"texts":5996,"translated":5676,"official":5676,"pct":94.7},"tokens":{"texts":458,"translated":457,"official":457,"pct":99.8},"traits":{"texts":1876,"translated":1860,"official":1860,"pct":99.1}},"totals":{"texts":23881,"translated":23181,"official":23143,"pct":97.1}},"names":{"\"炎佑\"":"「炎祐」","Dor-1号失败品":"Dor-1号失敗作","Dor-α号失败品":"Dor-α号失敗作","Dor-β号复制体":"Dor-β号複製体","M3茧甲":"M3コクーンアーマー","W·悬赏":"懸賞・W","“变形者集群”":"「変形者」","“墓碑”":"「墓碑」","“墓碑”·悬赏":"懸賞・「墓碑」","“复仇者”":"Vendetta","“复仇者”·悬赏":"懸賞・「ヴェンデッタ」","“小自在”":"「小自在」","“巨大的丑东西”":"「ビッグアグリー」","“巨大的丑东西”·悬赏":"懸賞・「ビッグアグリー」","“帝国的甲胄”":"「帝国の甲冑」","“庞贝”":"「ポンペイ」","“庞贝”·悬赏":"懸賞・Pompeii","“斩胄之剑”":"「甲冑断つ剣」","“灵幛”":"「霊骸布」","“独轮车玩具”":"「一輪車のおもちゃ」","“破胄之锤”":"「甲冑割る槌」","“碎铳之簧”":"「機銃砕く輪」","“神秘顾客”":"「謎の客人」","“耀阳”":"「ブレイジング・サン」","“自在”":"「ジザイ」","“自在”·悬赏":"懸賞・「ジザイ」","“萨科塔之眼”":"「サンクタの眼」","“萨科塔之眼”·悬赏":"懸賞・「サンクタの眼」","“萨科塔之翼”":"「サンクタの翼」","“萨科塔昂首”":"「サンクタの仰け反り」","“萨米的意志”":"「サーミの意志」","“裂管之音”/“断弦之音”":"「断絃の音」/「裂管の音」","“越长尘”":"「長塵」","“遗弃者”":"「見棄てし者」","“遗弃者”·悬赏":"懸賞・「見棄てし者」","“邪魔的利刃”":"「悪魔の利刃」","“邪魔的利刃”·悬赏":"懸賞・「悪魔の利刃」","“鼠王”·悬赏":"懸賞・「鼠王」","不屈":"不屈","不屈弹射器":"不屈の射出装置","不祥幻影":"不祥の幻影","不稳定要素":"不安定要素","业余竞演者":"一般参加の競演者","业务指标":"業務ノルマ","临时收音师":"臨時録音技師","主角阵营角色":"主役側の脇役","乌尔比安":"ウルピアヌス","乌顶巨角卢鲁":"黒き大角のルル","九流之缘":"人たらし","人事部文档":"人事部の書類","人才盲盒":"人材抽選","仇白":"チューバイ","从不混淆的方向":"混同せぬ方向","令":"リィン","以己之长":"持ち味を活かして","伊内丝":"イネス","伊利昂的木驮兽":"イリオスの木駄獣","伊奥莱塔·罗素":"イオレッタ・ラッセル","伊芙利特":"イフリータ","休眠子裔":"眠れる眷属","休谟斯":"ヒューマス","休露丝":"スキウース","众志合一":"一致団結","优等生":"優等生","传奇重犯":"伝説の凶悪犯","伪装服":"迷彩ヘルメット","伺夜":"ヴィジェル","余":"ユー","佩佩":"ペペ","俗心":"俗心","保护目标(冻结状态)":"防衛ライン(凍結状態)","信仰搅拌机":"サンクタ・ミキサー","信标":"ビーコン","假想敌:再生":"仮想敵:再生","假想敌:弦":"仮想敵:絃","假想敌:淤困":"仮想敵:泥濘","假想敌:管":"仮想敵:管","假想敌:胄":"仮想敵:冑","假想敌:蚀裂":"仮想敵:蝕裂","假想敌:铳":"仮想敵:銃","假想敌:镜膜":"仮想敵:鏡膜","假想敌:骨刺":"仮想敵:骨棘","假想敌:黑云":"仮想敵:黒雲","假日威龙陈":"遊龍チェン","傀影":"Line truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"version":1,"lang":"ko","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (kr)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"public/i18n/ko.json (the pack's UI strings)","coverage":{"bands":{"texts":186,"translated":186,"official":186,"pct":100},"bonds":{"texts":138,"translated":138,"official":138,"pct":100},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":679,"official":679,"pct":100},"config":{"texts":110,"translated":103,"official":103,"pct":93.6},"effects":{"texts":1083,"translated":1083,"official":1083,"pct":100},"emotes":{"texts":41,"translated":41,"official":3,"pct":100},"enemies":{"texts":1734,"translated":1734,"official":1734,"pct":100},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":570,"official":570,"pct":97.9},"modules":{"texts":2482,"translated":2419,"official":2419,"pct":97.5},"operators":{"texts":873,"translated":843,"official":843,"pct":96.6},"skills":{"texts":5646,"translated":5439,"official":5439,"pct":96.3},"stages":{"texts":1124,"translated":1111,"official":1111,"pct":98.8},"talents":{"texts":5963,"translated":5679,"official":5679,"pct":95.2},"tokens":{"texts":456,"translated":455,"official":455,"pct":99.8},"traits":{"texts":1870,"translated":1854,"official":1854,"pct":99.1}},"totals":{"texts":23794,"translated":23161,"official":23123,"pct":97.3}},"names":{"\"炎佑\"":"'염의 가호'","Dor-1号失败品":"Dor-1호 실패작","Dor-α号失败品":"Dor-α호 실패작","Dor-β号复制体":"Dor-β호 복제품","M3茧甲":"M3 고치 갑옷","W·悬赏":"W - 수배","“变形者集群”":"'다마즈티'","“墓碑”":"'툼스톤'","“墓碑”·悬赏":"'툼스톤' - 수배","“复仇者”":"'어벤져'","“复仇者”·悬赏":"'어벤져' - 수배","“小自在”":"'작은 즈자이'","“巨大的丑东西”":"'거대하고 못생긴 것'","“巨大的丑东西”·悬赏":"'거대하고 못생긴 것' - 수배","“帝国的甲胄”":"'제국의 갑옷'","“庞贝”":"'폼페이'","“庞贝”·悬赏":"'폼페이' - 수배","“斩胄之剑”":"'갑주를 베는 검'","“灵幛”":"'영장'","“独轮车玩具”":"'완구 외발자전거'","“破胄之锤”":"'갑주를 부수는 해머'","“碎铳之簧”":"'총을 부수는 리드'","“神秘顾客”":"'신비한 고객'","“耀阳”":"'눈 부신 태양'","“自在”":"'즈자이'","“自在”·悬赏":"'즈자이' - 수배","“萨科塔之眼”":"'산크타의 눈'","“萨科塔之眼”·悬赏":"'산크타의 눈' - 수배","“萨科塔之翼”":"'산크타의 날개'","“萨科塔昂首”":"'산크타의 긍지'","“萨米的意志”":"'사미의 의지'","“裂管之音”/“断弦之音”":"'단현지음'/'열관지음'","“越长尘”":"'월장진'","“遗弃者”":"'버림받은 자'","“遗弃者”·悬赏":"'버림받은 자' - 수배","“邪魔的利刃”":"'데몬의 칼날'","“邪魔的利刃”·悬赏":"'데몬의 칼날' - 수배","“鼠王”·悬赏":"'래트킹' - 수배","不屈":"불굴","不屈弹射器":"불굴의 사출기","不祥幻影":"불길한 환영","不稳定要素":"불안요소","业余竞演者":"아마추어 경연자","业务指标":"업무 지표","临时收音师":"임시 음향기사","主角阵营角色":"주인공 진영 캐릭터","乌尔比安":"울피아누스","乌顶巨角卢鲁":"검은 뿔의 루울","九流之缘":"구류의 인연","人事部文档":"인사부 파일","人才盲盒":"인재 랜덤박스","仇白":"치우바이","从不混淆的方向":"헷갈리지 않는 방향","令":"링","以己之长":"장점 활용","伊内丝":"이네스","伊利昂的木驮兽":"일리온의 나무 버든비스트","伊奥莱塔·罗素":"이올레타 로시","伊芙利特":"이프리트","休眠子裔":"잠자는 후예","休谟斯":"휴머스","休露丝":"시우루스","众志合一":"일치단결","优等生":"우등생","传奇重犯":"전설의 중범죄수","伪装服":"위장복","伺夜":"비질","余":"위","佩佩":"페페","俗心":"수신","保护目标(冻结状态)":"방어 포인트 (빙결 상태)","信仰搅拌机":"산크타 믹사파라토","信标":"비콘","假想敌:再生":"가상적: 재생","假想敌:弦":"가상적: 현","假想敌:淤困":"가상적: 정체","假想敌:管":"가상적: 관","假想敌:胄":"가상적: 갑주","假想敌:蚀裂":"가상적: 침식","假想敌:铳":"가상적: 총","假想敌:镜膜":"가상적: 경막","假想敌:骨刺":"가상적: 골극","假想敌:黑云":"가상적: 흑운","假日威龙陈":"첸 더 홀룽데이","傀影":"팬텀","催泪瓦斯":"최루가스","元核孽生者":"원핵의 악생자","元核孽生者·悬赏":"원핵의 악생자 - 수배","克莱Line truncated
|
||||
{"version":1,"lang":"ko","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (kr)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"public/i18n/ko.json (the pack's UI strings)","coverage":{"bands":{"texts":186,"translated":186,"official":186,"pct":100},"bonds":{"texts":138,"translated":138,"official":138,"pct":100},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":679,"official":679,"pct":100},"config":{"texts":110,"translated":103,"official":103,"pct":93.6},"effects":{"texts":1083,"translated":1083,"official":1083,"pct":100},"emotes":{"texts":41,"translated":41,"official":3,"pct":100},"enemies":{"texts":1734,"translated":1734,"official":1734,"pct":100},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":570,"official":570,"pct":97.9},"modules":{"texts":2498,"translated":2431,"official":2431,"pct":97.3},"operators":{"texts":876,"translated":846,"official":846,"pct":96.6},"skills":{"texts":5673,"translated":5439,"official":5439,"pct":95.9},"stages":{"texts":1124,"translated":1111,"official":1111,"pct":98.8},"talents":{"texts":5996,"translated":5680,"official":5680,"pct":94.7},"tokens":{"texts":458,"translated":457,"official":457,"pct":99.8},"traits":{"texts":1876,"translated":1860,"official":1860,"pct":99.1}},"totals":{"texts":23881,"translated":23185,"official":23147,"pct":97.1}},"names":{"\"炎佑\"":"'염의 가호'","Dor-1号失败品":"Dor-1호 실패작","Dor-α号失败品":"Dor-α호 실패작","Dor-β号复制体":"Dor-β호 복제품","M3茧甲":"M3 고치 갑옷","W·悬赏":"W - 수배","“变形者集群”":"'다마즈티'","“墓碑”":"'툼스톤'","“墓碑”·悬赏":"'툼스톤' - 수배","“复仇者”":"'어벤져'","“复仇者”·悬赏":"'어벤져' - 수배","“小自在”":"'작은 즈자이'","“巨大的丑东西”":"'거대하고 못생긴 것'","“巨大的丑东西”·悬赏":"'거대하고 못생긴 것' - 수배","“帝国的甲胄”":"'제국의 갑옷'","“庞贝”":"'폼페이'","“庞贝”·悬赏":"'폼페이' - 수배","“斩胄之剑”":"'갑주를 베는 검'","“灵幛”":"'영장'","“独轮车玩具”":"'완구 외발자전거'","“破胄之锤”":"'갑주를 부수는 해머'","“碎铳之簧”":"'총을 부수는 리드'","“神秘顾客”":"'신비한 고객'","“耀阳”":"'눈 부신 태양'","“自在”":"'즈자이'","“自在”·悬赏":"'즈자이' - 수배","“萨科塔之眼”":"'산크타의 눈'","“萨科塔之眼”·悬赏":"'산크타의 눈' - 수배","“萨科塔之翼”":"'산크타의 날개'","“萨科塔昂首”":"'산크타의 긍지'","“萨米的意志”":"'사미의 의지'","“裂管之音”/“断弦之音”":"'단현지음'/'열관지음'","“越长尘”":"'월장진'","“遗弃者”":"'버림받은 자'","“遗弃者”·悬赏":"'버림받은 자' - 수배","“邪魔的利刃”":"'데몬의 칼날'","“邪魔的利刃”·悬赏":"'데몬의 칼날' - 수배","“鼠王”·悬赏":"'래트킹' - 수배","不屈":"불굴","不屈弹射器":"불굴의 사출기","不祥幻影":"불길한 환영","不稳定要素":"불안요소","业余竞演者":"아마추어 경연자","业务指标":"업무 지표","临时收音师":"임시 음향기사","主角阵营角色":"주인공 진영 캐릭터","乌尔比安":"울피아누스","乌顶巨角卢鲁":"검은 뿔의 루울","九流之缘":"구류의 인연","人事部文档":"인사부 파일","人才盲盒":"인재 랜덤박스","仇白":"치우바이","从不混淆的方向":"헷갈리지 않는 방향","令":"링","以己之长":"장점 활용","伊内丝":"이네스","伊利昂的木驮兽":"일리온의 나무 버든비스트","伊奥莱塔·罗素":"이올레타 로시","伊芙利特":"이프리트","休眠子裔":"잠자는 후예","休谟斯":"휴머스","休露丝":"시우루스","众志合一":"일치단결","优等生":"우등생","传奇重犯":"전설의 중범죄수","伪装服":"위장복","伺夜":"비질","余":"위","佩佩":"페페","俗心":"수신","保护目标(冻结状态)":"방어 포인트 (빙결 상태)","信仰搅拌机":"산크타 믹사파라토","信标":"비콘","假想敌:再生":"가상적: 재생","假想敌:弦":"가상적: 현","假想敌:淤困":"가상적: 정체","假想敌:管":"가상적: 관","假想敌:胄":"가상적: 갑주","假想敌:蚀裂":"가상적: 침식","假想敌:铳":"가상적: 총","假想敌:镜膜":"가상적: 경막","假想敌:骨刺":"가상적: 골극","假想敌:黑云":"가상적: 흑운","假日威龙陈":"첸 더 홀룽데이","傀影":"팬텀","催泪瓦斯":"최루가스","元核孽生者":"원핵의 악생자","元核孽生者·悬赏":"원핵의 악생자 - 수배","克莱Line truncated
|
||||
@@ -1 +1 @@
|
||||
{"version":1,"lang":"zh-TW","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (tw)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"public/i18n/zh-TW.json (the pack's UI strings)","coverage":{"bands":{"texts":186,"translated":170,"official":170,"pct":91.4},"bonds":{"texts":138,"translated":130,"official":130,"pct":94.2},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":674,"official":674,"pct":99.3},"config":{"texts":110,"translated":103,"official":103,"pct":93.6},"effects":{"texts":1083,"translated":1053,"official":1053,"pct":97.2},"emotes":{"texts":41,"translated":22,"official":3,"pct":53.7},"enemies":{"texts":1734,"translated":1659,"official":1659,"pct":95.7},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":544,"official":544,"pct":93.5},"modules":{"texts":2482,"translated":2302,"official":2302,"pct":92.7},"operators":{"texts":873,"translated":585,"official":585,"pct":67},"skills":{"texts":5646,"translated":5110,"official":5110,"pct":90.5},"stages":{"texts":1124,"translated":901,"official":901,"pct":80.2},"talents":{"texts":5963,"translated":5368,"official":5368,"pct":90},"tokens":{"texts":456,"translated":433,"official":433,"pct":95},"traits":{"texts":1870,"translated":1854,"official":1854,"pct":99.1}},"totals":{"texts":23794,"translated":21735,"official":21716,"pct":91.3}},"names":{"\"炎佑\"":"“炎佑”","Dor-1号失败品":"Dor-1號失敗品","Dor-α号失败品":"Dor-α號失敗品","Dor-β号复制体":"Dor-β號複製體","M3茧甲":"M3繭甲","W·悬赏":"W·懸賞","“变形者集群”":"“變形者集群”","“墓碑”·悬赏":"“墓碑”·懸賞","“复仇者”":"“復仇者”","“复仇者”·悬赏":"“復仇者”·懸賞","“巨大的丑东西”":"“巨大的醜東西”","“巨大的丑东西”·悬赏":"“巨大的醜東西”·懸賞","“帝国的甲胄”":"“帝國的甲胄”","“庞贝”":"“龐貝”","“庞贝”·悬赏":"“龐貝”·懸賞","“斩胄之剑”":"“斬胄之劍”","“灵幛”":"“靈幛”","“独轮车玩具”":"“獨輪車玩具”","“破胄之锤”":"“破胄之錘”","“碎铳之簧”":"“碎銃之簧”","“神秘顾客”":"“神秘顧客”","“耀阳”":"“耀陽”","“自在”·悬赏":"“自在”·懸賞","“萨科塔之眼”":"“薩科塔之眼”","“萨科塔之眼”·悬赏":"“薩科塔之眼”·懸賞","“萨科塔之翼”":"“薩科塔之翼”","“萨科塔昂首”":"“薩科塔昂首”","“萨米的意志”":"“薩米的意志”","“裂管之音”/“断弦之音”":"“裂管之音”/“斷弦之音”","“越长尘”":"“越長塵”","“遗弃者”":"“遺棄者”","“遗弃者”·悬赏":"“遺棄者”·懸賞","“邪魔的利刃”·悬赏":"“邪魔的利刃”·懸賞","“鼠王”·悬赏":"“鼠王”·懸賞","不屈弹射器":"不屈彈射器","不稳定要素":"不穩定要素","业余竞演者":"業餘競演者","业务指标":"業務指標","临时收音师":"臨時收音師","主角阵营角色":"主角陣營角色","乌尔比安":"烏爾比安","乌顶巨角卢鲁":"烏頂巨角盧魯","九流之缘":"九流之緣","人事部文档":"人事部文件","从不混淆的方向":"從不混淆的方向","以己之长":"以己之長","伊内丝":"伊內絲","伊利昂的木驮兽":"伊利昂的木馱獸","伊奥莱塔·罗素":"伊奧萊塔·羅素","休谟斯":"休謨斯","休露丝":"休露絲","众志合一":"眾志合一","优等生":"優等生","传奇重犯":"傳奇重犯","伪装服":"偽裝服","余":"餘","保护目标(冻结状态)":"保護目標(凍結狀態)","信仰搅拌机":"信仰攪拌機","信标":"信標","假想敌:再生":"假想敵:再生","假想敌:弦":"假想敵:弦","假想敌:淤困":"假想敵:淤困","假想敌:管":"假想敵:管","假想敌:胄":"假想敵:胄","假想敌:蚀裂":"假想敵:蝕裂","假想敌:铳":"假想敵:銃","假想敌:镜膜":"假想敵:鏡膜","假想敌:骨刺":"假想敵:骨刺","假想敌:黑云":"假想敵:黑雲","假日威龙陈":"假日威龍陳","催泪瓦斯":"催淚瓦斯","元核孽生者·悬赏":"元核孽生者·懸賞","克莱门莎":"克萊門莎","军用猎狗":"軍用獵狗","冰爆源石虫":"冰爆源石蟲","冲击式施术单元":"衝擊式施術單元","凋零骑士":"凋零騎士","凋零骑士·悬赏":"凋零騎士·懸賞","凛御银灰":"凜御銀灰","凯尔希":"凱爾希","凯瑟琳":"凱瑟琳","列装":"列裝","利滚利":"利滾利","刺胄之弹":"刺胄之彈","加急调派":"緊急調派","加练!":"加練!","加速维式重锤":"加速維式重鎚","医疗探机":"醫療探機","升华":"昇華","华法琳":"華法琳","协Line truncated
|
||||
{"version":1,"lang":"zh-TW","meta":{"generator":"tools/build-i18n.mjs","source":{"id":"assets","label":"ArknightsAssets/ArknightsGamedata (tw)","home":"https://github.com/ArknightsAssets/ArknightsGamedata","season":"act2autochess"},"fallback":"public/i18n/zh-TW.json (the pack's UI strings)","coverage":{"bands":{"texts":186,"translated":170,"official":170,"pct":91.4},"bonds":{"texts":138,"translated":130,"official":130,"pct":94.2},"bosses":{"texts":66,"translated":66,"official":66,"pct":100},"choices":{"texts":679,"translated":674,"official":674,"pct":99.3},"config":{"texts":110,"translated":103,"official":103,"pct":93.6},"effects":{"texts":1083,"translated":1053,"official":1053,"pct":97.2},"emotes":{"texts":41,"translated":22,"official":3,"pct":53.7},"enemies":{"texts":1734,"translated":1659,"official":1659,"pct":95.7},"factions":{"texts":14,"translated":14,"official":14,"pct":100},"garrisons":{"texts":747,"translated":747,"official":747,"pct":100},"items":{"texts":582,"translated":544,"official":544,"pct":93.5},"modules":{"texts":2498,"translated":2329,"official":2329,"pct":93.2},"operators":{"texts":876,"translated":590,"official":590,"pct":67.4},"skills":{"texts":5673,"translated":5131,"official":5131,"pct":90.4},"stages":{"texts":1124,"translated":901,"official":901,"pct":80.2},"talents":{"texts":5996,"translated":5410,"official":5410,"pct":90.2},"tokens":{"texts":458,"translated":435,"official":435,"pct":95},"traits":{"texts":1876,"translated":1860,"official":1860,"pct":99.1}},"totals":{"texts":23881,"translated":21838,"official":21819,"pct":91.4}},"names":{"\"炎佑\"":"“炎佑”","Dor-1号失败品":"Dor-1號失敗品","Dor-α号失败品":"Dor-α號失敗品","Dor-β号复制体":"Dor-β號複製體","M3茧甲":"M3繭甲","W·悬赏":"W·懸賞","“变形者集群”":"“變形者集群”","“墓碑”·悬赏":"“墓碑”·懸賞","“复仇者”":"“復仇者”","“复仇者”·悬赏":"“復仇者”·懸賞","“巨大的丑东西”":"“巨大的醜東西”","“巨大的丑东西”·悬赏":"“巨大的醜東西”·懸賞","“帝国的甲胄”":"“帝國的甲胄”","“庞贝”":"“龐貝”","“庞贝”·悬赏":"“龐貝”·懸賞","“斩胄之剑”":"“斬胄之劍”","“灵幛”":"“靈幛”","“独轮车玩具”":"“獨輪車玩具”","“破胄之锤”":"“破胄之錘”","“碎铳之簧”":"“碎銃之簧”","“神秘顾客”":"“神秘顧客”","“耀阳”":"“耀陽”","“自在”·悬赏":"“自在”·懸賞","“萨科塔之眼”":"“薩科塔之眼”","“萨科塔之眼”·悬赏":"“薩科塔之眼”·懸賞","“萨科塔之翼”":"“薩科塔之翼”","“萨科塔昂首”":"“薩科塔昂首”","“萨米的意志”":"“薩米的意志”","“裂管之音”/“断弦之音”":"“裂管之音”/“斷弦之音”","“越长尘”":"“越長塵”","“遗弃者”":"“遺棄者”","“遗弃者”·悬赏":"“遺棄者”·懸賞","“邪魔的利刃”·悬赏":"“邪魔的利刃”·懸賞","“鼠王”·悬赏":"“鼠王”·懸賞","不屈弹射器":"不屈彈射器","不稳定要素":"不穩定要素","业余竞演者":"業餘競演者","业务指标":"業務指標","临时收音师":"臨時收音師","主角阵营角色":"主角陣營角色","乌尔比安":"烏爾比安","乌顶巨角卢鲁":"烏頂巨角盧魯","九流之缘":"九流之緣","人事部文档":"人事部文件","从不混淆的方向":"從不混淆的方向","以己之长":"以己之長","伊内丝":"伊內絲","伊利昂的木驮兽":"伊利昂的木馱獸","伊奥莱塔·罗素":"伊奧萊塔·羅素","休谟斯":"休謨斯","休露丝":"休露絲","众志合一":"眾志合一","优等生":"優等生","传奇重犯":"傳奇重犯","伪装服":"偽裝服","余":"餘","保护目标(冻结状态)":"保護目標(凍結狀態)","信仰搅拌机":"信仰攪拌機","信标":"信標","假想敌:再生":"假想敵:再生","假想敌:弦":"假想敵:弦","假想敌:淤困":"假想敵:淤困","假想敌:管":"假想敵:管","假想敌:胄":"假想敵:胄","假想敌:蚀裂":"假想敵:蝕裂","假想敌:铳":"假想敵:銃","假想敌:镜膜":"假想敵:鏡膜","假想敌:骨刺":"假想敵:骨刺","假想敌:黑云":"假想敵:黑雲","假日威龙陈":"假日威龍陳","催泪瓦斯":"催淚瓦斯","元核孽生者·悬赏":"元核孽生者·懸賞","克莱门莎":"克萊門莎","军用猎狗":"軍用獵狗","冰爆源石虫":"冰爆源石蟲","冲击式施术单元":"衝擊式施術單元","凋零骑士":"凋零騎士","凋零骑士·悬赏":"凋零騎士·懸賞","凛御银灰":"凜御銀灰","凯尔希":"凱爾希","凯瑟琳":"凱瑟琳","列装":"列裝","利滚利":"利滾利","刺胄之弹":"刺胄之彈","加急调派":"緊急調派","加练!":"加練!","加速维式重锤":"加速維式重鎚","医疗探机":"醫療探機","升华":"昇華","华法琳":"華法琳",Line truncated
|
||||
+1
-1
@@ -1 +1 @@
|
||||
{"token_10000_silent_healrb":{"tokenId":"token_10000_silent_healrb","kind":"summon","name":"医疗探机","appellation":"Medical Drone","desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","profession":"TOKEN","subProfessionId":"notchar1","position":"ALL","displayType":"DEFAULT","placeable":true,"ownerRange":false,"owners":["chess_char_2_02_a","chess_char_2_02_b"],"stats":{"maxHp":1000,"atk":85,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"rangeGrid":[[1,-1],[1,0],[1,1],[0,-1],[0,0],[0,1],[-1,-1],[-1,0],[-1,1]],"dmgType":"heal","attackKind":"heal","projectile":"orb","canHitFly":false,"skill":{"skillId":"skcom_withdraw","bb":{}},"deployLimit":1,"count":1,"abnormal":[],"variants":{"chess_char_2_02_a":{"phase":1,"level":60,"stats":{"maxHp":1000,"atk":85,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"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},"rangeGrid":[[1,-1],[1,0],[1,1],[0,-1],[0,0],[0,1],[-1,-1],[-1,0],[-1,1]],"trait":{"desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","bb":{},"bbStr":{}},"dmgType":"heal","attackKind":"heal","projectile":"orb","canHitFly":false,"targetPriority":null,"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1},"talents":[],"count":1,"sources":["skill","display"],"bySkill":{"0":{"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0},"count":null,"sources":["display"]}}},"chess_char_2_02_b":{"phase":2,"level":55,"stats":{"maxHp":1000,"atk":114,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"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},"rangeGrid":[[1,-1],[1,0],[1,1],[0,-1],[0,0],[0,1],[-1,-1],[-1,0],[-1,1]],"trait":{"desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","bb":{},"bbStr":{}},"dmgType":"heal","attackKind":"heal","projectile":"orb","canHitFly":false,"targetPriority":null,"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1},"talents":[],"count":1,"sources":["skill","display"],"bySkill":{"0":{"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0},"count":null,"sources":["display"]}},"byModule":{"none":{"stats":{"maxHp":1000,"atk":114,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"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},"trait":{"desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","bb":{},"bbStr":{}},"talents":[]}}}},"assets":{"avatar":"token_10000_silent_healrb","spine":"token_10000_silent_healrb"}},"token_10006_vodfox_doll":{"tokenId":"token_10006_vodfox_doll","kind":"summon"Line truncated
|
||||
{"token_10000_silent_healrb":{"tokenId":"token_10000_silent_healrb","kind":"summon","name":"医疗探机","appellation":"Medical Drone","desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","profession":"TOKEN","subProfessionId":"notchar1","position":"ALL","displayType":"DEFAULT","placeable":true,"ownerRange":false,"owners":["chess_char_2_02_a","chess_char_2_02_b"],"stats":{"maxHp":1000,"atk":85,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"spRecovery":1,"hpRecoveryPerSec":0,"moveSpeed":1,"tauntLevel":0,"massLevel":0,"deployLimit":1,"deckStack":0},"rangeGrid":[[1,-1],[1,0],[1,1],[0,-1],[0,0],[0,1],[-1,-1],[-1,0],[-1,1]],"dmgType":"heal","attackKind":"heal","projectile":"orb","canHitFly":false,"skill":{"skillId":"skcom_withdraw","bb":{}},"deployLimit":1,"count":1,"abnormal":[],"variants":{"chess_char_2_02_a":{"phase":1,"level":60,"stats":{"maxHp":1000,"atk":85,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"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},"rangeGrid":[[1,-1],[1,0],[1,1],[0,-1],[0,0],[0,1],[-1,-1],[-1,0],[-1,1]],"trait":{"desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","bb":{},"bbStr":{}},"dmgType":"heal","attackKind":"heal","projectile":"orb","canHitFly":false,"targetPriority":null,"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1},"talents":[],"count":1,"sources":["skill","display"],"bySkill":{"0":{"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0},"count":null,"sources":["display"]}}},"chess_char_2_02_b":{"phase":2,"level":55,"stats":{"maxHp":1000,"atk":114,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"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},"rangeGrid":[[1,-1],[1,0],[1,1],[0,-1],[0,0],[0,1],[-1,-1],[-1,0],[-1,1]],"trait":{"desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","bb":{},"bbStr":{}},"dmgType":"heal","attackKind":"heal","projectile":"orb","canHitFly":false,"targetPriority":null,"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":1},"talents":[],"count":1,"sources":["skill","display"],"bySkill":{"0":{"skill":{"skillId":"skcom_withdraw","iconId":"skcom_withdraw","name":"自我销毁","level":1,"desc":"10秒后自动销毁","descRaw":"<@ba.vup>10</>秒后自动销毁","skillType":"PASSIVE","durationType":"NONE","duration":10,"spType":"ON_DEPLOY","spCost":0,"initSp":0,"maxChargeTime":0,"increment":0,"bb":{},"bbStr":{},"rangeId":null,"rangeGrid":null,"prefabId":"skcom_withdraw","trigger":{"rule":"DEFAULT","rawRule":"DEFAULT","customRangeGrid":null},"index":0},"count":null,"sources":["display"]}},"byModule":{"none":{"stats":{"maxHp":1000,"atk":114,"def":0,"res":0,"cost":5,"blockCnt":0,"bat":0.5,"aspd":100,"respawnTime":5,"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},"trait":{"desc":"不会受到攻击,恢复周围友方单位的生命","descRaw":"不会受到攻击,恢复周围友方单位的生命","bb":{},"bbStr":{}},"talents":[]}}}},"assets":{"avatar":"token_10000_silent_healrb","spine":"token_10000_silent_healrb"}},"token_10006_vodfox_doll":{"tokenId":"token_10006_vodfox_doll","kind":"summon"Line truncated
|
||||
@@ -89,7 +89,7 @@ so old imports keep working: `public/js/ui/gameLogic.js` (`public/js/ui/gameLogi
|
||||
| `server/sim/Battle.js` | one battle field; its methods are in `server/sim/battle/` (`lifecycle.js`, `spawns.js`, `deploy.js`, `blocking.js`, `combat.js`, `status.js`, `summons.js`, `displacement.js`, `events.js` …) |
|
||||
| `server/sim/` (the rest) | `skills.js`, `ai.js`, `damage.js`, `buffs.js`, `targeting.js`, `grid.js` (pathing), `units.js`, `professions.js`, `snapshot.js`, `spec.js` (the BattleSpec), `simdata.js` (data records → engine defs), `nodeData.js` (the Node-only data loader, never served) |
|
||||
| `server/sim/content/` | everything game-specific, installed into a battle by `server/sim/content/index.js` |
|
||||
| `server/sim/content/kits/` | the operator kits: `ops/` holds one file per chess (`<chessId>-<codename>.js`, 129), per 补位 stand-in (`standin-<codename>.js`, 9) and per 自选 operator (`op-<codename>.js`, 71); `shared/` the helpers several kits use; `index.js` the registry; `README.md` the guide |
|
||||
| `server/sim/content/kits/` | the operator kits: `ops/` holds one file per chess (`<chessId>-<codename>.js`, 129), per 补位 stand-in (`standin-<codename>.js`, 9) and per 自选 operator (`op-<codename>.js`, 72); `shared/` the helpers several kits use; `index.js` the registry; `README.md` the guide |
|
||||
| `server/sim/content/enemies/` | the enemy kits by special type (`invisible.js`, `times.js`, `element.js`, `dot.js`, `reflection.js`, `fly.js`, `special.js`) and `leaders.js`; `server/sim/content/enemies.js` dispatches them, `server/sim/content/bosses.js` scripts the leaders |
|
||||
| `server/sim/content/garrisons/`, `items/`, `bands/` | 特质, equipment and strategies: `battle.js` is the battle side, `meta.js` the prep side (`registerMeta`, META §2) |
|
||||
| `server/sim/content/bonds/` | the 23 bonds: `core.js` the 8 core bonds (both sides), `server/sim/content/bonds/addon/` the 15 add-on bonds (`battle.js`, `meta.js`) |
|
||||
|
||||
+4
-4
@@ -600,9 +600,9 @@ Glyph legend (`rows`):
|
||||
|
||||
## 16. Counts (current build)
|
||||
|
||||
`chess 266 (112 visible; 283 selectable skills over the visible chess, 184 module choices over 129 goldens; 74 PRESET / 55 NORMAL / 4 DIY base chess)`, `bonds 23`, `garrisons 249 (43 effect keys)`, `items 115`, `bands 40`, `effects 361`,
|
||||
`chess 266 (112 visible; 283 selectable skills over the visible chess, 185 module choices over 129 goldens; 74 PRESET / 55 NORMAL / 4 DIY base chess)`, `bonds 23`, `garrisons 249 (43 effect keys)`, `items 115`, `bands 40`, `effects 361`,
|
||||
`enemies 249`, `factions 67 entries`, `waves 38`, `stages 11 (8 active)`, `bosses 10`, `tokens 22`, `choice events 109`,
|
||||
`bounty cards 129`, `tactic cards 43`, `backups: 88 units (17 stand-ins, 71 owned-6★ picks; 256 forms), 38 自选 summons, 4 DIY slots, 15 / 9 prototype picks (tier 5 / 6), 71 owned-6★ picks (7 collab operators excluded)`, potential (§2.3): `256 chess records, 219 forms / variants with potDown; 442 + 401 + 19 chained talent entries (chess, backups, tokens)`.
|
||||
`bounty cards 129`, `tactic cards 43`, `backups: 89 units (17 stand-ins, 72 owned-6★ picks; 259 forms), 38 自选 summons, 4 DIY slots, 15 / 9 prototype picks (tier 5 / 6), 72 owned-6★ picks (7 collab operators excluded)`, potential (§2.3): `256 chess records, 219 forms / variants with potDown; 442 + 401 + 19 chained talent entries (chess, backups, tokens)`.
|
||||
|
||||
## 17. Integrity guarantees (checked by the builder and `test/data.test.js`)
|
||||
|
||||
@@ -654,7 +654,7 @@ server/match/player/diy.js, docs/META.md §3). The rules in the data (activity_t
|
||||
even their elite form has none) and the row's potential (`potRank` 0 on all 55) — moot: the 17 原型干员 have no
|
||||
potential ranks, and a stand-in takes neither the player's potential nor the 自持有 练度 (0.2.2).
|
||||
|
||||
`units[charId]` — first the 17 stand-ins, then the 71 owned-6★ 自选 picks (`diy.ownedPool`); no unit for a PRESET or DIY
|
||||
`units[charId]` — first the 17 stand-ins, then the 72 owned-6★ 自选 picks (`diy.ownedPool`); no unit for a PRESET or DIY
|
||||
chess:
|
||||
|
||||
| Field | Example (`char_611_acnipe`) | Meaning |
|
||||
@@ -719,7 +719,7 @@ operator (自选)").
|
||||
| `slots[slotId]` | `{"tier":5,"goldenId":"chess_char_5_diy1_b","shopLevel":5,"requirement":"TIER_6"}` | the four DIY chess `chess_char_5_diy1/2_a`, `chess_char_6_diy1/2_a` (chess.json: price 4, sell 1, `diyRequirement`, empty `bonds` / `garrisonIds`); `shopLevel` = the 调度中心 level whose `shopLevelDisplayDataDict.charChessDiySlotIdList` lists the slot |
|
||||
| `prototypes[tier]` | `{"5":[…15],"6":[…9]}` | the legal prototype picks: the nine 6★ at both tiers, at tier 5 also the six 4★ that are not 先锋 / 特种 ("第5阶可额外从6名四星原型干员(先锋、特种职业除外)中选取"; `DIY_EXTRA_PROTOTYPES`). A prototype may fill a tier-5 and a tier-6 slot ("原型干员可于5、6阶之间重复选取") |
|
||||
| `locked[tier][charId]` | `{"skillIndex":2,"uniEquipId":"uniequip_002_acguad","from":["chess_char_5_06_a","chess_char_5_13_a"]}` | the skill and module a prototype carries in a slot of that tier — "技能携带规则与系统补位时一致" (PRTS 卫戍协议), read as [ASSUMED] (the owner's decision of 2026-10-05) the selection of its 补位 rows at that tier (`from`): the eight 6★ elites S3 with their own module, 领主·Sharp S1, the reserves S3 without a module; 预备干员-医疗 has no tier-5 row: S3 by analogy (`from` `[]`, `DIY_PROTOTYPE_FALLBACK_SKILL`) |
|
||||
| `ownedPool[]` | 71 charIds | the owned 6★ a player may slot: obtainable, rarity = the requirement, and no chess names it — hidden chess included ("不可甄选加入已在名单中的固定干员"); each at most once per roster ("玩家已拥有干员不可重复选取"). Not the collab operators (`excluded`) |
|
||||
| `ownedPool[]` | 72 charIds | the owned 6★ a player may slot: obtainable, rarity = the requirement, and no chess names it — hidden chess included ("不可甄选加入已在名单中的固定干员"); each at most once per roster ("玩家已拥有干员不可重复选取"). Not the collab operators (`excluded`) |
|
||||
| `excluded[]` | `["char_456_ash","char_1029_yato2","char_1048_orchd2","char_4123_ela","char_4141_marcil","char_4182_oblvns","char_4217_makoto"]` | the 7 obtainable 6★ outside the pool that come from a 联动寻访 — a collab team in `mainPower` / `subPower` (`DIY_EXCLUDED_TEAMS`: rainbow, action4, mujica, sees, laios — 灰烬, 麒麟R夜刀, 艾拉, 玛露西尔, 丰川祥子, 结城理) or a collab series in `displayNumber` (`DIY_EXCLUDED_NUMBER_PREFIXES` MH / RS / AM / PS / DD — also 焰狐龙梓兰 MH05, whose team reserve6 names no collab): left out of the data and the pool by the owner's decision of 2026-10-05 (copyright); the excel does not exclude them |
|
||||
| `operators[charId]` | `{"name":"煌","rarity":6,"profession":"WARRIOR","subProfessionId":"centurion","obtainable":true,"powers":["rhodes","elite","yan","victoria"],"bonds":["yanShip","victoriaShip"]}` | every pick (owned pool + prototypes): `powers` = the `nationId` / `groupId` / `teamId` of `mainPower` and of every `subPower` (隐藏势力); `bonds` = the core bonds whose `powerIdList` meets them — one or several — else `economy.fallbackBondId` 协防干员 ("甄选加入的干员会根据其实际阵营所属分配核心盟约,若没有可匹配的则改为分配协防干员盟约"); every prototype gets `["emptyShip"]` |
|
||||
|
||||
|
||||
+2
-1
@@ -4,7 +4,7 @@ This is the **single source of truth** for every implementer. Research lives in
|
||||
|
||||
Language: player-facing text is **Simplified Chinese** by default, with an English switch since 0.2.0 (§25.2, docs/I18N.md: UI strings through `t('中文')`, game texts from the official Chinese data or the official EN client's). Code, comments and identifiers are English.
|
||||
|
||||
Versions: the first public release was **0.1.0** (2026-10-02, the state of §0–§20.15); the releases after it add the player feedback and GitHub reports — 0.1.1 §21, 0.1.2 §22, 0.1.3 §23, 0.1.4 §24 — and **0.2.0** (2026-10-07; `CHANGELOG.md`) the maintainability refactor, two languages, 补位, 自选编队 and their fidelity work — §25 — **0.2.1** (2026-10-07) the 联防 battlefield restored, full potential and the GitHub fixes after it — §26 — and **0.2.2** (2026-10-09; `package.json`, `shared/constants.js APP_VERSION`) per-operator 潜能 / 练度, Japanese voices, the statistics page, 失衡, whole-frame attack timing and the GitHub fixes after 0.2.1 — §27, the state described by this document. The labels v1 / v2 / v2.1–v2.5.2 in §0, §14–§20 and in the BALANCE / SIM comparisons name the design generations and the private playtest builds that came before it; they are kept as history.
|
||||
Versions: the first public release was **0.1.0** (2026-10-02, the state of §0–§20.15); the releases after it add the player feedback and GitHub reports — 0.1.1 §21, 0.1.2 §22, 0.1.3 §23, 0.1.4 §24 — and **0.2.0** (2026-10-07; `CHANGELOG.md`) the maintainability refactor, two languages, 补位, 自选编队 and their fidelity work — §25 — **0.2.1** (2026-10-07) the 联防 battlefield restored, full potential and the GitHub fixes after it — §26 — and **0.2.2** (2026-10-09; `package.json`, `shared/constants.js APP_VERSION`) per-operator 潜能 / 练度, Japanese voices, the statistics page, 失衡, whole-frame attack timing and the GitHub fixes after 0.2.1 — §27. The current development state is **0.2.3** — §28 (not yet released). The labels v1 / v2 / v2.1–v2.5.2 in §0, §14–§20 and in the BALANCE / SIM comparisons name the design generations and the private playtest builds that came before it; they are kept as history.
|
||||
|
||||
---
|
||||
|
||||
@@ -34,3 +34,4 @@ normative lines it rewrote).
|
||||
| §25 | [history/0.2.0.md](history/0.2.0.md) | 0.2.0 |
|
||||
| §26 | [history/0.2.1.md](history/0.2.1.md) | 0.2.1 — after the 0.2.0 release |
|
||||
| §27 | [history/0.2.2.md](history/0.2.2.md) | 0.2.2 — after the 0.2.1 release (2026-10-09) |
|
||||
| §28 | [history/0.2.3.md](history/0.2.3.md) | 0.2.3 — development after 0.2.2 |
|
||||
@@ -171,7 +171,7 @@ Profession traits (default behaviours implemented once in the engine, keyed by `
|
||||
|
||||
Each domain file `server/sim/content/{tokens,bonds,garrisons,items,bands,enemies,bosses,devices,choices}.js` exports `install(battle)` (battle side; called once per Battle by `content/index.js → installContent`) and `registerMeta(registry)` (prep side; called once at server boot by `match/effectsMeta.js`, API documented in `docs/META.md`). Kits live one per file in `content/kits/ops/` (`export default { [baseChessId]: (bb, chess, def) => Kit }`), listed in `content/kits/index.js` (guide: `content/kits/README.md`). Content must be **data-driven from blackboards** (numbers never hard-coded when a blackboard key exists). Every effect gets at least one unit test in `test/content/*.test.js` using the `test/helpers/battleHarness.js` harness (provided by sim-core).
|
||||
|
||||
- kits: all 112 visible chess + hidden ones used by effects (盟约·辅助干员), default skill + talents + trait specifics; tokens.
|
||||
- kits: all 112 visible chess + hidden ones used by effects (盟约·辅助干员), default skill + talents + trait specifics; tokens. The 72 non-collaboration 6★ DIY operators include 克莱门莎 (§28.1); her launch-day provisional mechanics are local to her kit. 黍 GUA-Y and 乌尔比安 CRU-Y follow the generated module blackboards and existing module-level rules (§28.2).
|
||||
- bonds: 23 (battle + meta), exact per-layer formulas from research 02.
|
||||
- garrisons: 43 effect keys (IN_BATTLE via hooks; SERVER_* via meta registry).
|
||||
- items: 56 equipment (+golden) + 3 Arts; 变形同构体 bond grant; VI-tier set/combos.
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# DESIGN §28 — 0.2.3
|
||||
|
||||
Part of [DESIGN.md](../DESIGN.md) (the index; section numbers are global).
|
||||
|
||||
## 28. New content and community fixes
|
||||
|
||||
This chapter describes the development version, not a published release. Numerical content is rebuilt from
|
||||
CN client 2.7.81, ArknightsGameData commit `17759cc8cdf37388414145d16262a3a06f3ab25e` (2026-10-08),
|
||||
with mechanism notes from PRTS checked on 2026-10-09. Launch-day descriptions may receive corrections.
|
||||
|
||||
### 28.1 克莱门莎 — `sim/content/kits/ops/op-clemnt.js`
|
||||
|
||||
- **Source:** [PRTS 克莱门莎](https://prts.wiki/w/克莱门莎) and the official character, skill and range tables.
|
||||
The non-collaboration 6★ roster gains Clementia (`char_4231_clemnt`), a 本源近卫: 72 DIY operators,
|
||||
89 backup units including stand-ins, 259 selectable forms. All three skills are selectable in the existing
|
||||
tier-5 / tier-6 DIY slots at their existing skill-rank rules; potential and cultivation follow the player's settings.
|
||||
She has no launch module. Her bonds follow the existing faction mapping, including 阿戈尔.
|
||||
- **Talents:** each physical hit independently rolls 生死定夺's pre-DEF ATK multiplier; an enemy with current
|
||||
DEF below its initial DEF uses the higher probability. 习得性防御 reduces physical / Arts damage from the
|
||||
forward half-plane (including its boundary) or an enemy she blocks; 海怪 uses its separate reduction.
|
||||
Both talents take their potential-sensitive values from the generated data.
|
||||
- **S1:** the charged attack applies its ATK scale and inflicts 侵蚀损伤 proportional to actual HP damage.
|
||||
**S2:** the cabin travels forwards at 2 tiles/s, up to 3 tiles, carrying up to 15 ground enemies with a total
|
||||
weight of 8. Its collision square is 1.1 × 1.1. Impassable terrain stops it; self-bound / teleport-immune
|
||||
units cannot ride. Its actual stopping position becomes a radius-1.5 vortex that can affect air, slows by 70%, and each
|
||||
second deals 200 erosion damage plus the skill's physical damage. Erosion follows the engine's normal
|
||||
resistance, burst cooldown and mode-leader immunity rules.
|
||||
Ordinary skill attacks hit their main ground target and up to four neighbours.
|
||||
- **S3:** attacks select up to three ground enemies and add erosion based on actual HP damage without spending
|
||||
ammunition. A selectable ground enemy's erosion burst anywhere in the current battle marks it for 1 s.
|
||||
The closest mark consumes one of 10 bombardments: three physical + elemental hits in the target tile's
|
||||
five-tile cross. A tile with an outstanding projectile cannot be selected again for 5 s. Values are taken
|
||||
from the skill rank, not inferred from the final rank's description.
|
||||
- **[ASSUMED], pending PRTS confirmation:** S2 ordinary splash radius 1.5 and stable spawn-order tie breaks;
|
||||
放逐 presently prevents walking, attacking and blocking while keeping the passenger damageable; cabin
|
||||
movement updates every sim tick, stops 0.4 tiles before an impassable edge, and the vortex ends with S2.
|
||||
S3's first impact is 0.5 s after launch, the others 1 s apart; launched projectiles finish after skill end.
|
||||
These are local kit assumptions, not changes to displacement or targeting rules for other operators.
|
||||
- **Tests:** `test/content/op_clemnt.test.js` covers available forms, potential, crit probabilities, directional
|
||||
defence, S1 cadence, S2 capacity / immunity / terrain / air vortex / target cap, and S3 ammo / global marks /
|
||||
mixed damage. Golden changes and the final integration verification are recorded below once complete.
|
||||
|
||||
### 28.2 New modules — 黍「好时节」and 乌尔比安「前路」
|
||||
|
||||
- **Sources:** [PRTS 黍](https://prts.wiki/w/黍), [PRTS 乌尔比安](https://prts.wiki/w/乌尔比安), official
|
||||
`uniequip_table` and `battle_equip_table` from the same CN revision. Regenerating data adds GUA-Y
|
||||
(`uniequip_003_shu`) and CRU-Y (`uniequip_003_ulpia`) to their existing forms, including the anchor's
|
||||
module lookup. The day's new 5★ operators stay outside the established non-collaboration 6★ DIY pool.
|
||||
- **黍:** GUA-Y's trait gives 15% damage reduction. The upgraded 天有四时 takes the improved HP / ASPD /
|
||||
four-Sui squad bonuses from the module blackboard. Satisfying at least two of the three conditions grants
|
||||
the separate additional ATK bonus (3% / 5% at module levels 2 / 3); it expires when the conditions stop holding.
|
||||
- **乌尔比安:** CRU-Y increases damage to an enemy blocked by any ally by 10%. Its upgraded talent also counts another
|
||||
深海猎人's credited kills (including delayed hits after that hunter leaves) while 乌尔比安 is deployed, shares the module's specified HP / ATK proportion,
|
||||
and adds one block at 9 stacks. Potential's extra maximum stack is retained. The mode's tier-5 elite form
|
||||
still uses module level 1; support for upgraded talent blackboards does not change that established rule.
|
||||
- **Tests:** `test/content/new-modules-023.test.js`, plus existing 黍 and tier-5 kit cases. The level-3 talent
|
||||
fixture is sourced from the official module blackboard; it is not exposed as a new tier-5 loadout.
|
||||
|
||||
### Content verification checkpoint
|
||||
|
||||
The new content's targeted tests passed 16/16; existing Shu / tier-5 coverage passed 120/120. An independent
|
||||
interaction pass checked retreat cleanup, sleeping passengers, a real rebirth enemy, hit-count life,
|
||||
post-retreat bombardments and delayed hunter kill credit. It found and corrected vortex-position rounding,
|
||||
an unsupported elemental-resistance bypass and an unnecessary on-field check on the credited hunter.
|
||||
All 285 golden scenarios were regenerated: only `roster` and `diy` changed, (`roster-019`, `roster-038`, `diy-059`–`diy-140`), because the added module expands
|
||||
loadout coverage and the added DIY operator / Shu module expand and regroup the DIY scenarios. `bonds`,
|
||||
`fields`, `matches` and `standins` remained byte-identical. Full integration and browser checks follow separately.
|
||||
@@ -150,6 +150,7 @@ export const OPERATOR_KIT_FILES = Object.freeze([
|
||||
'op-necras.js',
|
||||
'op-kalts2.js',
|
||||
'op-monstr.js',
|
||||
'op-clemnt.js',
|
||||
]);
|
||||
|
||||
/**
|
||||
|
||||
@@ -143,8 +143,14 @@ export default {
|
||||
} },
|
||||
{ install(battle, unit) { // 血脉的哺养
|
||||
battle.on('kill', (c) => {
|
||||
if (c.killer !== unit || c.victim.side !== 'enemy' || !on(unit)) return;
|
||||
// CRU-Y stages 2/3: kills credited to any 深海猎人 count while Ulpianus is on the field.
|
||||
const hunterKill = num(t1.add_block_cnt_stack_cnt) > 0 && isOp(c.killer) && isAbyssal(c.killer);
|
||||
if ((c.killer !== unit && !hunterKill) || c.victim.side !== 'enemy' || !on(unit)) return;
|
||||
battle.addBuff(unit, { key: 'ulpia:blood', refresh: 'stack', maxStacks: Math.max(1, num(t1.max_stack_cnt, 9)), mods: mods({ hpFlat: num(t1.max_hp), atkFlat: num(t1.atk) }) });
|
||||
const threshold = num(t1.add_block_cnt_stack_cnt);
|
||||
if (threshold > 0 && unit.findBuff('ulpia:blood')?.stacks >= threshold) {
|
||||
battle.addBuff(unit, { key: 'ulpia:bloodBlock', mods: { blockCnt: num(t1.block_cnt) }, tags: ['talent'] });
|
||||
}
|
||||
const share = mods({ hpFlat: num(t1['ulpia_t_1[abyssal].max_hp']), atkFlat: num(t1['ulpia_t_1[abyssal].atk']) });
|
||||
if (!Object.keys(share).length) return;
|
||||
for (const a of battle.allies()) {
|
||||
@@ -154,6 +160,11 @@ export default {
|
||||
} },
|
||||
],
|
||||
install(battle, unit) {
|
||||
// CRU-Y: all his damage against a blocked enemy is scaled, including anchor hits.
|
||||
const blockedScale = num(tb.damage_scale, 1);
|
||||
if (blockedScale !== 1) battle.on('hit', (c) => {
|
||||
if (c.source === unit && c.target?.side === 'enemy' && c.target.blockedBy) c.dmg.mul *= blockedScale;
|
||||
}, { owner: unit });
|
||||
if (num(tb.heal_scale) > 0) permBuff(battle, unit, 'ulpia:module', { healingTakenMul: num(tb.heal_scale) });
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
// 克莱门莎 (char_4231_clemnt), 本源近卫. Official CN tables 2026-10-08 (client 2.7.81),
|
||||
// PRTS 克莱门莎, 2026-10-09: all skills at ranks 4/7 and both potential-sensitive talents.
|
||||
// https://prts.wiki/w/克莱门莎 . No module was released with her.
|
||||
// PRTS still marks several launch-day details unknown: [ASSUMED] S2's ordinary splash radius 1.5;
|
||||
// carriage's unresolved 放逐 combination = cannot walk/attack/be blocked, but remains damageable;
|
||||
// its boundary clearance 0.4, carriage updates once per sim tick, vortex ends with the skill;
|
||||
// S3 first bombardment at 0.5 s, then twice at 1 s intervals, launched shots survive skill end.
|
||||
// These pending confirmations are listed in DESIGN §28.1; keep each assumption local to this kit.
|
||||
|
||||
import { num, talentBb, skillRec, up } from '../shared/tier1.js';
|
||||
import { canTargetEnemy } from '../../../targeting.js';
|
||||
import { bodyInKeys, hitRect } from '../../../body.js';
|
||||
import { dirVec } from '../../../dir.js';
|
||||
import { COLS } from '../../../constants.js';
|
||||
import { hasHp } from '../../../damage.js';
|
||||
|
||||
const S1 = 'skchr_clemnt_1', S2 = 'skchr_clemnt_2', S3 = 'skchr_clemnt_3';
|
||||
const GROUND = Object.freeze({ canHitFly: false, groundOnly: true });
|
||||
const AIR = Object.freeze({ canHitFly: true });
|
||||
const SPEED = 2, DISTANCE = 3, CATCH_HALF = 0.55, VORTEX_RADIUS = 1.5;
|
||||
const SPLASH_RADIUS = 1.5; // [ASSUMED] PRTS has not published S2's normal attack splash radius.
|
||||
const FIRST_BOMB = 0.5; // [ASSUMED] PRTS lists the landing delay as unknown.
|
||||
const CAST = 'clemnt:cast', CARRY = 'clemnt:carry:';
|
||||
const skillBb = (raw, id) => skillRec(raw, id)?.bb ?? {};
|
||||
const tile = (u) => [Math.round(u.y), Math.round(u.x)];
|
||||
const immunity = (e) => e.def?.raw?.stats?.otherImmunities ?? [];
|
||||
// No current mode enemy has the three named teleport immunities. Also honour explicit normalized flags for custom data.
|
||||
const cannotCarry = (e) => e.s.flags.selfBound || e.def?.immune?.has('exile') || e.def?.immune?.has('teleport')
|
||||
|| immunity(e).some((s) => /teleport|transmit|exile/i.test(String(s)));
|
||||
|
||||
/** Cabin's 1.1 × 1.1 collision square; huge bodies use the engine hit rectangle. */
|
||||
function touches(e, x, y) {
|
||||
const r = hitRect(e);
|
||||
return r ? r.x1 >= x - CATCH_HALF && r.x0 <= x + CATCH_HALF && r.y1 >= y - CATCH_HALF && r.y0 <= y + CATCH_HALF
|
||||
: Math.abs(e.x - x) <= CATCH_HALF + 1e-9 && Math.abs(e.y - y) <= CATCH_HALF + 1e-9;
|
||||
}
|
||||
|
||||
export default {
|
||||
char_4231_clemnt: (bb, raw) => {
|
||||
const t0 = talentBb(raw, 0), t1 = talentBb(raw, 1);
|
||||
const b1 = skillBb(raw, S1), b2 = skillBb(raw, S2), b3 = skillBb(raw, S3);
|
||||
const rider = ({ battle, unit, target, dealt }, ratio) => {
|
||||
if (dealt > 0 && hasHp(target)) battle.dealDamage(unit, target, {
|
||||
amount: dealt * ratio, type: 'element', element: 'erosion', isSkill: true, tags: ['skill', 'clemnt:rider'],
|
||||
});
|
||||
};
|
||||
const freePassengers = (battle, unit) => {
|
||||
const c = unit.mem.clemntCabin;
|
||||
if (c) for (const e of c.passengers) battle.removeBuff(e, CARRY + unit.id);
|
||||
battle.removeBuff(unit, CAST);
|
||||
};
|
||||
const finishCabin = (battle, unit, c) => {
|
||||
if (c.stopped) return;
|
||||
c.stopped = true;
|
||||
freePassengers(battle, unit);
|
||||
// PRTS: vortex at the cabin's actual stopping position, radius 1.5, can hit air.
|
||||
c.tick = 0;
|
||||
battle.fx('tide', { x: c.x, y: c.y, r: VORTEX_RADIUS, dur: unit.skill.timeLeft, id: unit.id });
|
||||
};
|
||||
const startCabin = (battle, unit) => {
|
||||
const [dr, dc] = dirVec(unit.dir), [r, col] = tile(unit);
|
||||
let distance = DISTANCE;
|
||||
for (let d = 1; d <= DISTANCE + 1; d++) {
|
||||
const rr = r + dr * d, cc = col + dc * d, t = battle.grid.tile(rr, cc);
|
||||
if (!battle.grid.groundPassable(rr, cc) || t.height === 'HIGH' || t.key === 'tile_hole') {
|
||||
// [ASSUMED] PRTS's provisional rule: stop 0.4 tiles before the impassable edge.
|
||||
distance = Math.min(distance, Math.max(0, d - 0.5 - 0.4)); break;
|
||||
}
|
||||
}
|
||||
const c = unit.mem.clemntCabin = { x: col, y: r, ox: col, oy: r, dr, dc, distance, moved: 0,
|
||||
mass: num(b2['attack@max_passenger_mass'], 8), passengers: [], stopped: false, tick: 0 };
|
||||
battle.addBuff(unit, { key: CAST, duration: 10, flags: { disarm: true }, tags: ['skill'] });
|
||||
battle.fx('anchor', { x: col + dc * distance, y: r + dr * distance, fromX: col, fromY: r, id: unit.id, dur: distance / SPEED });
|
||||
if (distance <= 1e-9) finishCabin(battle, unit, c);
|
||||
};
|
||||
const tickCabin = (battle, unit, dt) => {
|
||||
const c = unit.mem.clemntCabin;
|
||||
if (!c || !up(unit)) return;
|
||||
if (!c.stopped) {
|
||||
c.moved = Math.min(c.distance, c.moved + SPEED * dt);
|
||||
c.x = c.ox + c.dc * c.moved; c.y = c.oy + c.dr * c.moved;
|
||||
const cap = num(b2['attack@max_passenger_cnt'], 15);
|
||||
for (const e of battle.enemies) {
|
||||
if (c.passengers.length >= cap) break;
|
||||
if (!e.alive || !e.deployed || e.hidden || e.isFlying || cannotCarry(e) || c.passengers.includes(e)
|
||||
|| e.weight > c.mass + 1e-9 || !touches(e, c.x, c.y)) continue;
|
||||
const [er, ec] = tile(e);
|
||||
if (!battle.grid.findPath(er, ec, Math.round(c.y), Math.round(c.x))) continue;
|
||||
c.mass -= e.weight;
|
||||
c.passengers.push(e);
|
||||
battle._unblock(e);
|
||||
// [ASSUMED] PRTS has not yet resolved every status in 放逐; no invulnerability or hide is invented.
|
||||
battle.addBuff(e, { key: CARRY + unit.id, flags: { noMove: true, disarm: true, unblockable: true }, source: unit, tags: ['skill'] });
|
||||
}
|
||||
for (const e of c.passengers) {
|
||||
if (!e.alive || e.hidden || cannotCarry(e)) { battle.removeBuff(e, CARRY + unit.id); continue; }
|
||||
if (!e.findBuff(CARRY + unit.id)) continue;
|
||||
const [er, ec] = tile(e);
|
||||
if (!battle.grid.findPath(er, ec, Math.round(c.y), Math.round(c.x))) { battle.removeBuff(e, CARRY + unit.id); continue; }
|
||||
const fromX = e.x, fromY = e.y;
|
||||
e.x = c.x; e.y = c.y;
|
||||
if (e.route) e.route.pts = null;
|
||||
battle.fx('teleport', { x: e.x, y: e.y, fromX, fromY, id: e.id, src: unit.id });
|
||||
}
|
||||
if (c.moved >= c.distance - 1e-9) finishCabin(battle, unit, c);
|
||||
return;
|
||||
}
|
||||
const foes = battle.enemiesInRadius(c.x, c.y, VORTEX_RADIUS).filter((e) => canTargetEnemy(unit, e, AIR));
|
||||
for (const e of foes) battle.addBuff(e, { key: `clemnt:vortex:${unit.id}`, duration: 0.1,
|
||||
mods: { moveMul: 1 + num(b2['attack@move_speed'], -0.7) }, source: unit, tags: ['skill'] });
|
||||
c.tick += dt;
|
||||
if (c.tick < 1 - 1e-9) return;
|
||||
c.tick -= 1;
|
||||
for (const e of foes) {
|
||||
battle.dealDamage(unit, e, { amount: num(b2['attack@water_element'], 200), type: 'element',
|
||||
element: 'erosion', isSkill: true, canDodge: false, tags: ['skill', 'dot', 'clemnt:vortex:erosion'] });
|
||||
if (hasHp(e)) battle.dealDamage(unit, e, { amount: unit.s.atk * num(b2['attack@physical_atk_scale']),
|
||||
type: 'phys', canDodge: false, isSkill: true, tags: ['skill', 'dot', 'clemnt:vortex'] });
|
||||
}
|
||||
};
|
||||
const bombard = (battle, unit, e, m, skill) => {
|
||||
const [r, c] = tile(e), key = r * COLS + c;
|
||||
if ((m.tiles.get(key) ?? -1) > battle.time) return false;
|
||||
m.tiles.set(key, battle.time + num(b3.projectile_life_time, 5));
|
||||
const keys = new Set([[r, c], [r + 1, c], [r - 1, c], [r, c + 1], [r, c - 1]].map(([rr, cc]) => rr * COLS + cc));
|
||||
const atk = unit.s.atk;
|
||||
battle.fx('lock', { x: c, y: r, id: e.id, src: unit.id, dur: FIRST_BOMB });
|
||||
for (let n = 0; n < 3; n++) battle.after(FIRST_BOMB + n, () => {
|
||||
battle.fx('blast', { x: c, y: r, r: 1.5, id: unit.id });
|
||||
for (const t of battle.enemies) {
|
||||
if (!canTargetEnemy(unit, t, GROUND) || !bodyInKeys(t, keys)) continue;
|
||||
battle.dealDamage(unit, t, { amount: atk * num(b3.s3_atk_scale), type: 'phys', canDodge: false,
|
||||
isSkill: true, tags: ['skill', 'clemnt:bomb'] });
|
||||
if (hasHp(t)) battle.dealDamage(unit, t, { amount: atk * num(b3.ep_damage_scale), type: 'elemental', element: 'erosion',
|
||||
canDodge: false, isSkill: true, tags: ['skill', 'clemnt:bomb'] });
|
||||
}
|
||||
}, { owner: unit, holdsBattle: true });
|
||||
skill.ammoLeft--;
|
||||
battle.emit('ammoUsed', { unit, left: skill.ammoLeft, skill });
|
||||
return true;
|
||||
};
|
||||
return {
|
||||
skills: {
|
||||
[S1]: { kind: 'instant', attack: { atkScale: num(b1.atk_scale, 1),
|
||||
onHit(c) { rider(c, num(b1.ep_damage_ratio)); } } },
|
||||
[S2]: {
|
||||
kind: 'duration', mods: { aspd: num(b2.attack_speed) },
|
||||
targeting: { rangeGrid: skillRec(raw, S2)?.rangeGrid },
|
||||
attack: { atkScale: num(b2['attack@aoe_atk_scale'], 1), groundOnly: true,
|
||||
onEachHit({ battle, unit, target, kind, attackId }) {
|
||||
if (kind !== 'main' || !target) return;
|
||||
// Main victim plus at most four neighbours, never every unit in the radius.
|
||||
// [ASSUMED] Ties among splash victims follow the engine's stable spawn order.
|
||||
const near = battle.foesInRadius(target.x, target.y, SPLASH_RADIUS, true)
|
||||
.filter((e) => e !== target && canTargetEnemy(unit, e, GROUND))
|
||||
.slice(0, Math.max(0, num(b2['attack@max_target'], 5) - 1));
|
||||
for (const e of near) battle.dealDamage(unit, e, {
|
||||
amount: unit.s.atk * unit.s.atkScaleMul * num(b2['attack@aoe_atk_scale'], 1), type: 'phys',
|
||||
isAttack: true, isSplash: true, isSkill: true, attackId, tags: ['skill', 'clemnt:splash'],
|
||||
});
|
||||
} },
|
||||
onStart({ battle, unit }) { startCabin(battle, unit); },
|
||||
onTick({ battle, unit, dt }) { tickCabin(battle, unit, dt); },
|
||||
onEnd({ battle, unit }) { freePassengers(battle, unit); unit.mem.clemntCabin = null; },
|
||||
},
|
||||
[S3]: {
|
||||
kind: 'ammo', ammo: num(b3.trigger_time, 10),
|
||||
targeting: { rangeGrid: skillRec(raw, S3)?.rangeGrid, maxTargets: num(b3['attack@max_target'], 3) },
|
||||
attack: { atkScale: num(b3['attack@atk_scale'], 1), onHit(c) { rider(c, num(b3['attack@ep_damage_ratio'])); } },
|
||||
onAttack(c) { c.noAmmo = true; },
|
||||
onStart({ unit }) { unit.mem.clemntBombs = { marks: new Map(), tiles: new Map() }; },
|
||||
onTick({ battle, unit, skill }) {
|
||||
const m = unit.mem.clemntBombs;
|
||||
if (!m || !unit.canAct) return;
|
||||
const choices = [];
|
||||
for (const [e, until] of m.marks) {
|
||||
if (until < battle.time - 1e-9 || !e.alive || e.hidden) { m.marks.delete(e); continue; }
|
||||
if (canTargetEnemy(unit, e, GROUND)) choices.push(e);
|
||||
}
|
||||
const dist2 = (e) => { const dx = e.x - unit.x, dy = e.y - unit.y; return dx * dx + dy * dy; };
|
||||
choices.sort((a, b) => dist2(a) - dist2(b) || a.spawnSeq - b.spawnSeq);
|
||||
for (const e of choices) if (bombard(battle, unit, e, m, skill)) { m.marks.delete(e); break; }
|
||||
if (skill.ammoLeft <= 0) skill.end('ammo');
|
||||
},
|
||||
onEnd({ unit }) { unit.mem.clemntBombs = null; },
|
||||
},
|
||||
},
|
||||
talents: [
|
||||
{ install(battle, unit) { // 生死定夺: ATK scale BEFORE DEF, per physical damage instance.
|
||||
battle.on('hit', ({ source, target, dmg }) => {
|
||||
if (source !== unit || dmg.type !== 'phys' || !target || target.side !== 'enemy') return;
|
||||
const chance = target.s.def < target.base.def ? num(t0.prob_special) : num(t0.prob_normal);
|
||||
if (battle.rng() < chance) dmg.amount *= num(t0.t1_atk_scale, 1);
|
||||
}, { owner: unit });
|
||||
} },
|
||||
{ install(battle, unit) { // 习得性防御: source tile in forward half-plane, plus every enemy she blocks.
|
||||
battle.on('hit', ({ source, target, dmg }) => {
|
||||
if (target !== unit || !source || (dmg.type !== 'phys' && dmg.type !== 'arts')) return;
|
||||
const [dr, dc] = dirVec(unit.dir), [r, c] = tile(source);
|
||||
if (source.blockedBy !== unit && (r - unit.tileR) * dr + (c - unit.tileC) * dc < 0) return;
|
||||
const sea = source.def?.tags?.includes('seamonster');
|
||||
dmg.mul *= 1 - num(sea ? t1.damage_resistance_seamonster : t1.damage_resistance_normal);
|
||||
}, { owner: unit });
|
||||
} },
|
||||
],
|
||||
install(battle, unit) {
|
||||
battle.on('elementBurst', ({ target, element }) => {
|
||||
if (element !== 'erosion' || !up(unit) || !unit.skill?.active || unit.skill.id !== S3
|
||||
|| !canTargetEnemy(unit, target, GROUND)) return;
|
||||
unit.mem.clemntBombs?.marks.set(target, battle.time + num(b3.ep_break_duration, 1));
|
||||
}, { owner: unit });
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@@ -99,6 +99,10 @@ export default {
|
||||
const born = RANGE_IDS[r0?.bbStr?.born_range_id] ?? null;
|
||||
const b1 = bbOf(chess, S1), b2 = bbOf(chess, S2), b3 = bbOf(chess, S3);
|
||||
const s1 = skillRec(chess, S1);
|
||||
// GUA-Y stages 2/3: the extra ATK sits on the module's hidden talent (index -1), not 天有四时.
|
||||
const seasonAtk = num(talentRec(chess, -1)?.bb?.atk);
|
||||
const squadOf = (battle, unit) => battle.allyUnits.filter((a) => a.kind === 'op' && a.ownerId === unit.ownerId);
|
||||
const suiReady = (battle, unit) => squadOf(battle, unit).filter((a) => SUI.has(a.def?.charId)).length >= SUI_NEEDED;
|
||||
const g1 = gridOf(chess, S1, X4), g2 = gridOf(chess, S2, X1), g3 = gridOf(chess, S3, X2);
|
||||
|
||||
/** The sown tiles of her current deployment (a Set of tile keys). */
|
||||
@@ -244,13 +248,15 @@ export default {
|
||||
const per = new Map();
|
||||
for (const a of ops) { const p = a.def?.profession ?? '?'; per.set(p, (per.get(p) ?? 0) + 1); }
|
||||
const many = per.size >= PROF_NEEDED, same = Math.max(0, ...per.values()) >= PROF_NEEDED;
|
||||
const bonus = seasonAtk > 0 && Number(many) + Number(same) + Number(suiReady(battle, unit)) >= 2;
|
||||
for (const a of ops) {
|
||||
if (many && hpUp) battle.addBuff(a, { key: 'talent:shu:seasons:hp', duration: FARM_HOLD, mods: { hpPct: hpUp }, source: unit, tags: ['talent'] });
|
||||
if (same && asUp) battle.addBuff(a, { key: 'talent:shu:seasons:aspd', duration: FARM_HOLD, mods: { aspd: asUp }, source: unit, tags: ['talent'] });
|
||||
if (bonus) battle.addBuff(a, { key: 'talent:shu:seasons:atk', duration: FARM_HOLD, mods: { atkPct: seasonAtk }, source: unit, tags: ['talent'] });
|
||||
}
|
||||
}, { owner: unit, immediate: true });
|
||||
// 编入队伍且编队中有四名【岁】干员: her squad's operators ATK + for the battle, +sp SP every `interval` s deployed
|
||||
const squadOf = () => battle.allyUnits.filter((a) => a.kind === 'op' && a.ownerId === unit.ownerId);
|
||||
const ownSquad = () => squadOf(battle, unit);
|
||||
const atk = num(t1.atk), sp = num(t1.sp), iv = num(t1.interval);
|
||||
const spBuff = (a) => {
|
||||
if (sp > 0 && iv > 0) battle.addBuff(a, { key: 'talent:shu:suiSp', interval: iv, onTick: ({ unit: x }) => giveSp(x, sp), source: unit, tags: ['talent'] });
|
||||
@@ -258,7 +264,7 @@ export default {
|
||||
const apply = () => {
|
||||
if (unit.mem.shuSuiDone) return;
|
||||
unit.mem.shuSuiDone = true;
|
||||
const squad = squadOf();
|
||||
const squad = ownSquad();
|
||||
if (squad.filter((a) => SUI.has(a.def?.charId)).length < SUI_NEEDED) return;
|
||||
const members = new Set(squad);
|
||||
for (const a of squad) {
|
||||
@@ -272,6 +278,11 @@ export default {
|
||||
} },
|
||||
],
|
||||
install(battle, unit) {
|
||||
// GUA-Y: damage reduction, independent of the sown tile's 庇护 (official trait damage_resistance).
|
||||
const dr = num(tb.damage_resistance);
|
||||
if (dr > 0) battle.on('deploy', ({ unit: u }) => {
|
||||
if (u === unit) battle.addBuff(unit, { key: 'shu:gua-y', mods: { dmgTakenMul: 1 - dr }, source: unit, tags: ['module'] });
|
||||
}, { owner: unit });
|
||||
// GUA-X: 治疗生命值低于50%的友方单位时治疗量提升15% (heal_scale_up[hpratio][LE]: at or below hp_ratio)
|
||||
const hs = num(tb.heal_scale, 1), hr = num(tb.hp_ratio);
|
||||
if (hs !== 1 && hr > 0) {
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { KITS } from '../../server/sim/content/kits/index.js';
|
||||
import { makeBattle, chessRec, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
|
||||
const GUAY = 'uniequip_003_shu', CRUY = 'uniequip_003_ulpia';
|
||||
const approx = (a, b) => assert.ok(Math.abs(a - b) < 1e-6, `${a} != ${b}`);
|
||||
const target = enemyRec({ key: 'dummy', hp: 1e8, speed: 0, def: 0, atk: 0 });
|
||||
const war = chessRec({ id: 'war', profession: 'WARRIOR', skill: null, stats: { atk: 100, blockCnt: 0 } });
|
||||
const med = chessRec({ id: 'med', profession: 'MEDIC', skill: null, stats: { atk: 100, blockCnt: 0 } });
|
||||
const helpers = [2, 3, 4].map((uid) => ({ uid, chessId: 'war', row: 10, col: uid }));
|
||||
function shu(tier, others = []) {
|
||||
const h = makeBattle({ defs: { enemies: { dummy: target }, chess: { war, med } }, autoFinish: false,
|
||||
units: [{ uid: 1, diy: { slot: tier, charId: 'char_2025_shu', skillIndex: 2, uniEquipId: GUAY }, elite: true, row: 11, col: 5 }, ...others] });
|
||||
h.step(); return { h, u: h.unit(1) };
|
||||
}
|
||||
|
||||
test('黍 GUA-Y stage 1/3 reduces incoming damage by 15%, independently of HP, after deployment', () => {
|
||||
for (const tier of [5, 6]) {
|
||||
const { h, u } = shu(tier);
|
||||
approx(u.s.dmgTakenMul, 0.85);
|
||||
const e = h.spawn('dummy', { pos: [10, 9] });
|
||||
const hp = u.hp;
|
||||
h.b.dealDamage(e, u, { amount: 100, type: 'true' });
|
||||
approx(hp - u.hp, 85);
|
||||
const hp2 = u.hp;
|
||||
h.b.dealDamage(e, u, { amount: 100, type: 'elemental' });
|
||||
approx(hp2 - u.hp, 100);
|
||||
checkInvariants(h.b); assert.equal(h.b.errors.length, 0);
|
||||
}
|
||||
});
|
||||
|
||||
test('黍 GUA-Y stage 3 requires two conditions, buffs each operator once, and drops the bonus when a condition ends', () => {
|
||||
for (const tier of [5, 6]) {
|
||||
const { h, u } = shu(tier, [...helpers, { uid: 5, chessId: 'med', row: 9, col: 3 }]);
|
||||
h.run(0.3);
|
||||
const a = h.unit(2);
|
||||
approx(a.s.atk / a.base.atk, tier === 6 ? 1.05 : 1);
|
||||
assert.equal(a.s.aspd, tier === 6 ? 116 : 112);
|
||||
h.b.retreat(h.unit(5), { permanent: true });
|
||||
h.run(0.7);
|
||||
approx(a.s.atk / a.base.atk, 1);
|
||||
assert.equal(u.s.aspd, tier === 6 ? 116 : 112);
|
||||
checkInvariants(h.b); assert.equal(h.b.errors.length, 0);
|
||||
}
|
||||
});
|
||||
|
||||
function ulpia({ moduleId = CRUY, potential = 6, stage3 = false } = {}) {
|
||||
// The mode's tier-5 elite only exposes module stage 1. Exercise its stage-3 talent separately using the
|
||||
// official CRU-Y blackboard (battle_equip_table, 2026-10-09); do not change the production slot's module level.
|
||||
const kits = stage3 ? { chess_char_5_05_a: (bb, raw, def) => {
|
||||
const rec = structuredClone(raw);
|
||||
rec.talents.find((t) => t.index === 1).bb = {
|
||||
max_stack_cnt: potential === 6 ? 10 : 9, max_hp: 150, atk: 38,
|
||||
'ulpia_t_1[abyssal].max_hp': 90, 'ulpia_t_1[abyssal].atk': 22.799999,
|
||||
'ulpia_t_1[abyssal].max_stack_cnt': potential === 6 ? 10 : 9,
|
||||
block_cnt: 1, add_block_cnt_stack_cnt: 9,
|
||||
};
|
||||
return KITS.chess_char_5_05_a(bb, rec, def);
|
||||
} } : undefined;
|
||||
const h = makeBattle({ autoFinish: false, kits, defs: { enemies: { dummy: target, victim: enemyRec({ key: 'victim', hp: 1, atk: 0, speed: 0 }) } },
|
||||
units: [{ uid: 1, chessId: 'chess_char_5_05_b', row: 10, col: 5, moduleId, skillIndex: 0, potential },
|
||||
{ uid: 2, chessId: 'chess_char_3_05_a', row: 11, col: 5 },
|
||||
{ uid: 3, chessId: 'chess_char_1_01_a', row: 9, col: 5 }] });
|
||||
h.step(); return { h, u: h.unit(1), hunter: h.unit(2), other: h.unit(3) };
|
||||
}
|
||||
|
||||
test('乌尔比安 CRU-Y scales damage against enemies blocked by any ally, including skill damage', () => {
|
||||
const { h, u, hunter } = ulpia();
|
||||
const e = h.spawn('dummy', { pos: [10, 7] });
|
||||
const amount = () => h.b.dealDamage(u, e, { amount: 100, type: 'phys', isSkill: true });
|
||||
approx(amount(), 100);
|
||||
e.blockedBy = hunter; hunter.blocking.push(e);
|
||||
approx(amount(), 110);
|
||||
e.blockedBy = null; hunter.blocking.length = 0;
|
||||
checkInvariants(h.b); assert.equal(h.b.errors.length, 0);
|
||||
});
|
||||
|
||||
test('乌尔比安 CRU-Y hunters share kill stacks; block +1 at nine, potential cap ten, other operators do not trigger it', () => {
|
||||
for (const potential of [1, 6]) {
|
||||
const { h, u, hunter, other } = ulpia({ potential, stage3: true });
|
||||
const kill = (killer) => h.b.dealDamage(killer, h.spawn('victim', { pos: [10, 8] }), { amount: 100, type: 'true' });
|
||||
kill(other); assert.equal(u.findBuff('ulpia:blood'), null);
|
||||
const block = u.s.blockCnt;
|
||||
for (let n = 1; n <= 12; n++) {
|
||||
kill(hunter);
|
||||
assert.equal(u.findBuff('ulpia:blood')?.stacks, Math.min(n, potential === 6 ? 10 : 9));
|
||||
assert.equal(u.s.blockCnt, block + (n >= 9 ? 1 : 0));
|
||||
}
|
||||
assert.ok(hunter.findBuff('ulpia:bloodShare'));
|
||||
checkInvariants(h.b); assert.equal(h.b.errors.length, 0);
|
||||
}
|
||||
});
|
||||
|
||||
test('乌尔比安 without the new module still only gains stacks from his own kills', () => {
|
||||
const { h, u, hunter } = ulpia({ moduleId: 'none' });
|
||||
h.b.dealDamage(hunter, h.spawn('victim', { pos: [10, 8] }), { amount: 100, type: 'true' });
|
||||
assert.equal(u.findBuff('ulpia:blood'), null);
|
||||
h.b.dealDamage(u, h.spawn('victim', { pos: [10, 8] }), { amount: 100, type: 'true' });
|
||||
assert.equal(u.findBuff('ulpia:blood').stacks, 1);
|
||||
checkInvariants(h.b); assert.equal(h.b.errors.length, 0);
|
||||
});
|
||||
|
||||
|
||||
test('乌尔比安 CRU-Y counts a withdrawn hunter’s delayed credited kill only while Ulpianus is deployed', () => {
|
||||
const { h, u, hunter } = ulpia({ stage3: true });
|
||||
h.b.retreat(hunter, { permanent: true });
|
||||
h.b.dealDamage(hunter, h.spawn('victim', { pos: [10, 8] }), { amount: 100, type: 'true' });
|
||||
assert.equal(u.findBuff('ulpia:blood')?.stacks, 1);
|
||||
h.b.retreat(u, { permanent: true });
|
||||
h.b.dealDamage(hunter, h.spawn('victim', { pos: [10, 8] }), { amount: 100, type: 'true' });
|
||||
assert.ok((u.findBuff('ulpia:blood')?.stacks ?? 0) <= 1);
|
||||
checkInvariants(h.b); assert.deepEqual(h.b.errors, []);
|
||||
});
|
||||
@@ -0,0 +1,153 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { makeBattle, enemyRec, checkInvariants } from '../helpers/battleHarness.js';
|
||||
import { KITTED_CHARS } from '../../server/sim/content/kits/index.js';
|
||||
import { diyPool } from '../../shared/diy.js';
|
||||
import { performAttack, effectiveProfile } from '../../server/sim/ai.js';
|
||||
const C = 'char_4231_clemnt';
|
||||
const data = Object.fromEntries(['chess', 'backups'].map((f) => [f, JSON.parse(readFileSync(new URL(`../../data/${f}.json`, import.meta.url)))]));
|
||||
const approx = (a, b, label = '') => assert.ok(Math.abs(a - b) < 1e-5 * Math.max(1, Math.abs(b)), `${label}: ${a} != ${b}`);
|
||||
const enemy = (key, opts = {}) => enemyRec({ key, hp: 1e8, atk: 0, speed: 0, ...opts });
|
||||
const defs = { enemies: { dummy: enemy('dummy'), light: enemy('light', { mass: 3 }), heavy: enemy('heavy', { mass: 9 }),
|
||||
fly: enemy('fly', { motion: 'FLY' }), zero: enemy('zero', { mass: 0 }), armored: enemy('armored', { def: 100 }) } };
|
||||
function field({ tier = 6, elite = true, skill = 0, potential = 6, dir = 'RIGHT', row = 10, col = 3 } = {}) {
|
||||
const h = makeBattle({ seed: 23, autoFinish: false, timeLimit: 180, defs,
|
||||
hooks: ['damaged', 'attack', 'elementBurst', 'ammoUsed'], captureNoisy: true,
|
||||
units: [{ uid: 1, diy: { slot: tier, charId: C, skillIndex: skill }, elite, potential, row, col, dir }] });
|
||||
h.step(); return { h, u: h.unit(1) };
|
||||
}
|
||||
function done(h) { checkInvariants(h.b); assert.deepEqual(h.b.errors, []); }
|
||||
function start(u) { u.skill.gainSp(999, 'init'); assert.equal(u.skill.activate('test'), true); }
|
||||
const hits = (h, tag) => h.hooksOf('damaged').filter((c) => c.dmg?.tags?.includes(tag));
|
||||
|
||||
test('克莱门莎 is selectable with authored skills in both slots, every form and potential', () => {
|
||||
assert.ok(KITTED_CHARS.includes(C));
|
||||
for (const tier of [5, 6]) {
|
||||
assert.ok(diyPool(tier, { data, kitted: KITTED_CHARS }).includes(C));
|
||||
for (const elite of [false, true]) for (const skill of [0, 1, 2]) for (const potential of [1, 6]) {
|
||||
const { h, u } = field({ tier, elite, skill, potential });
|
||||
assert.equal(u.def.charId, C); assert.equal(u.kit.skillSource, 'skills'); assert.ok(!u.kit.generic);
|
||||
assert.equal(u.skill.id, `skchr_clemnt_${skill + 1}`);
|
||||
assert.deepEqual([u.profile.dmgType, u.profile.canHitFly, u.s.blockCnt, u.base.bat], ['phys', false, 2, 1.2]);
|
||||
assert.ok(u.def.bonds.includes('egirShip'));
|
||||
assert.equal(u.skill.rule, skill ? 'ACTIVE_RANGE' : 'DEFAULT');
|
||||
done(h);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
test('生死定夺 checks current versus initial DEF for each physical hit; scales before DEF, never elemental damage', () => {
|
||||
for (const potential of [1, 3, 6]) {
|
||||
const { h, u } = field({ potential });
|
||||
const e = h.spawn('armored', { pos: [10, 6] }); h.b.rng = () => 0.3;
|
||||
approx(h.b.dealDamage(u, e, { amount: 1000, type: 'phys' }), 900);
|
||||
h.b.addBuff(e, { key: 'test:def', mods: { defFlat: -50 } });
|
||||
approx(h.b.dealDamage(u, e, { amount: 1000, type: 'phys' }), 1000 * (potential >= 3 ? 1.5 : 1.35) - 50);
|
||||
approx(h.b.dealDamage(u, e, { amount: 1000, type: 'elemental' }), 1000);
|
||||
const z = h.spawn('dummy', { pos: [10, 7] }); h.b.addBuff(z, { key: 'test:def', mods: { defFlat: -50 } });
|
||||
approx(h.b.dealDamage(u, z, { amount: 1000, type: 'phys' }), 1000);
|
||||
done(h);
|
||||
}
|
||||
});
|
||||
|
||||
test('习得性防御 handles all facings, boundary tiles, blocked enemies, seamonsters, and damage types', () => {
|
||||
for (const dir of ['RIGHT', 'LEFT', 'UP', 'DOWN']) {
|
||||
const { h, u } = field({ dir, col: 5 });
|
||||
const e = h.spawn('dummy', { pos: [10, 5] });
|
||||
const take = (type = 'arts') => { u.hp = u.s.maxHp; return h.b.dealDamage(e, u, { amount: 100, type }); };
|
||||
approx(take(), 100 * 0.9 * 0.65); // same tile/column belongs to the forward half-plane
|
||||
const [dr, dc] = { RIGHT: [0, 1], LEFT: [0, -1], UP: [1, 0], DOWN: [-1, 0] }[dir];
|
||||
e.x = 5 - dc; e.y = 10 - dr; approx(take(), 90);
|
||||
e.blockedBy = u; u.blocking.push(e); approx(take(), 90 * 0.65);
|
||||
e.def = { ...e.def, tags: ['seamonster'] }; approx(take(), 90 * 0.45);
|
||||
approx(take('true'), 100); approx(take('elemental'), 100);
|
||||
e.blockedBy = null; u.blocking.length = 0; done(h);
|
||||
}
|
||||
});
|
||||
|
||||
test('冲蚀 is every fourth attack and fills erosion from actual post-mitigation damage, with no air target', () => {
|
||||
for (const elite of [false, true]) {
|
||||
const { h, u } = field({ elite }); const e = h.spawn('dummy', { pos: [10, 4] }); h.b.rng = () => 0.99;
|
||||
h.run(5);
|
||||
const dealt = h.hooksOf('damaged').filter((c) => c.source === u && c.dmg.isAttack);
|
||||
assert.ok(dealt.length >= 4);
|
||||
dealt.forEach((c, i) => assert.equal(c.dmg.isSkill, i % 4 === 3));
|
||||
const r = hits(h, 'clemnt:rider'); assert.ok(r.length > 0);
|
||||
const first = dealt.find((c) => c.dmg.isSkill);
|
||||
approx(r[0].amount, first.amount * (elite ? 0.3 : 0.25));
|
||||
assert.ok(e.elem.erosion > 0); done(h);
|
||||
}
|
||||
});
|
||||
|
||||
test('风暴潮 carries at most eight total weight, excludes flyers/self-bound enemies and releases after three tiles', () => {
|
||||
const { h, u } = field({ skill: 1 });
|
||||
const es = [0, 1, 2].map(() => h.spawn('light', { pos: [10, 4] }));
|
||||
const heavy = h.spawn('heavy', { pos: [10, 4] }), fly = h.spawn('fly', { pos: [10, 4] });
|
||||
const bound = h.spawn('zero', { pos: [10, 4] }); h.b.addBuff(bound, { key: 'test:bound', flags: { selfBound: true, noMove: true } });
|
||||
start(u); assert.ok(u.s.flags.disarm); h.run(0.7);
|
||||
assert.equal(u.mem.clemntCabin.passengers.length, 2);
|
||||
assert.equal(u.mem.clemntCabin.mass, 2);
|
||||
assert.ok(es[0].s.flags.unblockable && es[0].s.flags.disarm);
|
||||
for (const e of [heavy, fly, bound]) assert.ok(!u.mem.clemntCabin.passengers.includes(e));
|
||||
h.run(0.9); assert.ok(u.mem.clemntCabin.stopped); approx(u.mem.clemntCabin.x, 6);
|
||||
assert.ok(!u.s.flags.disarm); assert.ok(!es[0].s.flags.unblockable);
|
||||
approx(es[0].x, 6); done(h);
|
||||
});
|
||||
|
||||
test('风暴潮 caps passengers at fifteen and cleans them on early skill end', () => {
|
||||
const { h, u } = field({ skill: 1 });
|
||||
for (let n = 0; n < 20; n++) h.spawn('zero', { pos: [10, 4] });
|
||||
start(u); h.run(0.4); assert.equal(u.mem.clemntCabin.passengers.length, 15);
|
||||
const es = [...u.mem.clemntCabin.passengers]; u.skill.stop();
|
||||
assert.ok(es.every((e) => !e.s.flags.disarm && !e.s.flags.unblockable && !e.s.flags.noMove));
|
||||
assert.equal(u.mem.clemntCabin, null); done(h);
|
||||
});
|
||||
|
||||
test('风暴潮 stops before a blocked tile; vortex keeps its continuous stop point, hits air and applies normal erosion resistance', () => {
|
||||
const { h, u } = field({ skill: 1 }); h.b.grid.setObstacle(10, 5, true);
|
||||
const fly = h.spawn('fly', { pos: [10, 5.55] });
|
||||
fly.def = { ...fly.def, epResistance: 99 };
|
||||
start(u); h.run(0.7); assert.ok(u.mem.clemntCabin.stopped);
|
||||
approx(u.mem.clemntCabin.x, 4.1); h.run(1.1);
|
||||
approx(fly.findBuff(`clemnt:vortex:${u.id}`).mods.moveMul, 0.3); approx(fly.elem.erosion, 10); // damage formula's 5% floor at 99 resistance
|
||||
assert.ok(hits(h, 'clemnt:vortex').some((c) => c.target === fly)); done(h);
|
||||
});
|
||||
|
||||
test('风暴潮 normal attack hits five ground enemies in total, never all neighbours or a flyer', () => {
|
||||
const { h, u } = field({ skill: 1 }); start(u); h.run(1.6);
|
||||
const es = Array.from({ length: 9 }, () => h.spawn('heavy', { pos: [10, 4] }));
|
||||
const fly = h.spawn('fly', { pos: [10, 4] });
|
||||
const before = h.hooksOf('damaged').length;
|
||||
performAttack(h.b, u, effectiveProfile(u), [es[0]]);
|
||||
const victims = new Set(h.hooksOf('damaged').slice(before).filter((c) => c.dmg.isAttack).map((c) => c.target));
|
||||
assert.equal(victims.size, 5); assert.ok(!victims.has(fly)); done(h);
|
||||
});
|
||||
|
||||
test('与海为敌 normal attacks hit three and spend no ammunition; remote erosion bursts fire three cross-shaped mixed hits', () => {
|
||||
const { h, u } = field({ skill: 2 }); start(u); h.b.rng = () => 0.99;
|
||||
const close = Array.from({ length: 3 }, () => h.spawn('dummy', { pos: [10, 4] }));
|
||||
performAttack(h.b, u, effectiveProfile(u), close);
|
||||
assert.equal(u.skill.ammoLeft, 10);
|
||||
const remote = h.spawn('dummy', { pos: [11, 9] }), near = h.spawn('dummy', { pos: [12, 9] });
|
||||
const diagonal = h.spawn('dummy', { pos: [12, 8] }), fly = h.spawn('fly', { pos: [11, 9] });
|
||||
h.b.dealDamage(u, remote, { amount: 1000, type: 'element', element: 'erosion' }); h.step();
|
||||
assert.equal(u.skill.ammoLeft, 9); u.skill.stop(); h.run(2.6);
|
||||
const bombs = hits(h, 'clemnt:bomb');
|
||||
for (const e of [remote, near]) {
|
||||
assert.equal(bombs.filter((c) => c.target === e && c.type === 'phys').length, 3);
|
||||
assert.equal(bombs.filter((c) => c.target === e && c.type === 'elemental').length, 3);
|
||||
}
|
||||
assert.ok(!bombs.some((c) => c.target === diagonal || c.target === fly)); done(h);
|
||||
});
|
||||
|
||||
test('与海为敌 selects nearest marked enemy, suppresses duplicate bombing tiles and does not mark air or sleeping units', () => {
|
||||
const { h, u } = field({ skill: 2 }); start(u);
|
||||
const far = h.spawn('dummy', { pos: [12, 9] }), near = h.spawn('dummy', { pos: [11, 7] });
|
||||
const same = h.spawn('dummy', { pos: [11, 7] }), fly = h.spawn('fly', { pos: [11, 8] });
|
||||
const asleep = h.spawn('dummy', { pos: [11, 6] }); h.b.applyStatus(asleep, 'sleep', { duration: 5 });
|
||||
for (const target of [far, near, same, fly, asleep]) h.b.emit('elementBurst', { source: null, target, element: 'erosion' });
|
||||
h.step(); assert.equal(u.skill.ammoLeft, 9); assert.ok(!u.mem.clemntBombs.marks.has(near));
|
||||
h.step(); assert.equal(u.skill.ammoLeft, 8); assert.ok(!u.mem.clemntBombs.marks.has(far));
|
||||
h.run(1.1); assert.equal(u.skill.ammoLeft, 8); assert.equal(u.mem.clemntBombs.marks.size, 0); done(h);
|
||||
});
|
||||
+2331
-2276
File diff suppressed because it is too large.
Load diff
+18
-18
@@ -1268,7 +1268,7 @@
|
||||
["p1",1,"op","chess_char_6_15_b",2,"uniequip_002_qiubai",5829.12,1,112,25,817580,42480,0,168,3],
|
||||
["p1",2,"op","chess_char_6_19_b",2,"uniequip_002_blkkgt",6696.14,1,9,5,198720,778,0,1,3],
|
||||
["p1",3,"op","chess_char_5_01_b",0,"uniequip_003_excu2",5521.67,1,10,0,11795,1147,300,4,0],
|
||||
["p1",4,"op","chess_char_5_05_b",0,"none",14096.5,1,7,0,0,0,0,0,0],
|
||||
["p1",4,"op","chess_char_5_05_b",0,"uniequip_003_ulpia",14967.7,1,7,0,0,0,0,0,0],
|
||||
["p1",5,"op","chess_char_6_17_b",2,"uniequip_002_nearl2",11659.29,1,24,21,474273,37335,0,107,3],
|
||||
["p1",6,"op","chess_char_6_13_b",1,"uniequip_002_angel2",5306.7,1,2,29,663495,11646,1190,58,2],
|
||||
["p1",7,"op","chess_char_6_14_b",2,"uniequip_002_lumen",4595.58,1,3,0,0,0,7779,76,1],
|
||||
@@ -1300,7 +1300,7 @@
|
||||
"hooks": [1,126,6021,786,786,2560,2883,573,109,114,28,25,56,20899,1618,75,108,0,1,109,2,0,0],
|
||||
"events": {"atk":1154,"bounty":6,"deploy":18,"die":114,"dmg":2673,"engage":10,"fx":534,"heal":437,"layer":2,"skill":53,"spawn":123,"status":429},
|
||||
"fx": {"airstrike":20,"aoe":9,"beam":26,"blink":2,"bombard":10,"bombardShell":10,"displace":5,"drone":347,"droneLock":57,"drones":3,"extraAttack":1,"finale":3,"garrison":2,"garrisonGrant":1,"link":10,"radiantSword":3,"slash":16,"steal":2,"summon":3,"sunBurst":1,"talent":3},
|
||||
"snaps": "f9e8faee dbe9b906 db6668e1 9b5d83f7 5ac11fea 257f514d 05c46f29 1991dd95 e806a918 38314f7b da515ea3 607236ee 6d03ef88 c5df95b9 3ac0270d 6bbc6ea8 183d1208 3638569e 0a132e83 38d98641"
|
||||
"snaps": "3bc002dc 99924baa b4e5485c 4572877f 2e5abf56 ab533660 d4f12dd4 7d0ce564 75b173a1 2daf77c4 765fb557 a2f4c5bd 0987ab99 45c06b00 2b52eba1 20bb7c71 b8fb29bd 6b0755df 1ac95c1e f2a7e61b"
|
||||
},
|
||||
"roster-020": {
|
||||
"about": "pass 1 band 1: chess_char_1_02_a chess_char_1_04_a chess_char_1_10_a chess_char_1_08_a chess_char_1_12_a chess_char_1_01_a chess_char_1_03_a chess_char_1_06_a chess_char_1_07_a chess_char_1_09_a chess_char_1_13_a chess_char_1_14_a",
|
||||
@@ -2358,41 +2358,41 @@
|
||||
"total": 157,
|
||||
"unspawned": 0,
|
||||
"bossHpLeft": null,
|
||||
"rngDraws": 49,
|
||||
"rngDraws": 45,
|
||||
"errors": {"count":0,"kinds":[]},
|
||||
"players": {
|
||||
"p1": {"killed":157,"total":157,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":8,"dmg":3467715,"bossDmg":0,"heal":72149,"deaths":2,"layerGains":{"raidShip":22}}
|
||||
"p1": {"killed":157,"total":157,"perfect":true,"leaks":0,"leaksUncounted":0,"coins":8,"dmg":3467641,"bossDmg":0,"heal":73044,"deaths":2,"layerGains":{"raidShip":22}}
|
||||
},
|
||||
"units": [
|
||||
["p1",1,"op","chess_char_5_08_b",1,"none",3052.5,1,2,18,392758,0,0,62,4],
|
||||
["p1",1,"op","chess_char_5_08_b",1,"none",3052.5,1,2,19,393842,0,0,62,4],
|
||||
["p1",2,"op","chess_char_6_19_b",0,"uniequip_003_blkkgt",5230.39,1,4,0,0,0,0,0,0],
|
||||
["p1",3,"op","chess_char_5_01_b",2,"none",2545.4,1,6,0,2613,0,0,2,0],
|
||||
["p1",4,"op","chess_char_5_05_b",1,"uniequip_002_ulpia",11326.7,1,7,11,138379,2934,360,24,1],
|
||||
["p1",5,"op","chess_char_5_06_b",1,"none",4121.7,1,8,110,2367402,24698,24698,110,8],
|
||||
["p1",4,"op","chess_char_5_05_b",1,"none",9477.62,1,7,9,113120,4230,480,20,1],
|
||||
["p1",5,"op","chess_char_5_06_b",1,"none",4121.7,1,8,107,2385886,24107,24107,110,8],
|
||||
["p1",6,"op","chess_char_6_17_b",0,"uniequip_003_nearl2",0,0,101,3,91899,9619,0,53,1],
|
||||
["p1",7,"op","chess_char_5_07_b",1,"none",3183.84,1,12,7,257729,44385,0,153,6],
|
||||
["p1",8,"op","chess_char_6_18_b",0,"none",1640.63,1,9,2,97475,0,0,149,1],
|
||||
["p1",9,"op","chess_char_6_20_b",0,"uniequip_003_agoat2",1628.75,1,10,0,0,0,44385,53,1],
|
||||
["p1",10,"op","chess_char_5_02_b",1,"uniequip_002_titi",1582.9,1,1,4,91179,0,2705,2,1],
|
||||
["p1",7,"op","chess_char_5_07_b",1,"none",3183.84,1,12,8,256736,45687,0,153,6],
|
||||
["p1",8,"op","chess_char_6_18_b",0,"none",1640.63,1,9,4,106163,0,0,149,1],
|
||||
["p1",9,"op","chess_char_6_20_b",0,"uniequip_003_agoat2",1628.75,1,10,0,0,0,45687,54,1],
|
||||
["p1",10,"op","chess_char_5_02_b",1,"uniequip_002_titi",1582.9,1,1,4,91738,0,2770,2,1],
|
||||
["p1",11,"op","chess_char_5_03_b",1,"none",1538.24,1,3,0,2310,162,0,2,1],
|
||||
["p1",12,"op","chess_char_5_10_b",1,"none",1518,1,5,1,25972,0,0,26,1]
|
||||
["p1",12,"op","chess_char_5_10_b",1,"none",1518,1,5,2,23335,0,0,23,1]
|
||||
],
|
||||
"enemies": {
|
||||
"enemy_1006_shield_3": [1,1,0,2931,143327],
|
||||
"enemy_1021_bslime": [1,1,0,3065,8815],
|
||||
"enemy_1148_dssbr_2": [1,1,0,0,12899],
|
||||
"enemy_1198_msfshu_2": [1,1,0,0,6],
|
||||
"enemy_1249_lysdb_2": [60,60,0,21415,1289945],
|
||||
"enemy_1251_lysyta": [51,51,0,2559,502541],
|
||||
"enemy_1249_lysdb_2": [60,60,0,20261,1289945],
|
||||
"enemy_1251_lysyta": [51,51,0,2355,502541],
|
||||
"enemy_1270_nhstlk": [1,1,0,2036,42998],
|
||||
"enemy_1329_cbshld": [39,39,0,46534,1397441],
|
||||
"enemy_1329_cbshld": [39,39,0,49898,1397441],
|
||||
"enemy_1389_winbab_2": [1,1,0,3097,25082],
|
||||
"enemy_2001_duckmi": [1,1,0,0,64497]
|
||||
},
|
||||
"hooks": [1,170,5944,770,768,3800,3743,575,159,159,25,20,40,15978,678,88,157,0,1,161,2,0,0],
|
||||
"events": {"atk":1152,"bounty":4,"deploy":13,"die":159,"dmg":3743,"engage":10,"fx":97,"heal":493,"layer":2,"skill":45,"spawn":169,"status":197},
|
||||
"hooks": [1,170,5944,764,762,3820,3763,578,159,159,25,20,40,15978,683,89,157,0,1,161,2,0,0],
|
||||
"events": {"atk":1149,"bounty":4,"deploy":13,"die":159,"dmg":3763,"engage":10,"fx":97,"heal":485,"layer":2,"skill":45,"spawn":169,"status":182},
|
||||
"fx": {"aoe":16,"explode":1,"garrison":2,"garrisonGrant":4,"overload":4,"reborn":1,"shieldBreak":60,"sleepGuard":1,"sunBurst":3,"talent":3,"undying":2},
|
||||
"snaps": "38ebdad4 4c56ab84 28991e1c d38e3ca9 a93fad01 78000e59 91035db7 97f82a70 314dbacf 171d41e5 77caf838 e9196e88 52b40b0e 302ec2b7 47b6a52c c639db96 51cb55bb 433ac4c3 d5827da5 868f9d65"
|
||||
"snaps": "2c013a42 e0a9d456 d93eb576 5f4d92f3 a5a0ebec 5214a5e1 27d57a43 91a4904c 9fca4890 d12b72df 7c44ce37 e62d1865 3d9a4fd9 350839a2 4e7c68e2 8dfe6cd9 9f96036b b28d664a 33c769dc 3d835553"
|
||||
},
|
||||
"roster-039": {
|
||||
"about": "pass 2 band 4: chess_char_3_12_a chess_char_3_12_b chess_char_3_18_a chess_char_3_18_b chess_char_3_04_a chess_char_3_05_a chess_char_3_04_b chess_char_3_05_b chess_char_3_01_a chess_char_3_19_a chess_char_3_21_a chess_char_3_01_b token_10028_vigil_wolf",
|
||||
|
||||
Reference in new issue
Block a user